Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.

Commit 9a59c67

Browse files
committed
Use XCTUnwrap instead of force-unwrapping for fixture paths in tests
This will make it easier to run the tests once the fixture files move around. If a file is misplaced, the test will fail instead of crashing. Operationally, failing is better than crashing because it generates a list of all misplaced tests, so that they can be addressed in one go. The alternative would be a run tests, tests crash, fix individual file path loop for as many misplaced fixture files there are.
1 parent 0e8dec4 commit 9a59c67

7 files changed

+177
-113
lines changed

WordPressKitTests/ReaderSiteServiceRemoteTests.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,12 @@ class ReaderSiteServiceRemoteTests: XCTestCase {
289289
XCTAssertTrue(failure)
290290
}
291291

292-
func testCheckSiteExistsAtURLSuccess() {
292+
func testCheckSiteExistsAtURLSuccess() throws {
293293
let testURLString = "http://www.wordpress.com"
294294
let testURL = URL(string: testURLString)!
295+
let stubPath = try XCTUnwrap(OHPathForFile("empty.json", type(of: self)))
295296
stub(condition: {request in request.url?.absoluteString == testURLString}) { _ in
296-
let stubPath = OHPathForFile("empty.json", type(of: self))
297-
return fixture(filePath: stubPath!, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
297+
return fixture(filePath: stubPath, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
298298
}
299299

300300
let expect = self.expectation(description: "One callback should be invoked")
@@ -308,12 +308,16 @@ class ReaderSiteServiceRemoteTests: XCTestCase {
308308
self.waitForExpectations(timeout: 2, handler: nil)
309309
}
310310

311-
func testCheckSiteExistsAtURLFailure() {
311+
func testCheckSiteExistsAtURLFailure() throws {
312312
let testURLString = "http://www.wordpress.com"
313313
let testURL = URL(string: testURLString)!
314+
let stubPath = try XCTUnwrap(OHPathForFile("empty.json", type(of: self)))
314315
stub(condition: {request in request.url?.absoluteString == testURLString}) { _ in
315-
let stubPath = OHPathForFile("empty.json", type(of: self))
316-
return fixture(filePath: stubPath!, status: 400, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
316+
return fixture(
317+
filePath: stubPath,
318+
status: 400,
319+
headers: ["Content-Type" as NSObject: "application/json" as AnyObject]
320+
)
317321
}
318322

319323
let expect = self.expectation(description: "One callback should be invoked")

WordPressKitTests/RemoteTestCase.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,15 @@ extension RemoteTestCase {
5454
contentType: ResponseContentType,
5555
status: Int32 = 200
5656
) {
57+
// This doesn't follow the XCTUnwrap pattern (yet?) because the method is used many times and it was too time consuming to update every call site at the time
58+
let stubPath = OHPathForFile(filename, type(of: self))
5759
stub(condition: condition) { _ in
58-
let stubPath = OHPathForFile(filename, type(of: self))
5960
var headers: [NSObject: AnyObject]?
6061

6162
if contentType != .NoContentType {
6263
headers = ["Content-Type" as NSObject: contentType.rawValue as AnyObject]
6364
}
65+
// This is force-unwrapped at call site, despite it making more sense at declaration site, so it can be found when grepping for force unwraps.
6466
return OHHTTPStubs.fixture(filePath: stubPath!, status: status, headers: headers)
6567
}
6668
}
@@ -74,15 +76,17 @@ extension RemoteTestCase {
7476
/// - status: The status code to use for the response. Defaults to 200.
7577
///
7678
func stubRemoteResponse(_ endpoint: String, filename: String, contentType: ResponseContentType, status: Int32 = 200) {
79+
// This doesn't follow the XCTUnwrap pattern (yet?) because the method is used many times and it was too time consuming to update every call site at the time
80+
let stubPath = OHPathForFile(filename, type(of: self))
7781
stub(condition: { request in
7882
return request.url?.absoluteString.range(of: endpoint) != nil
7983
}) { _ in
80-
let stubPath = OHPathForFile(filename, type(of: self))
8184
var headers: [NSObject: AnyObject]?
8285

8386
if contentType != .NoContentType {
8487
headers = ["Content-Type" as NSObject: contentType.rawValue as AnyObject]
8588
}
89+
// This is force-unwrapped at call site, despite it making more sense at declaration site, so it can be found when grepping for force unwraps.
8690
return fixture(filePath: stubPath!, status: status, headers: headers)
8791
}
8892
}

WordPressKitTests/WordPressComOAuthClientTests.swift

Lines changed: 79 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ class WordPressComOAuthClientTests: XCTestCase {
2626
}
2727
}
2828

29-
func testAuthenticateUsernameNo2FASuccessCase() {
29+
func testAuthenticateUsernameNo2FASuccessCase() throws {
30+
let stubPath = try XCTUnwrap(OHPathForFile("WordPressComOAuthSuccess.json", type(of: self)))
3031
stub(condition: isOauthTokenRequest(url: .oAuthTokenUrl)) { _ in
31-
let stubPath = OHPathForFile("WordPressComOAuthSuccess.json", type(of: self))
32-
return fixture(filePath: stubPath!, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
32+
return fixture(filePath: stubPath, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
3333
}
3434

3535
let expect = expectation(description: "One callback should be invoked")
@@ -52,10 +52,10 @@ class WordPressComOAuthClientTests: XCTestCase {
5252
waitForExpectations(timeout: 2, handler: nil)
5353
}
5454

55-
func testAuthenticateUsernameNo2FASuccessCase_withMFAClosure() {
55+
func testAuthenticateUsernameNo2FASuccessCase_withMFAClosure() throws {
56+
let stubPath = try XCTUnwrap(OHPathForFile("WordPressComOAuthSuccess.json", type(of: self)))
5657
stub(condition: isOauthTokenRequest(url: .oAuthTokenUrl)) { _ in
57-
let stubPath = OHPathForFile("WordPressComOAuthSuccess.json", type(of: self))
58-
return fixture(filePath: stubPath!, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
58+
return fixture(filePath: stubPath, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
5959
}
6060

6161
let expect = expectation(description: "One callback should be invoked")
@@ -81,10 +81,12 @@ class WordPressComOAuthClientTests: XCTestCase {
8181
waitForExpectations(timeout: 2, handler: nil)
8282
}
8383

84-
func testAuthenticateUsernameNo2FAFailureWrongPasswordCase() {
84+
func testAuthenticateUsernameNo2FAFailureWrongPasswordCase() throws {
85+
let stubPath = try XCTUnwrap(
86+
OHPathForFile("WordPressComOAuthWrongPasswordFail.json", type(of: self))
87+
)
8588
stub(condition: isOauthTokenRequest(url: .oAuthTokenUrl)) { _ in
86-
let stubPath = OHPathForFile("WordPressComOAuthWrongPasswordFail.json", type(of: self))
87-
return fixture(filePath: stubPath!, status: 400, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
89+
return fixture(filePath: stubPath, status: 400, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
8890
}
8991

9092
let expect = expectation(description: "One callback should be invoked")
@@ -106,10 +108,12 @@ class WordPressComOAuthClientTests: XCTestCase {
106108
waitForExpectations(timeout: 2, handler: nil)
107109
}
108110

109-
func testAuthenticateUsernameNo2FAFailureWrongPasswordCase_withMFAClosure() {
111+
func testAuthenticateUsernameNo2FAFailureWrongPasswordCase_withMFAClosure() throws {
112+
let stubPath = try XCTUnwrap(
113+
OHPathForFile("WordPressComOAuthWrongPasswordFail.json", type(of: self))
114+
)
110115
stub(condition: isOauthTokenRequest(url: .oAuthTokenUrl)) { _ in
111-
let stubPath = OHPathForFile("WordPressComOAuthWrongPasswordFail.json", type(of: self))
112-
return fixture(filePath: stubPath!, status: 400, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
116+
return fixture(filePath: stubPath, status: 400, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
113117
}
114118

115119
let expect = expectation(description: "One callback should be invoked")
@@ -134,10 +138,16 @@ class WordPressComOAuthClientTests: XCTestCase {
134138
waitForExpectations(timeout: 2, handler: nil)
135139
}
136140

137-
func testAuthenticateUsername2FAWrong2FACase() {
141+
func testAuthenticateUsername2FAWrong2FACase() throws {
142+
let stubPath = try XCTUnwrap(
143+
OHPathForFile("WordPressComOAuthNeeds2FAFail.json", type(of: self))
144+
)
138145
stub(condition: isOauthTokenRequest(url: .oAuthTokenUrl)) { _ in
139-
let stubPath = OHPathForFile("WordPressComOAuthNeeds2FAFail.json", type(of: self))
140-
return fixture(filePath: stubPath!, status: 400, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
146+
return fixture(
147+
filePath: stubPath,
148+
status: 400,
149+
headers: ["Content-Type" as NSObject: "application/json" as AnyObject]
150+
)
141151
}
142152

143153
let expect = expectation(description: "Call should complete")
@@ -179,10 +189,16 @@ class WordPressComOAuthClientTests: XCTestCase {
179189
waitForExpectations(timeout: 2, handler: nil)
180190
}
181191

182-
func testAuthenticateUsername2FAWrong2FACase_withMFAClosure() {
192+
func testAuthenticateUsername2FAWrong2FACase_withMFAClosure() throws {
193+
let stubPath = try XCTUnwrap(
194+
OHPathForFile("WordPressComOAuthNeeds2FAFail.json", type(of: self))
195+
)
183196
stub(condition: isOauthTokenRequest(url: .oAuthTokenUrl)) { _ in
184-
let stubPath = OHPathForFile("WordPressComOAuthNeeds2FAFail.json", type(of: self))
185-
return fixture(filePath: stubPath!, status: 400, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
197+
return fixture(
198+
filePath: stubPath,
199+
status: 400,
200+
headers: ["Content-Type" as NSObject: "application/json" as AnyObject]
201+
)
186202
}
187203

188204
let expect = expectation(description: "Call should complete")
@@ -227,10 +243,12 @@ class WordPressComOAuthClientTests: XCTestCase {
227243
waitForExpectations(timeout: 2, handler: nil)
228244
}
229245

230-
func testAuthenticateUsernameRequiresWebauthnMultifactorAuthentication() {
246+
func testAuthenticateUsernameRequiresWebauthnMultifactorAuthentication() throws {
247+
let stubPath = try XCTUnwrap(
248+
OHPathForFile("WordPressComOAuthNeedsWebauthnMFA.json", type(of: self))
249+
)
231250
stub(condition: isOauthTokenRequest(url: .oAuthTokenUrl)) { _ in
232-
let stubPath = OHPathForFile("WordPressComOAuthNeedsWebauthnMFA.json", type(of: self))
233-
return fixture(filePath: stubPath!, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
251+
return fixture(filePath: stubPath, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
234252
}
235253

236254
let expect = expectation(description: "Call should complete")
@@ -256,10 +274,12 @@ class WordPressComOAuthClientTests: XCTestCase {
256274
waitForExpectations(timeout: 2, handler: nil)
257275
}
258276

259-
func testRequestOneTimeCodeWithUsername() {
277+
func testRequestOneTimeCodeWithUsername() throws {
278+
let stubPath = try XCTUnwrap(
279+
OHPathForFile("WordPressComOAuthNeeds2FAFail.json", type(of: self))
280+
)
260281
stub(condition: isOauthTokenRequest(url: .oAuthTokenUrl)) { _ in
261-
let stubPath = OHPathForFile("WordPressComOAuthNeeds2FAFail.json", type(of: self))
262-
return fixture(filePath: stubPath!, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
282+
return fixture(filePath: stubPath, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
263283
}
264284

265285
let expect = expectation(description: "One callback should be invoked")
@@ -275,10 +295,12 @@ class WordPressComOAuthClientTests: XCTestCase {
275295
waitForExpectations(timeout: 2, handler: nil)
276296
}
277297

278-
func testRequestSocial2FACodeWithUserID() {
298+
func testRequestSocial2FACodeWithUserID() throws {
299+
let stubPath = try XCTUnwrap(
300+
OHPathForFile("WordPressComSocial2FACodeSuccess.json", type(of: self))
301+
)
279302
stub(condition: isOauthTokenRequest(url: .socialLoginNewSMS2FA)) { _ in
280-
let stubPath = OHPathForFile("WordPressComSocial2FACodeSuccess.json", type(of: self))
281-
return fixture(filePath: stubPath!, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
303+
return fixture(filePath: stubPath, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
282304
}
283305

284306
let expect = expectation(description: "One callback should be invoked")
@@ -296,10 +318,12 @@ class WordPressComOAuthClientTests: XCTestCase {
296318
waitForExpectations(timeout: 2, handler: nil)
297319
}
298320

299-
func testAuthenticateWithIDToken() {
321+
func testAuthenticateWithIDToken() throws {
322+
let stubPath = try XCTUnwrap(
323+
OHPathForFile("WordPressComAuthenticateWithIDTokenBearerTokenSuccess.json", type(of: self))
324+
)
300325
stub(condition: isOauthTokenRequest(url: .socialLogin)) { _ in
301-
let stubPath = OHPathForFile("WordPressComAuthenticateWithIDTokenBearerTokenSuccess.json", type(of: self))
302-
return fixture(filePath: stubPath!, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
326+
return fixture(filePath: stubPath, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
303327
}
304328

305329
let expect = expectation(description: "One callback should be invoked")
@@ -329,10 +353,12 @@ class WordPressComOAuthClientTests: XCTestCase {
329353
waitForExpectations(timeout: 2, handler: nil)
330354
}
331355

332-
func testAuthenticateWithIDToken2FANeeded() {
356+
func testAuthenticateWithIDToken2FANeeded() throws {
357+
let stubPath = try XCTUnwrap(
358+
OHPathForFile("WordPressComAuthenticateWithIDToken2FANeededSuccess.json", type(of: self))
359+
)
333360
stub(condition: isOauthTokenRequest(url: .socialLogin)) { _ in
334-
let stubPath = OHPathForFile("WordPressComAuthenticateWithIDToken2FANeededSuccess.json", type(of: self))
335-
return fixture(filePath: stubPath!, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
361+
return fixture(filePath: stubPath, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
336362
}
337363

338364
let expect = expectation(description: "One callback should be invoked")
@@ -363,10 +389,12 @@ class WordPressComOAuthClientTests: XCTestCase {
363389
waitForExpectations(timeout: 2, handler: nil)
364390
}
365391

366-
func testAuthenticateWithIDTokenUserNeedsConnection() {
392+
func testAuthenticateWithIDTokenUserNeedsConnection() throws {
393+
let stubPath = try XCTUnwrap(
394+
OHPathForFile("WordPressComAuthenticateWithIDTokenExistingUserNeedsConnection.json", type(of: self))
395+
)
367396
stub(condition: isOauthTokenRequest(url: .socialLogin)) { _ in
368-
let stubPath = OHPathForFile("WordPressComAuthenticateWithIDTokenExistingUserNeedsConnection.json", type(of: self))
369-
return fixture(filePath: stubPath!, status: 400, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
397+
return fixture(filePath: stubPath, status: 400, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
370398
}
371399

372400
let expect = expectation(description: "One callback should be invoked")
@@ -395,10 +423,12 @@ class WordPressComOAuthClientTests: XCTestCase {
395423
waitForExpectations(timeout: 2, handler: nil)
396424
}
397425

398-
func testAuthenticateSocialLoginUser() {
426+
func testAuthenticateSocialLoginUser() throws {
427+
let stubPath = try XCTUnwrap(
428+
OHPathForFile("WordPressComAuthenticateWithIDTokenBearerTokenSuccess.json", type(of: self))
429+
)
399430
stub(condition: isOauthTokenRequest(url: .socialLogin2FA)) { _ in
400-
let stubPath = OHPathForFile("WordPressComAuthenticateWithIDTokenBearerTokenSuccess.json", type(of: self))
401-
return fixture(filePath: stubPath!, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
431+
return fixture(filePath: stubPath, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
402432
}
403433

404434
let expect = expectation(description: "One callback should be invoked")
@@ -416,10 +446,12 @@ class WordPressComOAuthClientTests: XCTestCase {
416446
waitForExpectations(timeout: 2, handler: nil)
417447
}
418448

419-
func testRequestWebauthnChallengeReturnsCompleteChallengeInfo() {
449+
func testRequestWebauthnChallengeReturnsCompleteChallengeInfo() throws {
450+
let stubPath = try XCTUnwrap(
451+
OHPathForFile("WordPressComOAuthRequestChallenge.json", type(of: self))
452+
)
420453
stub(condition: isOauthTokenRequest(url: .requestWebauthnChallenge)) { _ in
421-
let stubPath = OHPathForFile("WordPressComOAuthRequestChallenge.json", type(of: self))
422-
return fixture(filePath: stubPath!, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
454+
return fixture(filePath: stubPath, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
423455
}
424456

425457
let expect = expectation(description: "One callback should be invoked")
@@ -437,10 +469,12 @@ class WordPressComOAuthClientTests: XCTestCase {
437469
waitForExpectations(timeout: 2, handler: nil)
438470
}
439471

440-
func testAuthenticateWebauthSignatureReturnsOauthToken() {
472+
func testAuthenticateWebauthSignatureReturnsOauthToken() throws {
473+
let stubPath = try XCTUnwrap(
474+
OHPathForFile("WordPressComOAuthAuthenticateSignature.json", type(of: self))
475+
)
441476
stub(condition: isOauthTokenRequest(url: .verifySignature)) { _ in
442-
let stubPath = OHPathForFile("WordPressComOAuthAuthenticateSignature.json", type(of: self))
443-
return fixture(filePath: stubPath!, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
477+
return fixture(filePath: stubPath, headers: ["Content-Type" as NSObject: "application/json" as AnyObject])
444478
}
445479

446480
let expect = expectation(description: "One callback should be invoked")

0 commit comments

Comments
 (0)