@@ -33,7 +33,7 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
3333
3434 // Then - should not flag site as unsupported even after more failures
3535 simulateFailureCount ( 5 , for: siteID) // Would normally reach threshold
36- XCTAssertFalse ( userDefaults. applicationPasswordUnsupportedList. contains ( siteID) )
36+ XCTAssertFalse ( userDefaults. applicationPasswordUnsupportedList. keys . contains ( String ( siteID) ) )
3737 }
3838
3939 func test_shouldRetryJetpackRequest_returns_false_for_nil_credentials( ) {
@@ -122,20 +122,21 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
122122 errorHandler. flagSiteAsUnsupported ( for: siteID)
123123
124124 // Then
125- XCTAssertEqual ( userDefaults. applicationPasswordUnsupportedList, [ siteID] )
125+ XCTAssertTrue ( userDefaults. applicationPasswordUnsupportedList. keys . contains ( String ( siteID) ) )
126126 }
127127
128128 func test_flagSiteAsUnsupported_appends_to_existing_list( ) {
129129 // Given
130130 let existingSiteID : Int64 = 789
131131 let newSiteID : Int64 = 456
132- userDefaults. applicationPasswordUnsupportedList = [ existingSiteID]
132+ userDefaults. applicationPasswordUnsupportedList = [ String ( existingSiteID) : Date ( ) ]
133133
134134 // When
135135 errorHandler. flagSiteAsUnsupported ( for: newSiteID)
136136
137137 // Then
138- XCTAssertEqual ( userDefaults. applicationPasswordUnsupportedList, [ existingSiteID, newSiteID] )
138+ XCTAssertTrue ( userDefaults. applicationPasswordUnsupportedList. keys. contains ( String ( existingSiteID) ) )
139+ XCTAssertTrue ( userDefaults. applicationPasswordUnsupportedList. keys. contains ( String ( newSiteID) ) )
139140 }
140141
141142 // MARK: - Thread Safety Tests
@@ -273,6 +274,114 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
273274 wait ( for: [ expectation] , timeout: 3.0 )
274275 }
275276
277+ // MARK: - siteFlaggedAsUnsupported Tests
278+
279+ func test_siteFlaggedAsUnsupported_returns_false_when_site_not_in_list( ) {
280+ // Given
281+ let siteID : Int64 = 123
282+ let unsupportedList : [ String : Date ] = [ : ]
283+
284+ // When
285+ let isFlagged = errorHandler. siteFlaggedAsUnsupported ( siteID: siteID, unsupportedList: unsupportedList)
286+
287+ // Then
288+ XCTAssertFalse ( isFlagged)
289+ }
290+
291+ func test_siteFlaggedAsUnsupported_returns_false_when_timestamp_string_invalid( ) {
292+ // Given
293+ let siteID : Int64 = 123
294+ let unsupportedList : [ String : Date ] = [ String ( siteID) : Date ( timeIntervalSince1970: 0 ) ]
295+
296+ // When
297+ let isFlagged = errorHandler. siteFlaggedAsUnsupported ( siteID: siteID, unsupportedList: unsupportedList)
298+
299+ // Then
300+ XCTAssertFalse ( isFlagged)
301+ }
302+
303+ func test_siteFlaggedAsUnsupported_returns_true_when_flag_is_recent( ) {
304+ // Given
305+ let siteID : Int64 = 123
306+ let recentDate = Date ( timeIntervalSince1970: Date ( ) . timeIntervalSince1970 - ( 60 * 60 ) ) // 1 hour ago
307+ let unsupportedList : [ String : Date ] = [ String ( siteID) : recentDate]
308+
309+ // When
310+ let isFlagged = errorHandler. siteFlaggedAsUnsupported ( siteID: siteID, unsupportedList: unsupportedList)
311+
312+ // Then
313+ XCTAssertTrue ( isFlagged)
314+ }
315+
316+ func test_siteFlaggedAsUnsupported_returns_false_and_clears_flag_when_expired( ) {
317+ // Given
318+ let siteID : Int64 = 123
319+ let expiredDate = Date ( timeIntervalSince1970: Date ( ) . timeIntervalSince1970 - ( 60 * 60 * 24 * 15 ) ) // 15 days ago (expired)
320+ userDefaults. applicationPasswordUnsupportedList = [ String ( siteID) : expiredDate]
321+
322+ // When
323+ let isFlagged = errorHandler. siteFlaggedAsUnsupported ( siteID: siteID, unsupportedList: userDefaults. applicationPasswordUnsupportedList)
324+
325+ // Then
326+ XCTAssertFalse ( isFlagged)
327+ // Verify the flag was cleared from UserDefaults
328+ XCTAssertFalse ( userDefaults. applicationPasswordUnsupportedList. keys. contains ( String ( siteID) ) )
329+ }
330+
331+ func test_siteFlaggedAsUnsupported_returns_true_for_flag_at_boundary_time( ) {
332+ // Given
333+ let siteID : Int64 = 123
334+ let boundaryDate = Date ( timeIntervalSince1970: Date ( ) . timeIntervalSince1970 - ( 60 * 60 * 24 * 7 - 1 ) ) // Just under 7 days ago
335+ let unsupportedList : [ String : Date ] = [ String ( siteID) : boundaryDate]
336+
337+ // When
338+ let isFlagged = errorHandler. siteFlaggedAsUnsupported ( siteID: siteID, unsupportedList: unsupportedList)
339+
340+ // Then
341+ XCTAssertTrue ( isFlagged)
342+ }
343+
344+ func test_siteFlaggedAsUnsupported_returns_false_for_flag_just_over_boundary( ) {
345+ // Given
346+ let siteID : Int64 = 123
347+ let expiredDate = Date ( timeIntervalSince1970: Date ( ) . timeIntervalSince1970 - ( 60 * 60 * 24 * 14 + 1 ) ) // Just over 7 days ago
348+ userDefaults. applicationPasswordUnsupportedList = [ String ( siteID) : expiredDate]
349+
350+ // When
351+ let isFlagged = errorHandler. siteFlaggedAsUnsupported ( siteID: siteID, unsupportedList: userDefaults. applicationPasswordUnsupportedList)
352+
353+ // Then
354+ XCTAssertFalse ( isFlagged)
355+ // Verify the flag was cleared from UserDefaults
356+ XCTAssertFalse ( userDefaults. applicationPasswordUnsupportedList. keys. contains ( String ( siteID) ) )
357+ }
358+
359+ func test_siteFlaggedAsUnsupported_handles_multiple_sites_correctly( ) {
360+ // Given
361+ let siteID1 : Int64 = 123
362+ let siteID2 : Int64 = 456
363+ let siteID3 : Int64 = 789
364+ let recentDate = Date ( timeIntervalSince1970: Date ( ) . timeIntervalSince1970 - ( 60 * 60 ) ) // 1 hour ago
365+ let expiredDate = Date ( timeIntervalSince1970: Date ( ) . timeIntervalSince1970 - ( 60 * 60 * 24 * 15 ) ) // 15 days ago
366+
367+ userDefaults. applicationPasswordUnsupportedList = [
368+ String ( siteID1) : recentDate,
369+ String ( siteID2) : expiredDate,
370+ String ( siteID3) : recentDate
371+ ]
372+
373+ // When & Then
374+ let list = userDefaults. applicationPasswordUnsupportedList
375+ XCTAssertTrue ( errorHandler. siteFlaggedAsUnsupported ( siteID: siteID1, unsupportedList: list) )
376+ XCTAssertFalse ( errorHandler. siteFlaggedAsUnsupported ( siteID: siteID2, unsupportedList: userDefaults. applicationPasswordUnsupportedList) )
377+ XCTAssertTrue ( errorHandler. siteFlaggedAsUnsupported ( siteID: siteID3, unsupportedList: userDefaults. applicationPasswordUnsupportedList) )
378+
379+ // Verify expired flag was cleared but others remain
380+ XCTAssertTrue ( userDefaults. applicationPasswordUnsupportedList. keys. contains ( String ( siteID1) ) )
381+ XCTAssertFalse ( userDefaults. applicationPasswordUnsupportedList. keys. contains ( String ( siteID2) ) )
382+ XCTAssertTrue ( userDefaults. applicationPasswordUnsupportedList. keys. contains ( String ( siteID3) ) )
383+ }
384+
276385 // MARK: - Integration Tests
277386
278387 func test_handleFailureForDirectRequestIfNeeded_calls_correct_callbacks( ) {
@@ -352,7 +461,7 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
352461 )
353462
354463 // Then
355- XCTAssertEqual ( userDefaults. applicationPasswordUnsupportedList, [ siteID] )
464+ XCTAssertTrue ( userDefaults. applicationPasswordUnsupportedList. keys . contains ( String ( siteID) ) )
356465 }
357466
358467 func test_flagSiteAsUnsupportedForAppPasswordIfNeeded_handles_disabled_error_codes( ) {
@@ -383,7 +492,7 @@ final class AlamofireNetworkErrorHandlerTests: XCTestCase {
383492 )
384493
385494 // Then
386- XCTAssertEqual ( userDefaults. applicationPasswordUnsupportedList, [ siteID] )
495+ XCTAssertTrue ( userDefaults. applicationPasswordUnsupportedList. keys . contains ( String ( siteID) ) )
387496 }
388497}
389498
0 commit comments