Skip to content

Commit 6d6e352

Browse files
jkmasselclaude
andcommitted
Use shared fixture files for API root responses on all platforms
Replace inline hardcoded JSON in Swift and Kotlin mock helpers with reads from the shared fixture files in test-data/login-mocks/. This ensures all three platforms (Rust, Swift, Kotlin) use the same JSON fixtures, preventing responses from getting out of sync. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 07b8b42 commit 6d6e352

File tree

4 files changed

+30
-57
lines changed

4 files changed

+30
-57
lines changed

native/kotlin/api/kotlin/src/integrationTest/kotlin/ApiUrlDiscoveryTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ class ApiUrlDiscoveryTest {
210210
),
211211
Stub.forUrl(
212212
"https://aggressive-caching.wpmt.co/wp-json/",
213-
WpNetworkResponse.vanillaApiRoot("https://aggressive-caching.wpmt.co")
213+
WpNetworkResponse.jsonResponse("/login-mocks/aggressive-caching-api-root.json")
214214
),
215215
)
216216
)

native/kotlin/api/kotlin/src/integrationTest/kotlin/MockRequestExecutor.kt

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -151,29 +151,4 @@ fun WpNetworkResponse.Companion.responseWithStatus(
151151
)
152152
}
153153

154-
fun WpNetworkResponse.Companion.vanillaApiRoot(siteUrl: String): WpNetworkResponse {
155-
val json = """
156-
{"name":"Test Site","description":"","url":"$siteUrl","home":"$siteUrl","gmt_offset":0,"timezone_string":"UTC","namespaces":["oembed/1.0","wp/v2","wp-site-health/v1"],"authentication":{"application-passwords":{"endpoints":{"authorization":"$siteUrl/wp-admin/authorize-application.php"}}},"routes":{},"site_logo":0,"site_icon":0,"site_icon_url":""}
157-
""".trimIndent()
158-
return WpNetworkResponse(
159-
json.toByteArray(),
160-
200u,
161-
WpNetworkHeaderMap.fromMap(mapOf("Content-Type" to "application/json")),
162-
"",
163-
WpNetworkHeaderMap.empty
164-
)
165-
}
166-
167-
fun WpNetworkResponse.Companion.httpOnlyApiRoot(siteUrl: String): WpNetworkResponse {
168-
val json = """
169-
{"name":"Test Site","description":"","url":"$siteUrl","home":"$siteUrl","gmt_offset":0,"timezone_string":"UTC","namespaces":["oembed/1.0","wp/v2","wp-site-health/v1"],"authentication":{},"routes":{},"site_logo":0,"site_icon":0,"site_icon_url":""}
170-
""".trimIndent()
171-
return WpNetworkResponse(
172-
json.toByteArray(),
173-
200u,
174-
WpNetworkHeaderMap.fromMap(mapOf("Content-Type" to "application/json")),
175-
"",
176-
WpNetworkHeaderMap.empty
177-
)
178-
}
179154

native/swift/Tests/wordpress-api/LoginTests.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class LoginTests {
1717
func testValidURL() async throws {
1818
let stubs = HTTPStubs(stubs: [
1919
try HTTPStubs.stub(url: "https://vanilla.wpmt.co/", with: .withApiRoot("https://vanilla.wpmt.co/wp-json/")),
20-
try HTTPStubs.stub(url: "https://vanilla.wpmt.co/wp-json/", with: .vanillaApiRoot(siteUrl: "https://vanilla.wpmt.co"))
20+
try HTTPStubs.stub(url: "https://vanilla.wpmt.co/wp-json/", with: .loginMockResponse(named: "vanilla-api-root"))
2121
])
2222
let client = WordPressLoginClient(requestExecutor: stubs)
2323
let parsedUrl = try await client.findLoginUrl(forSite: "https://vanilla.wpmt.co")
@@ -59,7 +59,7 @@ class LoginTests {
5959
// The AutoStrippedHttps attempt strips the admin suffix and succeeds.
6060
let stubs = HTTPStubs(stubs: [
6161
try HTTPStubs.stub(url: "https://vanilla.wpmt.co/", with: .withApiRoot("https://vanilla.wpmt.co/wp-json/")),
62-
try HTTPStubs.stub(url: "https://vanilla.wpmt.co/wp-json/", with: .vanillaApiRoot(siteUrl: "https://vanilla.wpmt.co"))
62+
try HTTPStubs.stub(url: "https://vanilla.wpmt.co/wp-json/", with: .loginMockResponse(named: "vanilla-api-root"))
6363
])
6464
let client = WordPressLoginClient(requestExecutor: stubs)
6565
let parsedUrl = try await client.findLoginUrl(forSite: provided)
@@ -72,7 +72,7 @@ class LoginTests {
7272
// AutoStrippedHttps attempt converts to https:// and succeeds.
7373
let stubs = HTTPStubs(stubs: [
7474
try HTTPStubs.stub(url: "https://vanilla.wpmt.co/", with: .withApiRoot("https://vanilla.wpmt.co/wp-json/")),
75-
try HTTPStubs.stub(url: "https://vanilla.wpmt.co/wp-json/", with: .vanillaApiRoot(siteUrl: "https://vanilla.wpmt.co"))
75+
try HTTPStubs.stub(url: "https://vanilla.wpmt.co/wp-json/", with: .loginMockResponse(named: "vanilla-api-root"))
7676
])
7777
let client = WordPressLoginClient(requestExecutor: stubs)
7878
let parsedUrl = try await client.findLoginUrl(forSite: "http://vanilla.wpmt.co")
@@ -85,7 +85,7 @@ class LoginTests {
8585
do {
8686
stubs = HTTPStubs(stubs: [
8787
try HTTPStubs.stub(url: "http://no-https.wpmt.co/", with: .withApiRoot("http://no-https.wpmt.co/wp-json/")),
88-
try HTTPStubs.stub(url: "http://no-https.wpmt.co/wp-json/", with: .httpOnlyApiRoot(siteUrl: "http://no-https.wpmt.co"))
88+
try HTTPStubs.stub(url: "http://no-https.wpmt.co/wp-json/", with: .loginMockResponse(named: "http-only-api-root"))
8989
])
9090
} catch {
9191
Issue.record("Failed to create stubs: \(error)")
@@ -111,7 +111,7 @@ class LoginTests {
111111
func testHttpOnlySiteWithApplicationPasswordsEnabled() async throws {
112112
let stubs = HTTPStubs(stubs: [
113113
try HTTPStubs.stub(url: "http://no-https-with-application-passwords.wpmt.co/", with: .withApiRoot("http://no-https-with-application-passwords.wpmt.co/wp-json/")),
114-
try HTTPStubs.stub(url: "http://no-https-with-application-passwords.wpmt.co/wp-json/", with: .httpOnlyWithAppPasswordsApiRoot(siteUrl: "http://no-https-with-application-passwords.wpmt.co"))
114+
try HTTPStubs.stub(url: "http://no-https-with-application-passwords.wpmt.co/wp-json/", with: .loginMockResponse(named: "http-only-with-app-passwords-api-root"))
115115
])
116116
let client = WordPressLoginClient(requestExecutor: stubs)
117117
let parsedUrl = try await client.findLoginUrl(forSite: "http://no-https-with-application-passwords.wpmt.co")
@@ -123,7 +123,7 @@ class LoginTests {
123123
// Homepage has no Link header, but HTML contains a <link> tag pointing to the API root
124124
let stubs = HTTPStubs(stubs: [
125125
try HTTPStubs.stub(url: "https://aggressive-caching.wpmt.co/", with: .htmlResponse(named: "homepage-with-link-tag")),
126-
try HTTPStubs.stub(url: "https://aggressive-caching.wpmt.co/wp-json/", with: .vanillaApiRoot(siteUrl: "https://aggressive-caching.wpmt.co"))
126+
try HTTPStubs.stub(url: "https://aggressive-caching.wpmt.co/wp-json/", with: .loginMockResponse(named: "aggressive-caching-api-root"))
127127
])
128128
let client = WordPressLoginClient(requestExecutor: stubs)
129129
let parsedUrl = try await client.findLoginUrl(forSite: "https://aggressive-caching.wpmt.co")
@@ -186,7 +186,7 @@ class LoginTests {
186186
func testWordPressSubdirectoryWithLinkHeader() async throws {
187187
let stubs = HTTPStubs(stubs: [
188188
try HTTPStubs.stub(url: "https://subdirectory.wpmt.co/index.php?link_header=true", with: .withApiRoot("https://subdirectory.wpmt.co/wordpress/wp-json/")),
189-
try HTTPStubs.stub(url: "https://subdirectory.wpmt.co/wordpress/wp-json/", with: .vanillaApiRoot(siteUrl: "https://subdirectory.wpmt.co/wordpress"))
189+
try HTTPStubs.stub(url: "https://subdirectory.wpmt.co/wordpress/wp-json/", with: .loginMockResponse(named: "subdirectory-api-root"))
190190
])
191191
let client = WordPressLoginClient(requestExecutor: stubs)
192192
let parsedUrl = try await client.findLoginUrl(forSite: "https://subdirectory.wpmt.co/index.php?link_header=true")
@@ -198,7 +198,7 @@ class LoginTests {
198198
// Homepage has no Link header but HTML contains a <link> tag pointing to subdirectory wp-json
199199
let stubs = HTTPStubs(stubs: [
200200
try HTTPStubs.stub(url: "https://subdirectory.wpmt.co/index.php?link_tag=true", with: .htmlResponse(named: "homepage-with-subdirectory-link-tag")),
201-
try HTTPStubs.stub(url: "https://subdirectory.wpmt.co/wordpress/wp-json/", with: .vanillaApiRoot(siteUrl: "https://subdirectory.wpmt.co/wordpress"))
201+
try HTTPStubs.stub(url: "https://subdirectory.wpmt.co/wordpress/wp-json/", with: .loginMockResponse(named: "subdirectory-api-root"))
202202
])
203203
let client = WordPressLoginClient(requestExecutor: stubs)
204204
let parsedUrl = try await client.findLoginUrl(forSite: "https://subdirectory.wpmt.co/index.php?link_tag=true")
@@ -211,7 +211,7 @@ class LoginTests {
211211
// With mocks, we simulate the final response directly on the requested URL.
212212
let stubs = HTTPStubs(stubs: [
213213
try HTTPStubs.stub(url: "https://subdirectory.wpmt.co/index.php?redirect=true", with: .withApiRoot("https://subdirectory.wpmt.co/wordpress/wp-json/")),
214-
try HTTPStubs.stub(url: "https://subdirectory.wpmt.co/wordpress/wp-json/", with: .vanillaApiRoot(siteUrl: "https://subdirectory.wpmt.co/wordpress"))
214+
try HTTPStubs.stub(url: "https://subdirectory.wpmt.co/wordpress/wp-json/", with: .loginMockResponse(named: "subdirectory-api-root"))
215215
])
216216
let client = WordPressLoginClient(requestExecutor: stubs)
217217
let parsedUrl = try await client.findLoginUrl(forSite: "https://subdirectory.wpmt.co/index.php?redirect=true")
@@ -287,7 +287,7 @@ class LoginTests {
287287
func testWordPressHttpBasicWithValidCredentials() async throws {
288288
let stubs = HTTPStubs(stubs: [
289289
try HTTPStubs.stub(url: "https://basic-auth.wpmt.co/", with: .withApiRoot("https://basic-auth.wpmt.co/wp-json/")),
290-
try HTTPStubs.stub(url: "https://basic-auth.wpmt.co/wp-json/", with: .vanillaApiRoot(siteUrl: "https://basic-auth.wpmt.co"))
290+
try HTTPStubs.stub(url: "https://basic-auth.wpmt.co/wp-json/", with: .loginMockResponse(named: "basic-auth-api-root"))
291291
])
292292
let valid = ApiDiscoveryAuthenticationMiddleware(username: "test@example.com", password: "str0ngp4ssw0rd!")
293293

@@ -305,7 +305,7 @@ class LoginTests {
305305
// The Link header points to the custom API root
306306
let stubs = HTTPStubs(stubs: [
307307
try HTTPStubs.stub(url: "https://custom-rest-prefix.wpmt.co/", with: .withApiRoot("https://custom-rest-prefix.wpmt.co/custom-api/")),
308-
try HTTPStubs.stub(url: "https://custom-rest-prefix.wpmt.co/custom-api/", with: .vanillaApiRoot(siteUrl: "https://custom-rest-prefix.wpmt.co"))
308+
try HTTPStubs.stub(url: "https://custom-rest-prefix.wpmt.co/custom-api/", with: .loginMockResponse(named: "custom-rest-prefix-api-root"))
309309
])
310310
let client = WordPressLoginClient(requestExecutor: stubs)
311311
let parsedUrl = try await client.findLoginUrl(forSite: "https://custom-rest-prefix.wpmt.co")

native/swift/Tests/wordpress-api/Support/HTTPStubs.swift

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,24 @@ extension WpNetworkResponse {
132132
)
133133
}
134134

135+
static func loginMockResponse(named name: String) throws -> WpNetworkResponse {
136+
137+
guard let resourceUrl = Bundle
138+
.module
139+
.url(forResource: name, withExtension: "json", subdirectory: "login-mocks")
140+
else {
141+
preconditionFailure("Could not find \(name).json in login-mocks")
142+
}
143+
144+
return WpNetworkResponse(
145+
body: try Data(contentsOf: resourceUrl),
146+
statusCode: 200,
147+
responseHeaderMap: try WpNetworkHeaderMap.fromMap(hashMap: ["Content-Type": "application/json"]),
148+
requestUrl: "https://example.com",
149+
requestHeaderMap: .empty
150+
)
151+
}
152+
135153
static func retryResponse(after: TimeInterval) throws -> WpNetworkResponse {
136154
return WpNetworkResponse(
137155
body: Data(),
@@ -181,24 +199,4 @@ extension WpNetworkResponse {
181199
)
182200
}
183201

184-
// MARK: - API Root Response Helpers
185-
186-
static func vanillaApiRoot(siteUrl: String) throws -> WpNetworkResponse {
187-
try .json("""
188-
{"name":"Test Site","description":"","url":"\(siteUrl)","home":"\(siteUrl)","gmt_offset":0,"timezone_string":"UTC","namespaces":["oembed/1.0","wp/v2","wp-site-health/v1"],"authentication":{"application-passwords":{"endpoints":{"authorization":"\(siteUrl)/wp-admin/authorize-application.php"}}},"routes":{},"site_logo":0,"site_icon":0,"site_icon_url":""}
189-
""")
190-
}
191-
192-
static func httpOnlyApiRoot(siteUrl: String) throws -> WpNetworkResponse {
193-
try .json("""
194-
{"name":"HTTP Only Site","description":"","url":"\(siteUrl)","home":"\(siteUrl)","gmt_offset":0,"timezone_string":"UTC","namespaces":["oembed/1.0","wp/v2","wp-site-health/v1"],"authentication":{},"routes":{},"site_logo":0,"site_icon":0,"site_icon_url":""}
195-
""")
196-
}
197-
198-
static func httpOnlyWithAppPasswordsApiRoot(siteUrl: String) throws -> WpNetworkResponse {
199-
try .json("""
200-
{"name":"HTTP Site with App Passwords","description":"","url":"\(siteUrl)","home":"\(siteUrl)","gmt_offset":0,"timezone_string":"UTC","namespaces":["oembed/1.0","wp/v2","wp-site-health/v1"],"authentication":{"application-passwords":{"endpoints":{"authorization":"\(siteUrl)/wp-admin/authorize-application.php"}}},"routes":{},"site_logo":0,"site_icon":0,"site_icon_url":""}
201-
""")
202-
}
203-
204202
}

0 commit comments

Comments
 (0)