Skip to content

Commit fc11138

Browse files
committed
Make user defaults update sync to avoid race condition and remove unnecessary wait in tests
1 parent e89461e commit fc11138

File tree

2 files changed

+2
-21
lines changed

2 files changed

+2
-21
lines changed

Modules/Sources/NetworkingCore/Network/AlamofireNetworkErrorHandler.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ final class AlamofireNetworkErrorHandler {
167167
// Use dedicated serial queue for UserDefaults operations to:
168168
// 1. Prevent race conditions where concurrent writes overwrite each other
169169
// 2. Avoid deadlock by not using the main queue that KVO observers may need
170-
userDefaultsQueue.async { [weak self] in
170+
userDefaultsQueue.sync { [weak self] in
171171
guard let self else { return }
172172
var currentList = userDefaults.applicationPasswordUnsupportedList
173173
currentList[String(siteID)] = Date()
@@ -242,7 +242,7 @@ private extension AlamofireNetworkErrorHandler {
242242
// Use dedicated serial queue for UserDefaults operations to:
243243
// 1. Prevent race conditions where concurrent writes overwrite each other
244244
// 2. Avoid deadlock by not using the main queue that KVO observers may need
245-
userDefaultsQueue.async { [weak self] in
245+
userDefaultsQueue.sync { [weak self] in
246246
guard let self else { return }
247247
let currentList = userDefaults.applicationPasswordUnsupportedList
248248
let filteredList = currentList.filter { flag in

Modules/Tests/NetworkingTests/Network/AlamofireNetworkErrorHandlerTests.swift

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
126126

127127
// When
128128
errorHandler.flagSiteAsUnsupported(for: siteID, flow: .apiRequest, cause: .majorError, error: NetworkError.notFound(response: nil))
129-
waitForUserDefaultsOperations()
130129

131130
// Then
132131
XCTAssertTrue(userDefaults.applicationPasswordUnsupportedList.keys.contains(String(siteID)))
@@ -140,7 +139,6 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
140139

141140
// When
142141
errorHandler.flagSiteAsUnsupported(for: newSiteID, flow: .apiRequest, cause: .majorError, error: NetworkError.notFound(response: nil))
143-
waitForUserDefaultsOperations()
144142

145143
// Then
146144
XCTAssertTrue(userDefaults.applicationPasswordUnsupportedList.keys.contains(String(existingSiteID)))
@@ -269,7 +267,6 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
269267

270268
// Then - no crashes should occur and all sites should be flagged
271269
wait(for: [expectation], timeout: 3.0)
272-
waitForUserDefaultsOperations()
273270

274271
// Verify all sites were added (though order may vary due to concurrency)
275272
let unsupportedList = userDefaults.applicationPasswordUnsupportedList
@@ -390,7 +387,6 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
390387

391388
// When
392389
let isFlagged = errorHandler.siteFlaggedAsUnsupported(siteID: siteID, unsupportedList: userDefaults.applicationPasswordUnsupportedList)
393-
waitForUserDefaultsOperations()
394390

395391
// Then
396392
XCTAssertFalse(isFlagged)
@@ -419,7 +415,6 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
419415

420416
// When
421417
let isFlagged = errorHandler.siteFlaggedAsUnsupported(siteID: siteID, unsupportedList: userDefaults.applicationPasswordUnsupportedList)
422-
waitForUserDefaultsOperations()
423418

424419
// Then
425420
XCTAssertFalse(isFlagged)
@@ -446,7 +441,6 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
446441
XCTAssertTrue(errorHandler.siteFlaggedAsUnsupported(siteID: siteID1, unsupportedList: list))
447442
XCTAssertFalse(errorHandler.siteFlaggedAsUnsupported(siteID: siteID2, unsupportedList: userDefaults.applicationPasswordUnsupportedList))
448443
XCTAssertTrue(errorHandler.siteFlaggedAsUnsupported(siteID: siteID3, unsupportedList: userDefaults.applicationPasswordUnsupportedList))
449-
waitForUserDefaultsOperations()
450444

451445
// Verify expired flag was cleared but others remain
452446
XCTAssertTrue(userDefaults.applicationPasswordUnsupportedList.keys.contains(String(siteID1)))
@@ -531,7 +525,6 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
531525
originalRequest: jetpackRequest,
532526
failure: nil
533527
)
534-
waitForUserDefaultsOperations()
535528

536529
// Then
537530
XCTAssertTrue(userDefaults.applicationPasswordUnsupportedList.keys.contains(String(siteID)))
@@ -563,7 +556,6 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
563556
originalRequest: jetpackRequest,
564557
failure: nil
565558
)
566-
waitForUserDefaultsOperations()
567559

568560
// Then
569561
XCTAssertTrue(userDefaults.applicationPasswordUnsupportedList.keys.contains(String(siteID)))
@@ -721,17 +713,6 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
721713

722714
// MARK: - Helper Methods
723715
private extension AlamofireNetworkErrorHandlerTests {
724-
/// Waits briefly for async UserDefaults operations to complete
725-
/// Since flagSiteAsUnsupported and clearUnsupportedFlag use userDefaultsQueue.async,
726-
/// tests need to wait for those operations to finish before checking UserDefaults state
727-
func waitForUserDefaultsOperations() {
728-
let expectation = XCTestExpectation(description: "UserDefaults operations complete")
729-
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
730-
expectation.fulfill()
731-
}
732-
wait(for: [expectation], timeout: 1.0)
733-
}
734-
735716
func createWPComCredentials() -> Credentials {
736717
return Credentials.wpcom(username: "test", authToken: "token", siteAddress: "https://example.com")
737718
}

0 commit comments

Comments
 (0)