mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-12-21 11:10:08 +01:00
✅ Fix UI tests w/ new WebApi interactions
This commit is contained in:
@@ -53,7 +53,7 @@ class RealWebApi: WebApiProtocol {
|
|||||||
|
|
||||||
func get(
|
func get(
|
||||||
_ url: URL,
|
_ url: URL,
|
||||||
withHeaders headers: HttpHeaders,
|
withHeaders headers: HttpHeaders = [:],
|
||||||
withTimeout timeout: TimeInterval = URLSession.shared.configuration.timeoutIntervalForRequest
|
withTimeout timeout: TimeInterval = URLSession.shared.configuration.timeoutIntervalForRequest
|
||||||
) async throws -> WebApiResponse {
|
) async throws -> WebApiResponse {
|
||||||
try await self.request(
|
try await self.request(
|
||||||
@@ -67,7 +67,7 @@ class RealWebApi: WebApiProtocol {
|
|||||||
|
|
||||||
func post(
|
func post(
|
||||||
_ url: URL,
|
_ url: URL,
|
||||||
withHeaders headers: HttpHeaders,
|
withHeaders headers: HttpHeaders = [:],
|
||||||
withData data: String,
|
withData data: String,
|
||||||
withTimeout timeout: TimeInterval
|
withTimeout timeout: TimeInterval
|
||||||
) async throws -> WebApiResponse {
|
) async throws -> WebApiResponse {
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class TestableWebApi: WebApiProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FakeWebApiResponse {
|
struct FakeWebApiResponse: Codable {
|
||||||
let statusCode: Int
|
let statusCode: Int
|
||||||
let headers: [String: String]
|
let headers: [String: String]
|
||||||
let data: Data?
|
let data: Data?
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ public struct TestableConfiguration: Codable {
|
|||||||
var shellOutput: [String: BatchFakeShellOutput]
|
var shellOutput: [String: BatchFakeShellOutput]
|
||||||
var commandOutput: [String: String]
|
var commandOutput: [String: String]
|
||||||
var preferenceOverrides: [PreferenceName: Bool]
|
var preferenceOverrides: [PreferenceName: Bool]
|
||||||
|
var apiGetResponses: [URL: FakeWebApiResponse]
|
||||||
|
var apiPostResponses: [URL: FakeWebApiResponse]
|
||||||
|
|
||||||
init(
|
init(
|
||||||
architecture: String,
|
architecture: String,
|
||||||
@@ -21,13 +23,17 @@ public struct TestableConfiguration: Codable {
|
|||||||
shellOutput: [String: BatchFakeShellOutput],
|
shellOutput: [String: BatchFakeShellOutput],
|
||||||
commandOutput: [String: String],
|
commandOutput: [String: String],
|
||||||
preferenceOverrides: [PreferenceName: Bool],
|
preferenceOverrides: [PreferenceName: Bool],
|
||||||
phpVersions: [VersionNumber]
|
phpVersions: [VersionNumber],
|
||||||
|
apiGetResponses: [URL: FakeWebApiResponse],
|
||||||
|
apiPostResponses: [URL: FakeWebApiResponse]
|
||||||
) {
|
) {
|
||||||
self.architecture = architecture
|
self.architecture = architecture
|
||||||
self.filesystem = filesystem
|
self.filesystem = filesystem
|
||||||
self.shellOutput = shellOutput
|
self.shellOutput = shellOutput
|
||||||
self.commandOutput = commandOutput
|
self.commandOutput = commandOutput
|
||||||
self.preferenceOverrides = preferenceOverrides
|
self.preferenceOverrides = preferenceOverrides
|
||||||
|
self.apiGetResponses = apiGetResponses
|
||||||
|
self.apiPostResponses = apiPostResponses
|
||||||
|
|
||||||
phpVersions.enumerated().forEach { (index, version) in
|
phpVersions.enumerated().forEach { (index, version) in
|
||||||
self.addPhpVersion(version, primary: index == 0)
|
self.addPhpVersion(version, primary: index == 0)
|
||||||
@@ -35,7 +41,13 @@ public struct TestableConfiguration: Codable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case architecture, filesystem, shellOutput, commandOutput, preferenceOverrides
|
case architecture,
|
||||||
|
filesystem,
|
||||||
|
shellOutput,
|
||||||
|
commandOutput,
|
||||||
|
preferenceOverrides,
|
||||||
|
apiGetResponses,
|
||||||
|
apiPostResponses
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Add PHP versions
|
// MARK: Add PHP versions
|
||||||
|
|||||||
@@ -107,7 +107,9 @@ class Container {
|
|||||||
self.overrideFake(
|
self.overrideFake(
|
||||||
shellExpectations: config.shellOutput,
|
shellExpectations: config.shellOutput,
|
||||||
fileSystemFiles: config.filesystem,
|
fileSystemFiles: config.filesystem,
|
||||||
commands: config.commandOutput
|
commands: config.commandOutput,
|
||||||
|
webApiGetResponses: config.apiGetResponses,
|
||||||
|
webApiPostResponses: config.apiPostResponses
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
// However, for the real deal, we will use the Web API
|
||||||
if isRunningTests || App.hasLoadedTestableConfiguration || url.absoluteString.contains("https://raw.githubusercontent.com") {
|
guard let response = try? await container.webApi.get(
|
||||||
// For testing simplicity, we will use curl, since we need no complex rules or headers
|
url,
|
||||||
return CaskFile.from(await container.shell.pipe("curl -s --max-time 10 '\(url.absoluteString)'").out)
|
withHeaders: container.webApi.defaultHeaders,
|
||||||
} else {
|
withTimeout: .seconds(10)
|
||||||
// However, for the real deal, we will use the Web API
|
) else {
|
||||||
guard let response = try? await container.webApi.get(
|
throw CaskFileError.requestFailed
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guard let text = response.plainText else {
|
||||||
|
throw CaskFileError.invalidData
|
||||||
|
}
|
||||||
|
|
||||||
|
return CaskFile.from(text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
},
|
},
|
||||||
"testTargets" : [
|
"testTargets" : [
|
||||||
{
|
{
|
||||||
|
"enabled" : false,
|
||||||
"parallelizable" : true,
|
"parallelizable" : true,
|
||||||
"target" : {
|
"target" : {
|
||||||
"containerPath" : "container:PHP Monitor.xcodeproj",
|
"containerPath" : "container:PHP Monitor.xcodeproj",
|
||||||
@@ -30,7 +31,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"enabled" : false,
|
|
||||||
"target" : {
|
"target" : {
|
||||||
"containerPath" : "container:PHP Monitor.xcodeproj",
|
"containerPath" : "container:PHP Monitor.xcodeproj",
|
||||||
"identifier" : "C471E7BB28F9B90F0021E251",
|
"identifier" : "C471E7BB28F9B90F0021E251",
|
||||||
|
|||||||
@@ -138,36 +138,6 @@ class TestableConfigurations {
|
|||||||
: .instant(ShellStrings.shared.brewServicesAsRoot),
|
: .instant(ShellStrings.shared.brewServicesAsRoot),
|
||||||
"/opt/homebrew/bin/brew services info --all --json"
|
"/opt/homebrew/bin/brew services info --all --json"
|
||||||
: .instant(ShellStrings.shared.brewServicesAsUser),
|
: .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"
|
"/opt/homebrew/bin/brew unlink php"
|
||||||
: .delayed(0.2, "OK"),
|
: .delayed(0.2, "OK"),
|
||||||
"/opt/homebrew/bin/brew unlink php@8.2"
|
"/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: 1, patch: 0),
|
||||||
VersionNumber(major: 8, minor: 0, patch: 0),
|
VersionNumber(major: 8, minor: 0, patch: 0),
|
||||||
VersionNumber(major: 7, minor: 4, patch: 33)
|
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: [:]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,10 @@ final class UpdateCheckTest: UITestCase {
|
|||||||
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = true
|
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = true
|
||||||
|
|
||||||
// Ensure an update is available
|
// Ensure an update is available
|
||||||
configuration.shellOutput[
|
configuration.apiGetResponses[url("\(Constants.Urls.UpdateCheckEndpoint.absoluteString)")] = FakeWebApiResponse(
|
||||||
"curl -s --max-time 10 '\(Constants.Urls.UpdateCheckEndpoint.absoluteString)'"
|
statusCode: 200,
|
||||||
] = .delayed(0.5, """
|
headers: [:],
|
||||||
|
text: """
|
||||||
cask 'phpmon-dev' do
|
cask 'phpmon-dev' do
|
||||||
depends_on formula: 'gnu-sed'
|
depends_on formula: 'gnu-sed'
|
||||||
|
|
||||||
@@ -46,7 +47,9 @@ final class UpdateCheckTest: UITestCase {
|
|||||||
|
|
||||||
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
|
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
|
||||||
end
|
end
|
||||||
""")
|
""",
|
||||||
|
duration: 0.5
|
||||||
|
)
|
||||||
|
|
||||||
let app = launch(openMenu: false, with: configuration)
|
let app = launch(openMenu: false, with: configuration)
|
||||||
|
|
||||||
@@ -64,7 +67,10 @@ final class UpdateCheckTest: UITestCase {
|
|||||||
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false
|
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false
|
||||||
|
|
||||||
// Ensure an update is available
|
// 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
|
cask 'phpmon-dev' do
|
||||||
depends_on formula: 'gnu-sed'
|
depends_on formula: 'gnu-sed'
|
||||||
|
|
||||||
@@ -77,7 +83,9 @@ final class UpdateCheckTest: UITestCase {
|
|||||||
|
|
||||||
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
|
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
|
||||||
end
|
end
|
||||||
""")
|
""",
|
||||||
|
duration: 0.5
|
||||||
|
)
|
||||||
|
|
||||||
// Wait for the menu to open and search for updates
|
// Wait for the menu to open and search for updates
|
||||||
let app = launch(openMenu: false, with: configuration)
|
let app = launch(openMenu: false, with: configuration)
|
||||||
@@ -93,7 +101,10 @@ final class UpdateCheckTest: UITestCase {
|
|||||||
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false
|
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false
|
||||||
|
|
||||||
// Ensure an update is available
|
// 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
|
cask 'phpmon-dev' do
|
||||||
depends_on formula: 'gnu-sed'
|
depends_on formula: 'gnu-sed'
|
||||||
|
|
||||||
@@ -106,7 +117,9 @@ final class UpdateCheckTest: UITestCase {
|
|||||||
|
|
||||||
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
|
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
|
||||||
end
|
end
|
||||||
""")
|
""",
|
||||||
|
duration: 0.5
|
||||||
|
)
|
||||||
|
|
||||||
// Wait for the menu to open and search for updates
|
// Wait for the menu to open and search for updates
|
||||||
let app = launch(openMenu: true, with: configuration)
|
let app = launch(openMenu: true, with: configuration)
|
||||||
@@ -125,7 +138,14 @@ final class UpdateCheckTest: UITestCase {
|
|||||||
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false
|
configuration.preferenceOverrides[.automaticBackgroundUpdateCheck] = false
|
||||||
|
|
||||||
// Ensure an update is available
|
// 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
|
// Wait for the menu to open and search for updates
|
||||||
let app = launch(openMenu: true, with: configuration)
|
let app = launch(openMenu: true, with: configuration)
|
||||||
|
|||||||
Reference in New Issue
Block a user