Skip to content

Commit 94f545e

Browse files
authored
Tests | CardScannerViewController (#2059)
# Summary Unit tests for: - [x] CardScannerViewController # Ticket <ticket> COIOS-826 </ticket>
2 parents a5c4ad9 + 61974fa commit 94f545e

3 files changed

Lines changed: 182 additions & 0 deletions

File tree

Adyen.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,8 @@
531531
C930FB6E269D79E0006A26D2 /* AffirmDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = C930FB6D269D79E0006A26D2 /* AffirmDetails.swift */; };
532532
C933801E276A06E1005B66CD /* BACSDirectDebitComponentTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C933801D276A06E1005B66CD /* BACSDirectDebitComponentTracker.swift */; };
533533
C9338020276A09E7005B66CD /* BACSDirectDebitComponentTrackerProtocolMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C933801F276A09E7005B66CD /* BACSDirectDebitComponentTrackerProtocolMock.swift */; };
534+
C93844732D79DF3B00B1E747 /* CardScannerViewModelMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C93844722D79DF3B00B1E747 /* CardScannerViewModelMock.swift */; };
535+
C93844752D7B1C4100B1E747 /* CardScannerViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C93844742D7B1C4100B1E747 /* CardScannerViewControllerTests.swift */; };
534536
C93B01B72760B03400D311A1 /* BACSConfirmationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C93B01B62760B03400D311A1 /* BACSConfirmationViewController.swift */; };
535537
C93B01B92760B06300D311A1 /* BACSConfirmationPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C93B01B82760B06300D311A1 /* BACSConfirmationPresenter.swift */; };
536538
C9454C37276A340B0086C218 /* BACSDirectDebitPresentationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9454C35276A33A00086C218 /* BACSDirectDebitPresentationDelegate.swift */; };
@@ -1904,6 +1906,8 @@
19041906
C930FB6D269D79E0006A26D2 /* AffirmDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AffirmDetails.swift; sourceTree = "<group>"; };
19051907
C933801D276A06E1005B66CD /* BACSDirectDebitComponentTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BACSDirectDebitComponentTracker.swift; sourceTree = "<group>"; };
19061908
C933801F276A09E7005B66CD /* BACSDirectDebitComponentTrackerProtocolMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BACSDirectDebitComponentTrackerProtocolMock.swift; sourceTree = "<group>"; };
1909+
C93844722D79DF3B00B1E747 /* CardScannerViewModelMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardScannerViewModelMock.swift; sourceTree = "<group>"; };
1910+
C93844742D7B1C4100B1E747 /* CardScannerViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardScannerViewControllerTests.swift; sourceTree = "<group>"; };
19071911
C93B01B62760B03400D311A1 /* BACSConfirmationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BACSConfirmationViewController.swift; sourceTree = "<group>"; };
19081912
C93B01B82760B06300D311A1 /* BACSConfirmationPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BACSConfirmationPresenter.swift; sourceTree = "<group>"; };
19091913
C9454C35276A33A00086C218 /* BACSDirectDebitPresentationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BACSDirectDebitPresentationDelegate.swift; sourceTree = "<group>"; };
@@ -3493,6 +3497,7 @@
34933497
children = (
34943498
C91BF2572D771667001F19DE /* CardImageParsingMock.swift */,
34953499
C91BF2592D7716D4001F19DE /* CaptureSessionManagingMock.swift */,
3500+
C93844722D79DF3B00B1E747 /* CardScannerViewModelMock.swift */,
34963501
);
34973502
path = Mocks;
34983503
sourceTree = "<group>";
@@ -3600,6 +3605,7 @@
36003605
C91BF2562D7715D8001F19DE /* Mocks */,
36013606
C96844922D771328001DB7F1 /* CardScannerViewModelTests.swift */,
36023607
C91BF25B2D772233001F19DE /* Assets.xcassets */,
3608+
C93844742D7B1C4100B1E747 /* CardScannerViewControllerTests.swift */,
36033609
);
36043610
path = AdyenCardScannerTests;
36053611
sourceTree = "<group>";
@@ -7082,6 +7088,8 @@
70827088
buildActionMask = 2147483647;
70837089
files = (
70847090
C91BF2582D771667001F19DE /* CardImageParsingMock.swift in Sources */,
7091+
C93844752D7B1C4100B1E747 /* CardScannerViewControllerTests.swift in Sources */,
7092+
C93844732D79DF3B00B1E747 /* CardScannerViewModelMock.swift in Sources */,
70857093
C91BF25A2D7716D4001F19DE /* CaptureSessionManagingMock.swift in Sources */,
70867094
C96844932D771328001DB7F1 /* CardScannerViewModelTests.swift in Sources */,
70877095
);
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//
2+
// Copyright (c) 2025 Adyen N.V.
3+
//
4+
// This file is open source and available under the MIT license. See the LICENSE file for more info.
5+
//
6+
7+
@testable import AdyenCardScanner
8+
import XCTest
9+
10+
final class CardScannerViewControllerTests: XCTestCase {
11+
12+
var viewModel: CardScannerViewModelMock!
13+
var sut: CardScannerViewController!
14+
15+
override func tearDownWithError() throws {
16+
viewModel = nil
17+
sut = nil
18+
try super.tearDownWithError()
19+
}
20+
21+
func testViewDidLoadShouldCallViewModelConfigureSession() throws {
22+
// Given
23+
viewModel = CardScannerViewModelMock()
24+
sut = CardScannerViewController(viewModel: viewModel)
25+
26+
// When
27+
sut.loadViewIfNeeded()
28+
29+
// Then
30+
XCTAssertEqual(viewModel.configureSessionCallsCount, 1)
31+
}
32+
33+
func testViewWillAppearShouldStartCaptureSession() throws {
34+
// Given
35+
viewModel = CardScannerViewModelMock()
36+
sut = CardScannerViewController(viewModel: viewModel)
37+
38+
// When
39+
sut.viewWillAppear(true)
40+
41+
// Then
42+
XCTAssertEqual(viewModel.startCaptureSessionCallsCount, 1)
43+
}
44+
45+
func testViewWillAppearShouldStopCaptureSession() throws {
46+
// Given
47+
viewModel = CardScannerViewModelMock()
48+
sut = CardScannerViewController(viewModel: viewModel)
49+
50+
// When
51+
sut.viewWillDisappear(true)
52+
53+
// Then
54+
XCTAssertEqual(viewModel.stopCaptureSessionCallsCount, 1)
55+
}
56+
57+
func testViewDidLayoutSubviewsShouldUpdateVideoOrientation() throws {
58+
// Given
59+
viewModel = CardScannerViewModelMock()
60+
sut = CardScannerViewController(viewModel: viewModel)
61+
62+
// When
63+
sut.viewDidLayoutSubviews()
64+
65+
// Then
66+
XCTAssertEqual(viewModel.updateVideoOrientationCallsCount, 1)
67+
}
68+
69+
func testVideoPreviewLayetIsSetOnInit() throws {
70+
// Given
71+
let expectedVideoPreviewLayer = CALayer()
72+
viewModel = CardScannerViewModelMock()
73+
viewModel.videoPreviewLayer = expectedVideoPreviewLayer
74+
sut = CardScannerViewController(viewModel: viewModel)
75+
76+
// When
77+
sut.loadViewIfNeeded()
78+
79+
// Then
80+
let layer = try XCTUnwrap(sut.view.layer.sublayers?.first)
81+
XCTAssertTrue(layer === expectedVideoPreviewLayer)
82+
}
83+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//
2+
// Copyright (c) 2025 Adyen N.V.
3+
//
4+
// This file is open source and available under the MIT license. See the LICENSE file for more info.
5+
//
6+
7+
@testable import AdyenCardScanner
8+
import Foundation
9+
import QuartzCore
10+
11+
class CardScannerViewModelMock: CardScannerViewModelProtocol {
12+
// MARK: - videoPreviewLayer
13+
14+
var videoPreviewLayer: CALayer = .init()
15+
16+
// MARK: - configureSession
17+
18+
var configureSessionCallsCount = 0
19+
var configureSessionCalled: Bool {
20+
configureSessionCallsCount > 0
21+
}
22+
23+
var configureSessionClosure: (() -> Void)?
24+
25+
func configureSession() {
26+
configureSessionCallsCount += 1
27+
configureSessionClosure?()
28+
}
29+
30+
// MARK: - startCaptureSession
31+
32+
var startCaptureSessionCallsCount = 0
33+
var startCaptureSessionCalled: Bool {
34+
startCaptureSessionCallsCount > 0
35+
}
36+
37+
var startCaptureSessionClosure: (() -> Void)?
38+
39+
func startCaptureSession() {
40+
startCaptureSessionCallsCount += 1
41+
startCaptureSessionClosure?()
42+
}
43+
44+
// MARK: - stopCaptureSession
45+
46+
var stopCaptureSessionCallsCount = 0
47+
var stopCaptureSessionCalled: Bool {
48+
stopCaptureSessionCallsCount > 0
49+
}
50+
51+
var stopCaptureSessionClosure: (() -> Void)?
52+
53+
func stopCaptureSession() {
54+
stopCaptureSessionCallsCount += 1
55+
stopCaptureSessionClosure?()
56+
}
57+
58+
// MARK: - updateVideoOrientation
59+
60+
var updateVideoOrientationCallsCount = 0
61+
var updateVideoOrientationCalled: Bool {
62+
updateVideoOrientationCallsCount > 0
63+
}
64+
65+
var updateVideoOrientationClosure: (() -> Void)?
66+
67+
func updateVideoOrientation() {
68+
updateVideoOrientationCallsCount += 1
69+
updateVideoOrientationClosure?()
70+
}
71+
72+
// MARK: - update
73+
74+
var updateCallsCount = 0
75+
var updateCalled: Bool {
76+
updateCallsCount > 0
77+
}
78+
79+
var updateReceivedPreviewLayerFrame: CGRect?
80+
var updateReceivedROIInPreviewLayer: CGRect?
81+
var updateReceivedInvocations: [(CGRect, CGRect)] = []
82+
var updateClosure: ((CGRect, CGRect) -> Void)?
83+
84+
func update(previewLayerFrame: CGRect, roiInPreviewLayer: CGRect) {
85+
updateCallsCount += 1
86+
updateReceivedPreviewLayerFrame = previewLayerFrame
87+
updateReceivedROIInPreviewLayer = roiInPreviewLayer
88+
updateReceivedInvocations.append((previewLayerFrame, roiInPreviewLayer))
89+
updateClosure?(previewLayerFrame, roiInPreviewLayer)
90+
}
91+
}

0 commit comments

Comments
 (0)