From 1be1e05c16c3d74bb1e533f62413d87de687e3e4 Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Mon, 23 Feb 2026 13:56:27 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20preference=20ov?= =?UTF-8?q?erride=20(for=20tests)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Testables/TestableConfiguration.swift | 18 ++++++++++--- phpmon/Domain/App/App+ActivationPolicy.swift | 2 +- tests/Shared/TestableConfigurations.swift | 2 +- tests/ui/SettingsTest.swift | 27 ++++++++++++------- tests/ui/StartupTest.swift | 6 ++--- tests/ui/UpdateCheckTest.swift | 8 +++--- 6 files changed, 41 insertions(+), 22 deletions(-) diff --git a/phpmon/Common/Testables/TestableConfiguration.swift b/phpmon/Common/Testables/TestableConfiguration.swift index 18d6b67f..983336e6 100644 --- a/phpmon/Common/Testables/TestableConfiguration.swift +++ b/phpmon/Common/Testables/TestableConfiguration.swift @@ -13,7 +13,7 @@ public struct TestableConfiguration: Codable { var filesystem: [String: FakeFile] var shellOutput: [String: BatchFakeShellOutput] var commandOutput: [String: String] - var preferenceOverrides: [PreferenceName: Bool] + var preferenceOverrides: [PreferenceName: PreferenceOverride] var apiGetResponses: [URL: FakeWebApiResponse] var apiPostResponses: [URL: FakeWebApiResponse] @@ -22,7 +22,7 @@ public struct TestableConfiguration: Codable { filesystem: [String: FakeFile], shellOutput: [String: BatchFakeShellOutput], commandOutput: [String: String], - preferenceOverrides: [PreferenceName: Bool], + preferenceOverrides: [PreferenceName: PreferenceOverride], phpVersions: [VersionNumber], apiGetResponses: [URL: FakeWebApiResponse], apiPostResponses: [URL: FakeWebApiResponse] @@ -138,8 +138,13 @@ public struct TestableConfiguration: Codable { Log.info("Applying temporary preference overrides...") var cachedPrefs = container.preferences.cachedPreferences - preferenceOverrides.forEach { (key: PreferenceName, value: Any?) in - cachedPrefs[key] = value + preferenceOverrides.forEach { (key: PreferenceName, value: PreferenceOverride) in + switch value { + case .bool(let boolValue): + cachedPrefs[key] = boolValue + case .string(let stringValue): + cachedPrefs[key] = stringValue + } } container.preferences.cachedPreferences = cachedPrefs @@ -193,3 +198,8 @@ public struct TestableConfiguration: Codable { ) } } + +enum PreferenceOverride: Codable { + case bool(Bool) + case string(String) +} diff --git a/phpmon/Domain/App/App+ActivationPolicy.swift b/phpmon/Domain/App/App+ActivationPolicy.swift index 16e1c3d3..68d67a14 100644 --- a/phpmon/Domain/App/App+ActivationPolicy.swift +++ b/phpmon/Domain/App/App+ActivationPolicy.swift @@ -42,7 +42,7 @@ extension App { } /** - Closes and invalidates all cached secondary window controllers (excluding preferences). + Closes and invalidates all cached secondary window controllers (excluding Preferences). This ensures that windows are recreated fresh, with the correct localization, the next time they are opened. Each `close()` call triggers `windowWillClose`, which automatically removes the window from `openWindows` via the existing delegate mechanism. diff --git a/tests/Shared/TestableConfigurations.swift b/tests/Shared/TestableConfigurations.swift index 367f5db1..28ee006a 100644 --- a/tests/Shared/TestableConfigurations.swift +++ b/tests/Shared/TestableConfigurations.swift @@ -198,7 +198,7 @@ class TestableConfigurations { "/opt/homebrew/bin/php -r echo ini_get('post_max_size');": "512M" ], preferenceOverrides: [ - .automaticBackgroundUpdateCheck: false + .automaticBackgroundUpdateCheck: .bool(false) ], phpVersions: [ VersionNumber(major: 8, minor: 4, patch: 5), diff --git a/tests/ui/SettingsTest.swift b/tests/ui/SettingsTest.swift index 707920af..d18fb305 100644 --- a/tests/ui/SettingsTest.swift +++ b/tests/ui/SettingsTest.swift @@ -14,16 +14,25 @@ final class SettingsTest: UITestCase { continueAfterFailure = false } + /** + In this test, we start with the app configured with the English override. + After opening the domains window, we switch to Japanese. + */ final func test_changing_language_closes_other_windows() throws { - let app = launch(openMenu: true) + var configuration = TestableConfigurations.working + + // Our default starting point is to use the system default language + configuration.preferenceOverrides[.languageOverride] = .string("en") + + let app = launch(openMenu: true, with: configuration) // First, open the domains window - app.mainMenuItem(withText: "mi_domain_list".localized).click() - let domainsWindow = app.windows["domain_list.title".localized] + app.mainMenuItem(withText: "mi_domain_list".localized(for: "en")).click() + let domainsWindow = app.windows["domain_list.title".localized(for: "en")] assertExists(domainsWindow, 2.0) // Press the menu button again - app.statusItems.firstMatch.click() // press the menu button again + app.statusItems.firstMatch.click() // This time, open the preferences window app.mainMenuItem(withText: "mi_preferences".localized).click() @@ -31,7 +40,7 @@ final class SettingsTest: UITestCase { .containing(.button, identifier: "prefs.tabs.general".localized(for: "en")) .firstMatch assertExists(settingsWindow, 2.0) - assertExists(app.buttons["prefs.tabs.general".localized(for: "en")], 2.0) + assertExists(app.buttons["prefs.tabs.general".localized(for: "en")]) // In the languages pop-up, click on it let languagePopup = settingsWindow.popUpButtons.element(boundBy: 0) @@ -45,12 +54,12 @@ final class SettingsTest: UITestCase { .containing(.button, identifier: "prefs.tabs.general".localized(for: "ja")) .firstMatch assertExists(settingsWindowJa, 2.0) - assertExists(app.buttons["prefs.tabs.general".localized(for: "ja")], 2.0) - assertExists(settingsWindowJa.staticTexts["prefs.language".localized(for: "ja")], 2.0) + assertExists(app.buttons["prefs.tabs.general".localized(for: "ja")]) + assertExists(settingsWindowJa.staticTexts["prefs.language".localized(for: "ja")]) - // Switch back to the original language + // Switch back to English let resetPopup = settingsWindowJa.popUpButtons.element(boundBy: 0) resetPopup.click() - resetPopup.menuItems["System Default"].click() + resetPopup.menuItems["English"].click() } } diff --git a/tests/ui/StartupTest.swift b/tests/ui/StartupTest.swift index ee2cb0e7..a63357fc 100644 --- a/tests/ui/StartupTest.swift +++ b/tests/ui/StartupTest.swift @@ -29,9 +29,9 @@ final class StartupTest: UITestCase { assertAllExist([ app.dialogs["generic.notice".localized], app.staticTexts["startup.errors.php_binary.title".localized], - app.buttons["generic.ok".localized] + app.buttons["startup.fix_manually".localized] ]) - click(app.buttons["generic.ok".localized]) + click(app.buttons["startup.fix_manually".localized]) // Dialog 2: PHP Monitor failed to start assertAllExist([ @@ -72,6 +72,6 @@ final class StartupTest: UITestCase { ) assertExists(app.staticTexts["startup.errors.valet_version_not_supported.title".localized], 3.0) - click(app.buttons["generic.ok".localized]) + click(app.buttons["startup.fix_manually".localized]) } } diff --git a/tests/ui/UpdateCheckTest.swift b/tests/ui/UpdateCheckTest.swift index 23c08483..359abf15 100644 --- a/tests/ui/UpdateCheckTest.swift +++ b/tests/ui/UpdateCheckTest.swift @@ -28,7 +28,7 @@ final class UpdateCheckTest: UITestCase { var configuration = TestableConfigurations.working // Ensure automatic check is enabled - configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = true + configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = .bool(true) // Ensure an update is available configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse( @@ -64,7 +64,7 @@ final class UpdateCheckTest: UITestCase { var configuration = TestableConfigurations.working // Ensure automatic check is disabled - configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false + configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = .bool(false) // Ensure an update is available configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse( @@ -98,7 +98,7 @@ final class UpdateCheckTest: UITestCase { var configuration = TestableConfigurations.working // Ensure automatic check is disabled - configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false + configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = .bool(false) // Ensure an update is available configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse( @@ -135,7 +135,7 @@ final class UpdateCheckTest: UITestCase { var configuration = TestableConfigurations.working // Ensure automatic check is disabled - configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false + configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = .bool(false) // Ensure an update is available configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse(