1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2026-03-30 08:20:09 +02:00

♻️ Refactor preference override (for tests)

This commit is contained in:
2026-02-23 13:56:27 +01:00
parent ab34716273
commit 1be1e05c16
6 changed files with 41 additions and 22 deletions

View File

@@ -13,7 +13,7 @@ public struct TestableConfiguration: Codable {
var filesystem: [String: FakeFile] var filesystem: [String: FakeFile]
var shellOutput: [String: BatchFakeShellOutput] var shellOutput: [String: BatchFakeShellOutput]
var commandOutput: [String: String] var commandOutput: [String: String]
var preferenceOverrides: [PreferenceName: Bool] var preferenceOverrides: [PreferenceName: PreferenceOverride]
var apiGetResponses: [URL: FakeWebApiResponse] var apiGetResponses: [URL: FakeWebApiResponse]
var apiPostResponses: [URL: FakeWebApiResponse] var apiPostResponses: [URL: FakeWebApiResponse]
@@ -22,7 +22,7 @@ public struct TestableConfiguration: Codable {
filesystem: [String: FakeFile], filesystem: [String: FakeFile],
shellOutput: [String: BatchFakeShellOutput], shellOutput: [String: BatchFakeShellOutput],
commandOutput: [String: String], commandOutput: [String: String],
preferenceOverrides: [PreferenceName: Bool], preferenceOverrides: [PreferenceName: PreferenceOverride],
phpVersions: [VersionNumber], phpVersions: [VersionNumber],
apiGetResponses: [URL: FakeWebApiResponse], apiGetResponses: [URL: FakeWebApiResponse],
apiPostResponses: [URL: FakeWebApiResponse] apiPostResponses: [URL: FakeWebApiResponse]
@@ -138,8 +138,13 @@ public struct TestableConfiguration: Codable {
Log.info("Applying temporary preference overrides...") Log.info("Applying temporary preference overrides...")
var cachedPrefs = container.preferences.cachedPreferences var cachedPrefs = container.preferences.cachedPreferences
preferenceOverrides.forEach { (key: PreferenceName, value: Any?) in preferenceOverrides.forEach { (key: PreferenceName, value: PreferenceOverride) in
cachedPrefs[key] = value switch value {
case .bool(let boolValue):
cachedPrefs[key] = boolValue
case .string(let stringValue):
cachedPrefs[key] = stringValue
}
} }
container.preferences.cachedPreferences = cachedPrefs container.preferences.cachedPreferences = cachedPrefs
@@ -193,3 +198,8 @@ public struct TestableConfiguration: Codable {
) )
} }
} }
enum PreferenceOverride: Codable {
case bool(Bool)
case string(String)
}

View File

@@ -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 This ensures that windows are recreated fresh, with the correct localization, the next
time they are opened. Each `close()` call triggers `windowWillClose`, which automatically time they are opened. Each `close()` call triggers `windowWillClose`, which automatically
removes the window from `openWindows` via the existing delegate mechanism. removes the window from `openWindows` via the existing delegate mechanism.

View File

@@ -198,7 +198,7 @@ class TestableConfigurations {
"/opt/homebrew/bin/php -r echo ini_get('post_max_size');": "512M" "/opt/homebrew/bin/php -r echo ini_get('post_max_size');": "512M"
], ],
preferenceOverrides: [ preferenceOverrides: [
.automaticBackgroundUpdateCheck: false .automaticBackgroundUpdateCheck: .bool(false)
], ],
phpVersions: [ phpVersions: [
VersionNumber(major: 8, minor: 4, patch: 5), VersionNumber(major: 8, minor: 4, patch: 5),

View File

@@ -14,16 +14,25 @@ final class SettingsTest: UITestCase {
continueAfterFailure = false 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 { 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 // First, open the domains window
app.mainMenuItem(withText: "mi_domain_list".localized).click() app.mainMenuItem(withText: "mi_domain_list".localized(for: "en")).click()
let domainsWindow = app.windows["domain_list.title".localized] let domainsWindow = app.windows["domain_list.title".localized(for: "en")]
assertExists(domainsWindow, 2.0) assertExists(domainsWindow, 2.0)
// Press the menu button again // Press the menu button again
app.statusItems.firstMatch.click() // press the menu button again app.statusItems.firstMatch.click()
// This time, open the preferences window // This time, open the preferences window
app.mainMenuItem(withText: "mi_preferences".localized).click() app.mainMenuItem(withText: "mi_preferences".localized).click()
@@ -31,7 +40,7 @@ final class SettingsTest: UITestCase {
.containing(.button, identifier: "prefs.tabs.general".localized(for: "en")) .containing(.button, identifier: "prefs.tabs.general".localized(for: "en"))
.firstMatch .firstMatch
assertExists(settingsWindow, 2.0) 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 // In the languages pop-up, click on it
let languagePopup = settingsWindow.popUpButtons.element(boundBy: 0) let languagePopup = settingsWindow.popUpButtons.element(boundBy: 0)
@@ -45,12 +54,12 @@ final class SettingsTest: UITestCase {
.containing(.button, identifier: "prefs.tabs.general".localized(for: "ja")) .containing(.button, identifier: "prefs.tabs.general".localized(for: "ja"))
.firstMatch .firstMatch
assertExists(settingsWindowJa, 2.0) assertExists(settingsWindowJa, 2.0)
assertExists(app.buttons["prefs.tabs.general".localized(for: "ja")], 2.0) assertExists(app.buttons["prefs.tabs.general".localized(for: "ja")])
assertExists(settingsWindowJa.staticTexts["prefs.language".localized(for: "ja")], 2.0) 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) let resetPopup = settingsWindowJa.popUpButtons.element(boundBy: 0)
resetPopup.click() resetPopup.click()
resetPopup.menuItems["System Default"].click() resetPopup.menuItems["English"].click()
} }
} }

View File

@@ -29,9 +29,9 @@ final class StartupTest: UITestCase {
assertAllExist([ assertAllExist([
app.dialogs["generic.notice".localized], app.dialogs["generic.notice".localized],
app.staticTexts["startup.errors.php_binary.title".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 // Dialog 2: PHP Monitor failed to start
assertAllExist([ assertAllExist([
@@ -72,6 +72,6 @@ final class StartupTest: UITestCase {
) )
assertExists(app.staticTexts["startup.errors.valet_version_not_supported.title".localized], 3.0) 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])
} }
} }

View File

@@ -28,7 +28,7 @@ final class UpdateCheckTest: UITestCase {
var configuration = TestableConfigurations.working var configuration = TestableConfigurations.working
// Ensure automatic check is enabled // Ensure automatic check is enabled
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = true configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = .bool(true)
// Ensure an update is available // Ensure an update is available
configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse( configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse(
@@ -64,7 +64,7 @@ final class UpdateCheckTest: UITestCase {
var configuration = TestableConfigurations.working var configuration = TestableConfigurations.working
// Ensure automatic check is disabled // Ensure automatic check is disabled
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = .bool(false)
// Ensure an update is available // Ensure an update is available
configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse( configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse(
@@ -98,7 +98,7 @@ final class UpdateCheckTest: UITestCase {
var configuration = TestableConfigurations.working var configuration = TestableConfigurations.working
// Ensure automatic check is disabled // Ensure automatic check is disabled
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = .bool(false)
// Ensure an update is available // Ensure an update is available
configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse( configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse(
@@ -135,7 +135,7 @@ final class UpdateCheckTest: UITestCase {
var configuration = TestableConfigurations.working var configuration = TestableConfigurations.working
// Ensure automatic check is disabled // Ensure automatic check is disabled
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = .bool(false)
// Ensure an update is available // Ensure an update is available
configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse( configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse(