diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Operations/OperationPreferredDateCalculator.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Operations/OperationPreferredDateCalculator.swift index 954c6b92fd..f5d2063be0 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Operations/OperationPreferredDateCalculator.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Operations/OperationPreferredDateCalculator.swift @@ -18,6 +18,16 @@ import Foundation +protocol DateProtocol { + var now: Date { get } +} + +struct SystemDate: DateProtocol { + var now: Date { + return Date() + } +} + struct OperationPreferredDateCalculator { func dateForScanOperation(currentPreferredRunDate: Date?, @@ -52,7 +62,8 @@ struct OperationPreferredDateCalculator { func dateForOptOutOperation(currentPreferredRunDate: Date?, historyEvents: [HistoryEvent], extractedProfileID: Int64?, - schedulingConfig: DataBrokerScheduleConfig) throws -> Date? { + schedulingConfig: DataBrokerScheduleConfig, + date: DateProtocol = SystemDate()) throws -> Date? { guard let lastEvent = historyEvents.last else { throw DataBrokerProtectionError.cantCalculatePreferredRunDate @@ -63,12 +74,12 @@ struct OperationPreferredDateCalculator { if let extractedProfileID = extractedProfileID, shouldScheduleNewOptOut(events: historyEvents, extractedProfileId: extractedProfileID, schedulingConfig: schedulingConfig) { - return Date() + return date.now } else { return currentPreferredRunDate } case .error: - return Date().addingTimeInterval(schedulingConfig.retryError.hoursToSeconds) + return date.now.addingTimeInterval(schedulingConfig.retryError.hoursToSeconds) case .optOutStarted, .scanStarted, .noMatchFound: return currentPreferredRunDate case .optOutConfirmed, .optOutRequested: @@ -84,6 +95,7 @@ struct OperationPreferredDateCalculator { return false } - return lastRemovalEvent.date.addingTimeInterval(schedulingConfig.maintenanceScan.hoursToSeconds) < Date() + let lastRemovalEventDate = lastRemovalEvent.date.addingTimeInterval(schedulingConfig.maintenanceScan.hoursToSeconds) + return lastRemovalEventDate < Date() } } diff --git a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/OperationPreferredDateCalculatorTests.swift b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/OperationPreferredDateCalculatorTests.swift index a3cbcf36f3..959f9555b4 100644 --- a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/OperationPreferredDateCalculatorTests.swift +++ b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/OperationPreferredDateCalculatorTests.swift @@ -273,9 +273,9 @@ final class OperationPreferredDateCalculatorTests: XCTestCase { } func testMatchFoundWithExpiredProfile_thenOptOutDateIsNow() throws { - let expiredDate = Date().addingTimeInterval(-schedulingConfig.maintenanceScan.hoursToSeconds) + let expiredDate = Date(timeIntervalSince1970: 0).addingTimeInterval(-schedulingConfig.maintenanceScan.hoursToSeconds * 2) - let expectedOptOutDate = Date() + let expectedOptOutDate = Date(timeIntervalSince1970: 0) let historyEvents = [ HistoryEvent(extractedProfileId: 1, @@ -293,7 +293,8 @@ final class OperationPreferredDateCalculatorTests: XCTestCase { let actualOptOutDate = try calculator.dateForOptOutOperation(currentPreferredRunDate: nil, historyEvents: historyEvents, extractedProfileID: 1, - schedulingConfig: schedulingConfig) + schedulingConfig: schedulingConfig, + date: MockDate()) XCTAssertTrue(areDatesEqualIgnoringSeconds(date1: expectedOptOutDate, date2: actualOptOutDate)) } @@ -476,10 +477,10 @@ final class OperationPreferredDateCalculatorTests: XCTestCase { /* If the time elapsed since the last profile removal exceeds the current date plus maintenance period (expired), we should proceed with scheduling a new opt-out request as the broker has failed to honor the previous one. */ - func skipMatchFoundWithExpiredProfileWithRecentDate_thenOptOutDateDoesNotChange() throws { - let expiredDate = Date().addingTimeInterval(-schedulingConfig.maintenanceScan.hoursToSeconds) + func testMatchFoundWithExpiredProfileWithRecentDate_thenOptOutDateDoesNotChange() throws { + let expiredDate = Date(timeIntervalSince1970: 0).addingTimeInterval(-schedulingConfig.maintenanceScan.hoursToSeconds) - let expectedOptOutDate = Date() + let expectedOptOutDate = Date(timeIntervalSince1970: 0) let historyEvents = [ HistoryEvent(extractedProfileId: 1, @@ -491,13 +492,15 @@ final class OperationPreferredDateCalculatorTests: XCTestCase { brokerId: 1, profileQueryId: 1, type: .matchesFound(count: 1))] + let dateProtocol = MockDate() let calculator = OperationPreferredDateCalculator() let actualOptOutDate = try calculator.dateForOptOutOperation(currentPreferredRunDate: nil, historyEvents: historyEvents, extractedProfileID: 1, - schedulingConfig: schedulingConfig) + schedulingConfig: schedulingConfig, + date: dateProtocol) XCTAssertTrue(areDatesEqualIgnoringSeconds(date1: expectedOptOutDate, date2: actualOptOutDate)) } @@ -601,3 +604,9 @@ final class OperationPreferredDateCalculatorTests: XCTestCase { XCTAssertTrue(areDatesEqualIgnoringSeconds(date1: expectedOptOutDate, date2: actualOptOutDate)) } } + +struct MockDate: DateProtocol { + var now: Date { + return Date(timeIntervalSince1970: 0) + } +}