AirAcceptCoreTests.swift 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import XCTest
  2. @testable import AirAcceptCore
  3. final class AirAcceptCoreTests: XCTestCase {
  4. func testDefaultConfigAcceptsMatchedAirPlayRequests() {
  5. let config = AirAcceptConfig()
  6. XCTAssertEqual(config.pollIntervalMilliseconds, 2_500)
  7. }
  8. func testMatchesEnglishAirPlayPrompt() {
  9. let candidate = PromptCandidate(
  10. hostProcess: "com.apple.AirPlayUIAgent",
  11. texts: ["John's iPhone would like to AirPlay to this Mac."],
  12. buttonTitles: ["Decline", "Accept"]
  13. )
  14. let match = AirPlayPromptMatcher.match(candidate)
  15. XCTAssertEqual(match?.deviceName, "John's iPhone")
  16. XCTAssertEqual(match?.acceptButtonTitle, "Accept")
  17. XCTAssertEqual(match?.declineButtonTitle, "Decline")
  18. }
  19. func testMatchesQuotedTraditionalChinesePrompt() {
  20. let candidate = PromptCandidate(
  21. hostProcess: "com.apple.AirPlayUIAgent",
  22. texts: ["「客廳 iPad」想要使用 AirPlay 連線到這台 Mac。"],
  23. buttonTitles: ["拒絕", "接受"]
  24. )
  25. let match = AirPlayPromptMatcher.match(candidate)
  26. XCTAssertEqual(match?.deviceName, "客廳 iPad")
  27. XCTAssertEqual(match?.acceptButtonTitle, "接受")
  28. XCTAssertEqual(match?.declineButtonTitle, "拒絕")
  29. }
  30. func testRejectsNonAirPlayAcceptDeclineDialog() {
  31. let candidate = PromptCandidate(
  32. hostProcess: "com.apple.SecurityAgent",
  33. texts: ["A system change requires approval."],
  34. buttonTitles: ["Decline", "Accept"]
  35. )
  36. XCTAssertNil(AirPlayPromptMatcher.match(candidate))
  37. }
  38. func testMatchesAirPlayPromptWithoutDeclineButton() {
  39. let candidate = PromptCandidate(
  40. hostProcess: "com.apple.AirPlayUIAgent",
  41. texts: ["John's iPhone would like to AirPlay to this Mac."],
  42. buttonTitles: ["Accept"]
  43. )
  44. let match = AirPlayPromptMatcher.match(candidate)
  45. XCTAssertEqual(match?.deviceName, "John's iPhone")
  46. XCTAssertEqual(match?.acceptButtonTitle, "Accept")
  47. XCTAssertNil(match?.declineButtonTitle)
  48. }
  49. func testRejectsGenericAirPlayTextWithoutConnectionRequest() {
  50. let candidate = PromptCandidate(
  51. hostProcess: "com.apple.AirPlayUIAgent",
  52. texts: ["AirPlay settings are available on this Mac."],
  53. buttonTitles: ["Accept"]
  54. )
  55. XCTAssertNil(AirPlayPromptMatcher.match(candidate))
  56. }
  57. func testConfigStoreCreatesDefaultConfig() throws {
  58. let directory = FileManager.default.temporaryDirectory
  59. .appendingPathComponent(UUID().uuidString, isDirectory: true)
  60. let url = directory.appendingPathComponent("config.json")
  61. let store = ConfigStore(configURL: url)
  62. let config = try store.loadOrCreate()
  63. XCTAssertEqual(config, AirAcceptConfig())
  64. XCTAssertTrue(FileManager.default.fileExists(atPath: url.path))
  65. }
  66. func testConfigStoreRemovesLegacyKeys() throws {
  67. let directory = FileManager.default.temporaryDirectory
  68. .appendingPathComponent(UUID().uuidString, isDirectory: true)
  69. let url = directory.appendingPathComponent("config.json")
  70. try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
  71. try Data("""
  72. {
  73. "dry_run": false,
  74. "fallback_click_visible_airplay_banner": true,
  75. "poll_interval_ms": 2500
  76. }
  77. """.utf8).write(to: url)
  78. let store = ConfigStore(configURL: url)
  79. let config = try store.loadOrCreate()
  80. let rewrittenConfig = try String(contentsOf: url, encoding: .utf8)
  81. XCTAssertEqual(config, AirAcceptConfig())
  82. XCTAssertFalse(rewrittenConfig.contains("dry_run"))
  83. XCTAssertFalse(rewrittenConfig.contains("fallback_click_visible_airplay_banner"))
  84. XCTAssertTrue(rewrittenConfig.contains("poll_interval_ms"))
  85. }
  86. }