Skip to content

Commit f5afa99

Browse files
committed
Update BlockEditorSettingsService tests
Use HTTP stubs instead of fake implementations
1 parent bb220fd commit f5afa99

3 files changed

Lines changed: 77 additions & 90 deletions

File tree

WordPress/WordPressTest/BlockEditorSettingsServiceTests.swift

Lines changed: 76 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import XCTest
22
import Nimble
3+
import OHHTTPStubs
34
@testable import WordPress
45

56
class BlockEditorSettingsServiceTests: CoreDataTestCase {
@@ -10,30 +11,31 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
1011
private let blockSettingsThemeJSONResponseFilename = "wp-block-editor-v1-settings-success-ThemeJSON"
1112

1213
private var service: BlockEditorSettingsService!
13-
var mockRemoteApi: MockWordPressComRestApi!
1414
var gssOriginalValue: Bool!
1515
private var blog: Blog!
1616

1717
override func setUp() {
18-
mockRemoteApi = MockWordPressComRestApi()
1918
blog = BlogBuilder(mainContext)
2019
.with(wordPressVersion: "5.8")
2120
.withAnAccount()
2221
.build()
2322
contextManager.saveContextAndWait(mainContext)
24-
service = BlockEditorSettingsService(blog: blog, remoteAPI: mockRemoteApi, coreDataStack: contextManager)
23+
service = BlockEditorSettingsService(blog: blog, coreDataStack: contextManager)
2524
}
2625

2726
// MARK: Editor `theme_supports` support
2827
func testThemeSupportsNewTheme() {
2928
blog = BlogBuilder(mainContext)
3029
.with(wordPressVersion: "5.7")
3130
.with(isHostedAtWPCom: true)
31+
.withAnAccount()
3232
.build()
3333
contextManager.saveContextAndWait(mainContext)
3434

35-
service = BlockEditorSettingsService(blog: blog, remoteAPI: mockRemoteApi, coreDataStack: contextManager)
3635
let mockedResponse = mockedData(withFilename: twentytwentyoneResponseFilename)
36+
stubThemeRequest(response: HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil))
37+
38+
service = BlockEditorSettingsService(blog: blog, coreDataStack: contextManager)
3739
let waitExpectation = expectation(description: "Theme should be successfully fetched")
3840
service.fetchSettings { result in
3941
switch result {
@@ -46,8 +48,6 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
4648
waitExpectation.fulfill()
4749
}
4850

49-
mockRemoteApi.successBlockPassedIn!(mockedResponse, HTTPURLResponse())
50-
5151
waitForExpectations(timeout: expectationTimeout)
5252
validateThemeResponse()
5353
XCTAssertNotNil(self.blog.blockEditorSettings?.checksum)
@@ -57,15 +57,18 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
5757
blog = BlogBuilder(mainContext)
5858
.with(wordPressVersion: "5.7")
5959
.with(isHostedAtWPCom: true)
60+
.withAnAccount()
6061
.build()
6162
contextManager.saveContextAndWait(mainContext)
6263

63-
service = BlockEditorSettingsService(blog: blog, remoteAPI: mockRemoteApi, coreDataStack: contextManager)
64+
service = BlockEditorSettingsService(blog: blog, coreDataStack: contextManager)
6465

6566
setData(withFilename: twentytwentyResponseFilename)
6667
let originalChecksum = blog.blockEditorSettings?.checksum ?? ""
6768

6869
let mockedResponse = mockedData(withFilename: twentytwentyoneResponseFilename)
70+
stubThemeRequest(response: HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil))
71+
6972
let waitExpectation = expectation(description: "Theme should be successfully fetched")
7073
service.fetchSettings { result in
7174
switch result {
@@ -78,8 +81,6 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
7881
waitExpectation.fulfill()
7982
}
8083

81-
mockRemoteApi.successBlockPassedIn!(mockedResponse, HTTPURLResponse())
82-
8384
waitForExpectations(timeout: expectationTimeout)
8485
validateThemeResponse()
8586
XCTAssertNotEqual(self.blog.blockEditorSettings?.checksum, originalChecksum)
@@ -89,14 +90,17 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
8990
blog = BlogBuilder(mainContext)
9091
.with(wordPressVersion: "5.7")
9192
.with(isHostedAtWPCom: true)
93+
.withAnAccount()
9294
.build()
9395
contextManager.saveContextAndWait(mainContext)
9496

95-
service = BlockEditorSettingsService(blog: blog, remoteAPI: mockRemoteApi, coreDataStack: contextManager)
97+
service = BlockEditorSettingsService(blog: blog, coreDataStack: contextManager)
9698

9799
setData(withFilename: twentytwentyoneResponseFilename)
98100
let originalChecksum = blog.blockEditorSettings?.checksum ?? ""
101+
99102
let mockedResponse = mockedData(withFilename: twentytwentyoneResponseFilename)
103+
stubThemeRequest(response: HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil))
100104

101105
let waitExpectation = expectation(description: "Theme should be successfully fetched")
102106
service.fetchSettings { result in
@@ -109,25 +113,33 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
109113
}
110114
waitExpectation.fulfill()
111115
}
112-
mockRemoteApi.successBlockPassedIn!(mockedResponse, HTTPURLResponse())
113116

114117
waitForExpectations(timeout: expectationTimeout)
115118
validateThemeResponse()
116119
XCTAssertEqual(self.blog.blockEditorSettings?.checksum, originalChecksum)
117120
}
118121

119122
private func validateThemeResponse() {
120-
let siteID = blog.dotComID ?? 0
121-
XCTAssertTrue(self.mockRemoteApi.getMethodCalled)
122-
XCTAssertEqual(self.mockRemoteApi.URLStringPassedIn!, "/wp/v2/sites/\(siteID)/themes")
123-
XCTAssertEqual((self.mockRemoteApi.parametersPassedIn as! [String: String])["status"], "active")
124123
XCTAssertGreaterThan(self.blog.blockEditorSettings!.colors!.count, 0)
125124
XCTAssertGreaterThan(self.blog.blockEditorSettings!.gradients!.count, 0)
126125
}
127126

127+
private func stubThemeRequest(response: HTTPStubsResponse) {
128+
let siteID = blog.dotComID ?? 0
129+
stub(
130+
condition:
131+
isMethodGET()
132+
&& { $0.url?.absoluteString.contains("/wp/v2/sites/\(siteID)/themes") == true }
133+
&& { $0.url?.absoluteString.contains("status=active") == true },
134+
response: { _ in response }
135+
)
136+
}
137+
128138
// MARK: Editor Global Styles support
129139
func testFetchBlockEditorSettingsNotThemeJSON() {
130140
let mockedResponse = mockedData(withFilename: blockSettingsNOTThemeJSONResponseFilename)
141+
stubBlockEditorSettingsRequest(response: HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil))
142+
131143
let waitExpectation = expectation(description: "Theme should be successfully fetched")
132144
service.fetchSettings { result in
133145
switch result {
@@ -140,15 +152,15 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
140152
waitExpectation.fulfill()
141153
}
142154

143-
mockRemoteApi.successBlockPassedIn!(mockedResponse, HTTPURLResponse())
144-
145155
waitForExpectations(timeout: expectationTimeout)
146156
validateBlockEditorSettingsResponse(isGlobalStyles: false)
147157
XCTAssertNotNil(self.blog.blockEditorSettings?.checksum)
148158
}
149159

150160
func testFetchBlockEditorSettingsThemeJSON() {
151161
let mockedResponse = mockedData(withFilename: blockSettingsThemeJSONResponseFilename)
162+
stubBlockEditorSettingsRequest(response: HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil))
163+
152164
let waitExpectation = expectation(description: "Theme should be successfully fetched")
153165
service.fetchSettings { result in
154166
switch result {
@@ -161,8 +173,6 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
161173
waitExpectation.fulfill()
162174
}
163175

164-
mockRemoteApi.successBlockPassedIn!(mockedResponse, HTTPURLResponse())
165-
166176
waitForExpectations(timeout: expectationTimeout)
167177
validateBlockEditorSettingsResponse()
168178
XCTAssertNotNil(self.blog.blockEditorSettings?.checksum)
@@ -173,6 +183,8 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
173183
let originalChecksum = blog.blockEditorSettings?.checksum ?? ""
174184

175185
let mockedResponse = mockedData(withFilename: blockSettingsThemeJSONResponseFilename)
186+
stubBlockEditorSettingsRequest(response: HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil))
187+
176188
let waitExpectation = expectation(description: "Theme should be successfully fetched")
177189
service.fetchSettings { result in
178190
switch result {
@@ -185,8 +197,6 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
185197
waitExpectation.fulfill()
186198
}
187199

188-
mockRemoteApi.successBlockPassedIn!(mockedResponse, HTTPURLResponse())
189-
190200
waitForExpectations(timeout: expectationTimeout)
191201
validateBlockEditorSettingsResponse()
192202
XCTAssertNotNil(self.blog.blockEditorSettings?.checksum)
@@ -198,6 +208,8 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
198208
let originalChecksum = blog.blockEditorSettings?.checksum ?? ""
199209

200210
let mockedResponse = mockedData(withFilename: blockSettingsThemeJSONResponseFilename)
211+
stubBlockEditorSettingsRequest(response: HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil))
212+
201213
let waitExpectation = expectation(description: "Theme should be successfully fetched")
202214
service.fetchSettings { result in
203215
switch result {
@@ -210,8 +222,6 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
210222
waitExpectation.fulfill()
211223
}
212224

213-
mockRemoteApi.successBlockPassedIn!(mockedResponse, HTTPURLResponse())
214-
215225
waitForExpectations(timeout: expectationTimeout)
216226
validateBlockEditorSettingsResponse()
217227
XCTAssertNotNil(self.blog.blockEditorSettings?.checksum)
@@ -224,6 +234,8 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
224234
let originalChecksum = blog.blockEditorSettings?.checksum ?? ""
225235

226236
let mockedResponse = mockedData(withFilename: blockSettingsThemeJSONResponseFilename)
237+
stubBlockEditorSettingsRequest(response: HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil))
238+
227239
let waitExpectation = expectation(description: "Theme should be successfully fetched")
228240
service.fetchSettings { result in
229241
switch result {
@@ -236,50 +248,51 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
236248
waitExpectation.fulfill()
237249
}
238250

239-
mockRemoteApi.successBlockPassedIn!(mockedResponse, HTTPURLResponse())
240-
241251
waitForExpectations(timeout: expectationTimeout)
242252
validateBlockEditorSettingsResponse()
243253
XCTAssertNotNil(self.blog.blockEditorSettings?.checksum)
244254
XCTAssertEqual(self.blog.blockEditorSettings?.checksum, originalChecksum)
245255
}
246256

247257
func testFetchBlockEditorSettings_OrgSite_NoPlugin() {
258+
let first = expectation(description: "The app will call the none-experimental path first but fail because of compatibility reasons")
259+
let second = expectation(description: "The app will then retry the wp/v2/themes path")
260+
248261
let mockedResponse = mockedData(withFilename: blockSettingsNOTThemeJSONResponseFilename)
249-
let mockOrgRemoteApi = MockWordPressOrgRestApi()
250-
service = BlockEditorSettingsService(blog: blog, remoteAPI: mockOrgRemoteApi, coreDataStack: contextManager)
262+
stub(condition: isAbsoluteURLString("https://w.org/wp-json/wp-block-editor/v1/settings?context=mobile")) { _ in
263+
first.fulfill()
264+
return HTTPStubsResponse(error: URLError(.networkConnectionLost))
265+
}
266+
stub(condition: isAbsoluteURLString("https://w.org/wp-json/wp/v2/themes?status=active")) { _ in
267+
second.fulfill()
268+
return HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil)
269+
}
270+
271+
let remoteAPI = WordPressOrgRestApi(selfHostedSiteWPJSONURL: URL(string: "https://w.org/wp-json")!, credential: .init(loginURL: URL(string: "https://not-used.org")!, username: "user", password: "pass", adminURL: URL(string: "https://not-used.org")!))
272+
service = BlockEditorSettingsService(blog: blog, remoteAPI: remoteAPI, coreDataStack: contextManager)
251273

252274
let waitExpectation = expectation(description: "Theme should be successfully fetched")
253275
service.fetchSettings { _ in
254276
waitExpectation.fulfill()
255277
}
256278

257-
// The app will call the none-experimental path first but fail because of compatibility reasons
258-
mockOrgRemoteApi.completionPassedIn!(.failure(NSError(domain: "test", code: 404, userInfo: nil)), HTTPURLResponse())
259-
// The app will then retry the wp/v2/themes path.
260-
mockOrgRemoteApi.completionPassedIn!(.success(mockedResponse), HTTPURLResponse())
261-
waitForExpectations(timeout: expectationTimeout)
262-
263-
XCTAssertTrue(mockOrgRemoteApi.getMethodCalled)
264-
XCTAssertEqual(mockOrgRemoteApi.URLStringPassedIn!, "/wp/v2/themes")
265-
XCTAssertEqual((mockOrgRemoteApi.parametersPassedIn as! [String: String])["status"], "active")
279+
wait(for: [first, second, waitExpectation], timeout: 0.3, enforceOrder: true)
266280
}
267281

268282
func testFetchBlockEditorSettings_OrgSite() {
269283
let mockedResponse = mockedData(withFilename: blockSettingsNOTThemeJSONResponseFilename)
270-
let mockOrgRemoteApi = MockWordPressOrgRestApi()
271-
service = BlockEditorSettingsService(blog: blog, remoteAPI: mockOrgRemoteApi, coreDataStack: contextManager)
284+
stub(condition: isAbsoluteURLString("https://w.org/wp-json/wp-block-editor/v1/settings?context=mobile")) { _ in
285+
HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil)
286+
}
287+
288+
let remoteAPI = WordPressOrgRestApi(selfHostedSiteWPJSONURL: URL(string: "https://w.org/wp-json")!, credential: .init(loginURL: URL(string: "https://not-used.org")!, username: "user", password: "pass", adminURL: URL(string: "https://not-used.org")!))
289+
service = BlockEditorSettingsService(blog: blog, remoteAPI: remoteAPI, coreDataStack: contextManager)
272290

273291
let waitExpectation = expectation(description: "Theme should be successfully fetched")
274292
service.fetchSettings { _ in
275293
waitExpectation.fulfill()
276294
}
277-
mockOrgRemoteApi.completionPassedIn!(.success(mockedResponse), HTTPURLResponse())
278295
waitForExpectations(timeout: expectationTimeout)
279-
280-
XCTAssertTrue(mockOrgRemoteApi.getMethodCalled)
281-
XCTAssertEqual(mockOrgRemoteApi.URLStringPassedIn!, "/wp-block-editor/v1/settings")
282-
XCTAssertEqual((mockOrgRemoteApi.parametersPassedIn as! [String: String])["context"], "mobile")
283296
}
284297

285298
func testFetchBlockEditorSettings_Com5_8Site() {
@@ -289,19 +302,17 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
289302
.build()
290303
contextManager.saveContextAndWait(mainContext)
291304

292-
service = BlockEditorSettingsService(blog: blog, remoteAPI: mockRemoteApi, coreDataStack: contextManager)
305+
service = BlockEditorSettingsService(blog: blog, coreDataStack: contextManager)
293306

294307
let mockedResponse = mockedData(withFilename: blockSettingsNOTThemeJSONResponseFilename)
308+
stubBlockEditorSettingsRequest(response: HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil))
309+
295310
let waitExpectation = expectation(description: "Theme should be successfully fetched")
296311
service.fetchSettings { _ in
297312
waitExpectation.fulfill()
298313
}
299-
mockRemoteApi.successBlockPassedIn!(mockedResponse, HTTPURLResponse())
300-
waitForExpectations(timeout: expectationTimeout)
301314

302-
XCTAssertTrue(self.mockRemoteApi.getMethodCalled)
303-
XCTAssertEqual(self.mockRemoteApi.URLStringPassedIn!, "/wp-block-editor/v1/sites/\(blog.dotComID!.intValue)/settings")
304-
XCTAssertEqual((self.mockRemoteApi.parametersPassedIn as! [String: String])["context"], "mobile")
315+
waitForExpectations(timeout: expectationTimeout)
305316
}
306317

307318
func testFetchBlockEditorSettings_Com5_9Site() {
@@ -311,26 +322,19 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
311322
.build()
312323
contextManager.saveContextAndWait(mainContext)
313324

314-
service = BlockEditorSettingsService(blog: blog, remoteAPI: mockRemoteApi, coreDataStack: contextManager)
325+
service = BlockEditorSettingsService(blog: blog, coreDataStack: contextManager)
315326

316327
let mockedResponse = mockedData(withFilename: blockSettingsNOTThemeJSONResponseFilename)
328+
stubBlockEditorSettingsRequest(response: HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil))
317329
let waitExpectation = expectation(description: "Theme should be successfully fetched")
318330
service.fetchSettings { _ in
319331
waitExpectation.fulfill()
320332
}
321-
mockRemoteApi.successBlockPassedIn!(mockedResponse, HTTPURLResponse())
322-
waitForExpectations(timeout: expectationTimeout)
323333

324-
XCTAssertTrue(self.mockRemoteApi.getMethodCalled)
325-
XCTAssertEqual(self.mockRemoteApi.URLStringPassedIn!, "/wp-block-editor/v1/sites/\(blog.dotComID!.intValue)/settings")
326-
XCTAssertEqual((self.mockRemoteApi.parametersPassedIn as! [String: String])["context"], "mobile")
334+
waitForExpectations(timeout: expectationTimeout)
327335
}
328336

329337
private func validateBlockEditorSettingsResponse(isGlobalStyles: Bool = true) {
330-
XCTAssertTrue(self.mockRemoteApi.getMethodCalled)
331-
XCTAssertEqual(self.mockRemoteApi.URLStringPassedIn!, "/wp-block-editor/v1/sites/\(blog.dotComID!.intValue)/settings")
332-
XCTAssertEqual((self.mockRemoteApi.parametersPassedIn as! [String: String])["context"], "mobile")
333-
334338
if isGlobalStyles {
335339
XCTAssertNotNil(self.blog.blockEditorSettings?.rawStyles)
336340
XCTAssertNotNil(self.blog.blockEditorSettings?.rawFeatures)
@@ -355,6 +359,17 @@ class BlockEditorSettingsServiceTests: CoreDataTestCase {
355359
}
356360
XCTAssertGreaterThan(gradients.count, 0)
357361
}
362+
363+
private func stubBlockEditorSettingsRequest(response: HTTPStubsResponse) {
364+
let siteID = blog.dotComID ?? 0
365+
stub(
366+
condition:
367+
isMethodGET()
368+
&& { $0.url?.absoluteString.contains("/wp-block-editor/v1/sites/\(siteID)/settings") == true }
369+
&& { $0.url?.absoluteString.contains("context=mobile") == true },
370+
response: { _ in response }
371+
)
372+
}
358373
}
359374

360375
extension BlockEditorSettingsServiceTests {
@@ -368,10 +383,11 @@ extension BlockEditorSettingsServiceTests {
368383
func setData(withFilename filename: String) {
369384
let waitExpectation = expectation(description: "Theme should be successfully fetched")
370385
let mockedResponse = mockedData(withFilename: filename)
386+
let descriptor = stub(condition: { _ in true }, response: { _ in HTTPStubsResponse(jsonObject: mockedResponse, statusCode: 200, headers: nil) })
371387
service.fetchSettings { _ in
372388
waitExpectation.fulfill()
373389
}
374-
mockRemoteApi.successBlockPassedIn!(mockedResponse, HTTPURLResponse())
375390
waitForExpectations(timeout: expectationTimeout)
391+
HTTPStubs.removeStub(descriptor)
376392
}
377393
}

WordPress/WordPressTest/BlogBuilder.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ final class BlogBuilder {
9797
let account = NSEntityDescription.insertNewObject(forEntityName: WPAccount.entityName(), into: context) as! WPAccount
9898
account.displayName = "displayName"
9999
account.username = username
100+
account.authToken = "authtoken"
100101
blog.account = account
101102

102103
return self

0 commit comments

Comments
 (0)