Skip to content

Commit 11a7eff

Browse files
committed
Evict WordPress clients during account and site removal
1 parent bb6d18d commit 11a7eff

5 files changed

Lines changed: 107 additions & 0 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import OHHTTPStubs
2+
import OHHTTPStubsSwift
3+
import XCTest
4+
5+
@testable import WordPress
6+
@testable import WordPressData
7+
8+
final class WordPressClientFactoryTests: CoreDataTestCase {
9+
override func setUp() {
10+
super.setUp()
11+
contextManager.useAsSharedInstance(untilTestFinished: self)
12+
WordPressClientFactory.shared.reset()
13+
HTTPStubs.removeAllStubs()
14+
stub(condition: { _ in true }) { _ in
15+
HTTPStubsResponse(
16+
jsonObject: [:],
17+
statusCode: 200,
18+
headers: ["Content-Type": "application/json"]
19+
)
20+
}
21+
}
22+
23+
override func tearDown() {
24+
WordPressClientFactory.shared.reset()
25+
HTTPStubs.removeAllStubs()
26+
super.tearDown()
27+
}
28+
29+
func testEvictInstanceIsIdempotentAndCreatesANewClient() throws {
30+
let site = try makeSite(dotComID: 123)
31+
let otherSite = try makeSite(dotComID: 456)
32+
let original = WordPressClientFactory.shared.instance(for: site)
33+
let otherOriginal = WordPressClientFactory.shared.instance(for: otherSite)
34+
35+
WordPressClientFactory.shared.evictInstance(for: site.blogId)
36+
WordPressClientFactory.shared.evictInstance(for: site.blogId)
37+
38+
let replacement = WordPressClientFactory.shared.instance(for: site)
39+
XCTAssertFalse(original === replacement)
40+
XCTAssertTrue(replacement === WordPressClientFactory.shared.instance(for: site))
41+
XCTAssertTrue(otherOriginal === WordPressClientFactory.shared.instance(for: otherSite))
42+
}
43+
44+
func testResetCreatesANewClient() throws {
45+
let site = try makeSite(dotComID: 123)
46+
let original = WordPressClientFactory.shared.instance(for: site)
47+
48+
WordPressClientFactory.shared.reset()
49+
50+
XCTAssertFalse(original === WordPressClientFactory.shared.instance(for: site))
51+
}
52+
53+
func testRemovingDefaultAccountEvictsBlogClient() throws {
54+
let blog = makeBlog(dotComID: 123)
55+
try mainContext.save()
56+
let site = try WordPressSite(blog: blog)
57+
let original = WordPressClientFactory.shared.instance(for: site)
58+
let service = AccountService(coreDataStack: contextManager)
59+
service.setDefaultWordPressComAccount(try XCTUnwrap(blog.account))
60+
61+
service.removeDefaultWordPressComAccount()
62+
63+
XCTAssertFalse(original === WordPressClientFactory.shared.instance(for: site))
64+
}
65+
66+
func testRemovingBlogEvictsClient() throws {
67+
let blog = makeBlog(dotComID: 123)
68+
try mainContext.save()
69+
let site = try WordPressSite(blog: blog)
70+
let original = WordPressClientFactory.shared.instance(for: site)
71+
72+
BlogService(coreDataStack: contextManager).remove(blog)
73+
74+
XCTAssertFalse(original === WordPressClientFactory.shared.instance(for: site))
75+
}
76+
77+
private func makeSite(dotComID: Int) throws -> WordPressSite {
78+
try WordPressSite(blog: makeBlog(dotComID: dotComID))
79+
}
80+
81+
private func makeBlog(dotComID: Int) -> Blog {
82+
let blog = BlogBuilder(mainContext, dotComID: NSNumber(value: dotComID))
83+
.with(url: "https://example.wordpress.com")
84+
.isHostedAtWPcom()
85+
.withAnAccount(username: "test-user", authToken: "test-token")
86+
.build()
87+
blog.account?.uuid = UUID().uuidString
88+
return blog
89+
}
90+
}

‎WordPress/Classes/Networking/WordPressClient.swift‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ public final class WordPressClientFactory: Sendable {
2525
}
2626
}
2727

28+
public func evictInstance(for blogID: TaggedManagedObjectID<Blog>) {
29+
instances.withLock { instances in
30+
instances.removeValue(forKey: blogID)
31+
}
32+
}
33+
2834
public func reset() {
2935
instances.withLock { dict in
3036
dict.removeAll()

‎WordPress/Classes/Services/AccountService+Swift.swift‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ extension AccountService {
4949
return
5050
}
5151

52+
account.blogs?
53+
.forEach {
54+
WordPressClientFactory.shared.evictInstance(for: TaggedManagedObjectID($0))
55+
}
56+
5257
let objectID = TaggedManagedObjectID(account)
5358
coreDataStack.performAndSave { context in
5459
do {

‎WordPress/Classes/Services/BlogService+Swift.swift‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import WordPressCore
66
import WordPressAPI
77

88
extension BlogService {
9+
@objc(evictWordPressClientForBlog:)
10+
public func evictWordPressClient(for blog: Blog) {
11+
WordPressClientFactory.shared.evictInstance(for: TaggedManagedObjectID(blog))
12+
}
13+
914
@objc public func unscheduleBloggingReminders(for blog: Blog) {
1015
do {
1116
let scheduler = try ReminderScheduleCoordinator()

‎WordPress/Classes/Services/BlogService.m‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ - (void)removeBlog:(Blog *)blog
344344
DDLogInfo(@"<Blog:%@> remove", blog.displayURL);
345345
[blog.xmlrpcApi invalidateAndCancelTasks];
346346
[self unscheduleBloggingRemindersFor:blog];
347+
[self evictWordPressClientForBlog:blog];
347348

348349
WPAccount *account = blog.account;
349350

0 commit comments

Comments
 (0)