1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-12-21 03:10:06 +01:00

Fix UI tests w/ new WebApi interactions

This commit is contained in:
2025-11-19 09:54:17 +01:00
parent df7476c54b
commit 24d2aa115e
8 changed files with 86 additions and 66 deletions

View File

@@ -53,7 +53,7 @@ class RealWebApi: WebApiProtocol {
func get(
_ url: URL,
withHeaders headers: HttpHeaders,
withHeaders headers: HttpHeaders = [:],
withTimeout timeout: TimeInterval = URLSession.shared.configuration.timeoutIntervalForRequest
) async throws -> WebApiResponse {
try await self.request(
@@ -67,7 +67,7 @@ class RealWebApi: WebApiProtocol {
func post(
_ url: URL,
withHeaders headers: HttpHeaders,
withHeaders headers: HttpHeaders = [:],
withData data: String,
withTimeout timeout: TimeInterval
) async throws -> WebApiResponse {

View File

@@ -100,7 +100,7 @@ class TestableWebApi: WebApiProtocol {
}
}
struct FakeWebApiResponse {
struct FakeWebApiResponse: Codable {
let statusCode: Int
let headers: [String: String]
let data: Data?

View File

@@ -14,6 +14,8 @@ public struct TestableConfiguration: Codable {
var shellOutput: [String: BatchFakeShellOutput]
var commandOutput: [String: String]
var preferenceOverrides: [PreferenceName: Bool]
var apiGetResponses: [URL: FakeWebApiResponse]
var apiPostResponses: [URL: FakeWebApiResponse]
init(
architecture: String,
@@ -21,13 +23,17 @@ public struct TestableConfiguration: Codable {
shellOutput: [String: BatchFakeShellOutput],
commandOutput: [String: String],
preferenceOverrides: [PreferenceName: Bool],
phpVersions: [VersionNumber]
phpVersions: [VersionNumber],
apiGetResponses: [URL: FakeWebApiResponse],
apiPostResponses: [URL: FakeWebApiResponse]
) {
self.architecture = architecture
self.filesystem = filesystem
self.shellOutput = shellOutput
self.commandOutput = commandOutput
self.preferenceOverrides = preferenceOverrides
self.apiGetResponses = apiGetResponses
self.apiPostResponses = apiPostResponses
phpVersions.enumerated().forEach { (index, version) in
self.addPhpVersion(version, primary: index == 0)
@@ -35,7 +41,13 @@ public struct TestableConfiguration: Codable {
}
private enum CodingKeys: String, CodingKey {
case architecture, filesystem, shellOutput, commandOutput, preferenceOverrides
case architecture,
filesystem,
shellOutput,
commandOutput,
preferenceOverrides,
apiGetResponses,
apiPostResponses
}
// MARK: Add PHP versions

View File

@@ -107,7 +107,9 @@ class Container {
self.overrideFake(
shellExpectations: config.shellOutput,
fileSystemFiles: config.filesystem,
commands: config.commandOutput
commands: config.commandOutput,
webApiGetResponses: config.apiGetResponses,
webApiPostResponses: config.apiPostResponses
)
}
}

View File

@@ -28,25 +28,19 @@ extension CaskFile {
}
}
// If it's a URL via the network we need to know if to use the complex API or not
if isRunningTests || App.hasLoadedTestableConfiguration || url.absoluteString.contains("https://raw.githubusercontent.com") {
// For testing simplicity, we will use curl, since we need no complex rules or headers
return CaskFile.from(await container.shell.pipe("curl -s --max-time 10 '\(url.absoluteString)'").out)
} else {
// However, for the real deal, we will use the Web API
guard let response = try? await container.webApi.get(
url,
withHeaders: container.webApi.defaultHeaders,
withTimeout: .seconds(10)
) else {
throw CaskFileError.requestFailed
}
guard let text = response.plainText else {
throw CaskFileError.invalidData
}
return CaskFile.from(text)
// However, for the real deal, we will use the Web API
guard let response = try? await container.webApi.get(
url,
withHeaders: container.webApi.defaultHeaders,
withTimeout: .seconds(10)
) else {
throw CaskFileError.requestFailed
}
guard let text = response.plainText else {
throw CaskFileError.invalidData
}
return CaskFile.from(text)
}
}

View File

@@ -13,6 +13,7 @@
},
"testTargets" : [
{
"enabled" : false,
"parallelizable" : true,
"target" : {
"containerPath" : "container:PHP Monitor.xcodeproj",
@@ -30,7 +31,6 @@
}
},
{
"enabled" : false,
"target" : {
"containerPath" : "container:PHP Monitor.xcodeproj",
"identifier" : "C471E7BB28F9B90F0021E251",

View File

@@ -138,36 +138,6 @@ class TestableConfigurations {
: .instant(ShellStrings.shared.brewServicesAsRoot),
"/opt/homebrew/bin/brew services info --all --json"
: .instant(ShellStrings.shared.brewServicesAsUser),
"curl -s --max-time 10 '\(Constants.Urls.UpdateCheckEndpoint.absoluteString)'"
: .delayed(0.5, """
cask 'phpmon-dev' do
depends_on formula: 'gnu-sed'
version '25.08.0_1000'
sha256 '1cb147bd1b1fbd52971d90dff577465b644aee7c878f15ede57f46e8f217067a'
url 'https://github.com/nicoverbruggen/phpmon/releases/download/v6.0/phpmon-dev.zip'
name 'PHP Monitor DEV'
homepage 'https://phpmon.app'
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
end
"""),
"curl -s --max-time 10 'https://raw.githubusercontent.com/nicoverbruggen/homebrew-cask/master/Casks/phpmon.rb''" :
.delayed(0.5, """
cask 'phpmon-dev' do
depends_on formula: 'gnu-sed'
version '25.08.0_1000'
sha256 '1cb147bd1b1fbd52971d90dff577465b644aee7c878f15ede57f46e8f217067a'
url 'https://github.com/nicoverbruggen/phpmon/releases/download/v6.0/phpmon-dev.zip'
name 'PHP Monitor DEV'
homepage 'https://phpmon.app'
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
end
"""),
"/opt/homebrew/bin/brew unlink php"
: .delayed(0.2, "OK"),
"/opt/homebrew/bin/brew unlink php@8.2"
@@ -222,7 +192,29 @@ class TestableConfigurations {
VersionNumber(major: 8, minor: 1, patch: 0),
VersionNumber(major: 8, minor: 0, patch: 0),
VersionNumber(major: 7, minor: 4, patch: 33)
]
],
apiGetResponses: [
url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)"): FakeWebApiResponse(
statusCode: 200,
headers: [:],
text: """
cask 'phpmon-dev' do
depends_on formula: 'gnu-sed'
version '25.08.0_1000'
sha256 '1cb147bd1b1fbd52971d90dff577465b644aee7c878f15ede57f46e8f217067a'
url 'https://github.com/nicoverbruggen/phpmon/releases/download/v6.0/phpmon-dev.zip'
name 'PHP Monitor DEV'
homepage 'https://phpmon.app'
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
end
""",
duration: 0.5
)
],
apiPostResponses: [:]
)
}

View File

@@ -31,9 +31,10 @@ final class UpdateCheckTest: UITestCase {
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = true
// Ensure an update is available
configuration.shellOutput[
"curl -s --max-time 10 '\(Constants.Urls.UpdateCheckEndpoint.absoluteString)'"
] = .delayed(0.5, """
configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse(
statusCode: 200,
headers: [:],
text: """
cask 'phpmon-dev' do
depends_on formula: 'gnu-sed'
@@ -46,7 +47,9 @@ final class UpdateCheckTest: UITestCase {
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
end
""")
""",
duration: 0.5
)
let app = launch(openMenu: false, with: configuration)
@@ -64,7 +67,10 @@ final class UpdateCheckTest: UITestCase {
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false
// Ensure an update is available
configuration.shellOutput["curl -s --max-time 10 '\(Constants.Urls.UpdateCheckEndpoint.absoluteString)'"] = .delayed(0.5, """
configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse(
statusCode: 200,
headers: [:],
text: """
cask 'phpmon-dev' do
depends_on formula: 'gnu-sed'
@@ -77,7 +83,9 @@ final class UpdateCheckTest: UITestCase {
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
end
""")
""",
duration: 0.5
)
// Wait for the menu to open and search for updates
let app = launch(openMenu: false, with: configuration)
@@ -93,7 +101,10 @@ final class UpdateCheckTest: UITestCase {
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false
// Ensure an update is available
configuration.shellOutput["curl -s --max-time 10 '\(Constants.Urls.UpdateCheckEndpoint.absoluteString)'"] = .delayed(0.5, """
configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse(
statusCode: 200,
headers: [:],
text: """
cask 'phpmon-dev' do
depends_on formula: 'gnu-sed'
@@ -106,7 +117,9 @@ final class UpdateCheckTest: UITestCase {
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
end
""")
""",
duration: 0.5
)
// Wait for the menu to open and search for updates
let app = launch(openMenu: true, with: configuration)
@@ -125,7 +138,14 @@ final class UpdateCheckTest: UITestCase {
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false
// Ensure an update is available
configuration.shellOutput["curl -s --max-time 10 '\(Constants.Urls.UpdateCheckEndpoint.absoluteString)'"] = .delayed(0.5, "404 PAGE NOT FOUND")
configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse(
statusCode: 500,
headers: [:],
text: """
OOPS, SERVER DOWN
""",
duration: 0.5
)
// Wait for the menu to open and search for updates
let app = launch(openMenu: true, with: configuration)