Skip to content

Commit f778b38

Browse files
Merge pull request #430 from checkout/hotfix/PIMOB-2058-card-validator-improvement
Improve CardValidator test cases
2 parents 7209747 + 15406c7 commit f778b38

File tree

5 files changed

+44
-22
lines changed

5 files changed

+44
-22
lines changed

Checkout/Checkout/Source/Extension/Foundation+Extensions.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77

88
import Foundation
99

10-
extension Calendar: CalendarProtocol { }
10+
extension Calendar: CalendarProtocol {
11+
func current() -> Date {
12+
Date()
13+
}
14+
}
15+
1116
extension JSONEncoder: Encoding { }
1217
extension JSONDecoder: Decoding { }

Checkout/Checkout/Source/Protocols/CalendarProtocol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import Foundation
99

10-
protocol CalendarProtocol {
10+
protocol CalendarProtocol: DateProviding {
1111
func date(from components: DateComponents) -> Date?
1212
func date(byAdding component: Calendar.Component, value: Int, to date: Date, wrappingComponents: Bool) -> Date?
1313
func component(_ component: Calendar.Component, from date: Date) -> Int

Checkout/Checkout/Source/Validation/Validators/CardValidator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public class CardValidator: CardValidating {
224224
return .failure(.invalidMonth)
225225
}
226226

227-
let currentDate = Date()
227+
let currentDate = calendar.current()
228228
// using UTC-12 as this is the latest timezone where a card could be valid
229229
let cardExpiryComponents = DateComponents(
230230
timeZone: .utcMinus12,

CheckoutTests/Stubs/StubCalendar.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,23 @@ import Foundation
99
@testable import Checkout
1010

1111
final class StubCalendar: CalendarProtocol {
12+
var currentDateToReturn: Date?
13+
14+
func current() -> Date {
15+
currentDateToReturn ?? Date()
16+
}
17+
18+
var forceToReturnNilComponents: Bool = false
1219
var dateFromComponentsToReturn: Date?
1320
private(set) var dateFromComponentsCalledWith: DateComponents?
1421

1522
func date(from components: DateComponents) -> Date? {
1623
dateFromComponentsCalledWith = components
17-
return dateFromComponentsToReturn
24+
25+
if forceToReturnNilComponents {
26+
return nil
27+
}
28+
return dateFromComponentsToReturn ?? Calendar(identifier: .gregorian).date(from: components)
1829
}
1930

2031
var dateByAddingOverride = true

CheckoutTests/Validation/CardValidatorTests.swift

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -164,33 +164,37 @@ extension CardValidatorTests {
164164
expiryYear: "2021",
165165
expectedResult: .success(ExpiryDate(month: 11, year: 2021)))
166166

167-
let dateComponents2040 = stubCalendar.dateFromComponentsCalledWith
168-
XCTAssertEqual(dateComponents2040?.month, 11)
169-
XCTAssertEqual(dateComponents2040?.year, 2021)
167+
let components = stubCalendar.dateFromComponentsCalledWith
168+
XCTAssertEqual(components?.month, 11)
169+
XCTAssertEqual(components?.year, 2021)
170+
}
170171

171-
test_validate(
172-
expiryMonth: "11",
173-
expiryYear: "2021",
174-
expectedResult: .success(ExpiryDate(month: 11, year: 2021)))
172+
func test_validate_expiryMonthYearString_providedMontInThePast_SameYear_returnsCorrectError() {
173+
let formatter = DateFormatter()
174+
formatter.dateFormat = "yyyy/MM/dd HH:mm"
175175

176-
let dateComponents40 = stubCalendar.dateFromComponentsCalledWith
177-
XCTAssertEqual(dateComponents40?.month, 11)
178-
XCTAssertEqual(dateComponents40?.year, 2021)
176+
stubCalendar.currentDateToReturn = formatter.date(from: "2023/06/20 00:00")
177+
178+
test_validate(
179+
expiryMonth: "05",
180+
expiryYear: "2023",
181+
expectedResult: .failure(.inThePast))
179182
}
180183

181184
func test_validate_expiryMonthYearString_providedDateInThePast_returnsCorrectError() {
182185
let formatter = DateFormatter()
183186
formatter.dateFormat = "yyyy/MM/dd HH:mm"
184187

185-
stubCalendar.dateFromComponentsToReturn = formatter.date(from: "2020/10/01 00:00")
188+
stubCalendar.currentDateToReturn = formatter.date(from: "2023/05/25 00:00")
186189

187190
test_validate(
188191
expiryMonth: "11",
189-
expiryYear: "2040",
192+
expiryYear: "2022",
190193
expectedResult: .failure(.inThePast))
191194
}
192195

193196
func test_validate_expiryMonthYearString_calendarDateReturnsNil_returnsCorrectError() {
197+
stubCalendar.forceToReturnNilComponents = true
194198
stubCalendar.dateFromComponentsToReturn = nil
195199
test_validate(
196200
expiryMonth: "11",
@@ -247,7 +251,7 @@ extension CardValidatorTests {
247251
let formatter = DateFormatter()
248252
formatter.dateFormat = "yyyy/MM/dd HH:mm"
249253

250-
stubCalendar.dateFromComponentsToReturn = formatter.date(from: "2099/10/01 00:00")
254+
stubCalendar.currentDateToReturn = formatter.date(from: "2039/10/01 00:00")
251255

252256
test_validate(
253257
expiryMonth: 11,
@@ -273,7 +277,9 @@ extension CardValidatorTests {
273277
private func test_validate(
274278
expiryMonth: String,
275279
expiryYear: String,
276-
expectedResult: Result<ExpiryDate, ValidationError.ExpiryDate>
280+
expectedResult: Result<ExpiryDate, ValidationError.ExpiryDate>,
281+
file: StaticString = #file,
282+
line: UInt = #line
277283
) {
278284
let result = subject.validate(
279285
expiryMonth: expiryMonth,
@@ -284,18 +290,18 @@ extension CardValidatorTests {
284290

285291
switch expectedResult {
286292
case .success(let expectedExpiryDate):
287-
XCTAssertEqual(expiryDate, expectedExpiryDate)
293+
XCTAssertEqual(expiryDate, expectedExpiryDate, file: file, line: line)
288294
case .failure(let error):
289-
XCTFail(error.localizedDescription)
295+
XCTFail(error.localizedDescription, file: file, line: line)
290296
}
291297

292298
case .failure(let error):
293299

294300
switch expectedResult {
295301
case .success(let expiryDate):
296-
XCTFail("Unexpected successful expiry date validation: \(expiryDate).")
302+
XCTFail("Unexpected successful expiry date validation: \(expiryDate).", file: file, line: line)
297303
case .failure(let expectedError):
298-
XCTAssertEqual(expectedError, error)
304+
XCTAssertEqual(expectedError, error, file: file, line: line)
299305
}
300306
}
301307
}

0 commit comments

Comments
 (0)