From 120d0d1a9764676ac71e38174688f7ff3edb1241 Mon Sep 17 00:00:00 2001 From: Diogo Autilio Date: Thu, 25 Jan 2024 10:03:12 -0300 Subject: [PATCH] Add CardDetailViewController unit tests --- .../Controller/CardDetailViewController.swift | 4 +- .../CardDetail/Protocol/CardViewType.swift | 21 +++++ .../Classes/CardDetail/View/CardView.swift | 2 +- .../CardDetailViewControllerTests.swift | 80 +++++++++++++++++-- .../Doubles/CardDetailPresenterSpy.swift | 31 +++++++ .../CardDetail/Doubles/CardViewSpy.swift | 40 ++++++++++ 6 files changed, 167 insertions(+), 11 deletions(-) create mode 100644 SWDestinyTrades/Classes/CardDetail/Protocol/CardViewType.swift create mode 100644 SWDestinyTradesTests/Screens/CardDetail/Doubles/CardDetailPresenterSpy.swift create mode 100644 SWDestinyTradesTests/Screens/CardDetail/Doubles/CardViewSpy.swift diff --git a/SWDestinyTrades/Classes/CardDetail/Controller/CardDetailViewController.swift b/SWDestinyTrades/Classes/CardDetail/Controller/CardDetailViewController.swift index 8f0f8b4c..13abe1a2 100644 --- a/SWDestinyTrades/Classes/CardDetail/Controller/CardDetailViewController.swift +++ b/SWDestinyTrades/Classes/CardDetail/Controller/CardDetailViewController.swift @@ -11,13 +11,13 @@ import UIKit final class CardDetailViewController: UIViewController { - private let cardView: CardView + private let cardView: CardViewType var presenter: CardDetailPresenterProtocol? // MARK: - Life Cycle - init(with view: CardView = CardView()) { + init(with view: CardViewType = CardView()) { cardView = view super.init(nibName: nil, bundle: nil) } diff --git a/SWDestinyTrades/Classes/CardDetail/Protocol/CardViewType.swift b/SWDestinyTrades/Classes/CardDetail/Protocol/CardViewType.swift new file mode 100644 index 00000000..790623b6 --- /dev/null +++ b/SWDestinyTrades/Classes/CardDetail/Protocol/CardViewType.swift @@ -0,0 +1,21 @@ +// +// CardViewType.swift +// SWDestinyTrades +// +// Created by Diogo Autilio on 25/01/24. +// Copyright © 2024 Diogo Autilio. All rights reserved. +// + +import Foundation +import ImageSlideshow +import UIKit + +protocol CardViewType where Self: UIView { + + var currentPageChanged: ((_ page: Int) -> Void)? { get set } + + func setSlideshowImageInputs(_ imageInputs: [InputSource]) + func setCurrentPage(_ page: Int, animated: Bool) + func getCurrentPage() -> Int + func getCurrentSlideshowItem() -> ImageSlideshowItem? +} diff --git a/SWDestinyTrades/Classes/CardDetail/View/CardView.swift b/SWDestinyTrades/Classes/CardDetail/View/CardView.swift index 518278b0..0e090c4c 100644 --- a/SWDestinyTrades/Classes/CardDetail/View/CardView.swift +++ b/SWDestinyTrades/Classes/CardDetail/View/CardView.swift @@ -18,7 +18,7 @@ protocol CardDetailViewProtocol: AnyObject { func showSuccessMessage(card: CardDTO) } -final class CardView: UIView { +final class CardView: UIView, CardViewType { var currentPageChanged: ((_ page: Int) -> Void)? { didSet { diff --git a/SWDestinyTradesTests/Screens/CardDetail/Controller/CardDetailViewControllerTests.swift b/SWDestinyTradesTests/Screens/CardDetail/Controller/CardDetailViewControllerTests.swift index e0767572..a2ef5249 100644 --- a/SWDestinyTradesTests/Screens/CardDetail/Controller/CardDetailViewControllerTests.swift +++ b/SWDestinyTradesTests/Screens/CardDetail/Controller/CardDetailViewControllerTests.swift @@ -9,29 +9,93 @@ import UIKit import XCTest +@testable import PKHUD @testable import SWDestinyTrades final class CardDetailViewControllerTests: XCTestCase { private var sut: CardDetailViewController! + private var view: CardViewSpy! + private var presenter: CardDetailPresenterSpy! + private var keyWindow: UIWindow! + private var navigationController: UINavigationControllerMock! override func setUp() { super.setUp() - sut = CardDetailViewController() + keyWindow = UIWindow(frame: .testDevice) + view = CardViewSpy() + sut = CardDetailViewController(with: view) + presenter = CardDetailPresenterSpy() + sut.presenter = presenter + navigationController = UINavigationControllerMock(rootViewController: sut) + keyWindow.showTestWindow(controller: navigationController) } - func testCreateController() { - XCTAssertNotNil(sut) + override func tearDown() { + view = nil + presenter = nil + navigationController = nil + sut = nil + keyWindow.cleanTestWindow() + super.tearDown() } - func testViewIsKindOfCardView() { - XCTAssertTrue(sut.view is CardView) + func test_loadView() { + sut.loadView() + + XCTAssertTrue(sut.view is CardViewType) + } + + func test_viewDidLoad() { + sut.viewDidLoad() + + XCTAssertEqual(presenter.didCallViewDidLoadCount, 1) + XCTAssertEqual(presenter.didCallSetupNavigationItemsCount, 1) } - func testNavigationTitle() { - _ = UINavigationController(rootViewController: sut) + func test_viewWillAppear() { sut.viewWillAppear(false) - XCTAssertEqual(sut.navigationItem.title, "") + XCTAssertEqual(presenter.didCallSetNavigationTitleCount, 1) + } + + func test_currentPageChanged() { + sut.viewDidLoad() + view.currentPageChanged?(1) + + XCTAssertEqual(presenter.didCallSetNavigationTitleCount, 1) + } + + func test_setSlideshowImageInputs() { + sut.setSlideshowImageInputs([]) + + XCTAssertEqual(view.didCallSetSlideshowImageInputs.count, 0) + } + + func test_setCurrentPage() { + sut.setCurrentPage(1, animated: false) + + XCTAssertEqual(view.didCallSetCurrentPage[0].page, 1) + XCTAssertEqual(view.didCallSetCurrentPage[0].animated, false) + } + + func test_getCurrentPage() { + XCTAssertEqual(sut.getCurrentPage(), 0) + } + + func test_getCurrentSlideshowItem() { + XCTAssertEqual(sut.getCurrentSlideshowItem(), nil) + } + + func test_setNavigationTitle() { + sut.setNavigationTitle("Card Title") + + XCTAssertEqual(sut.navigationItem.title, "Card Title") + } + + func test_showSuccessMessage() { + sut.showSuccessMessage(card: .stub()) + + XCTAssertTrue(keyWindow.subviews.contains { $0 is ContainerView }) } } diff --git a/SWDestinyTradesTests/Screens/CardDetail/Doubles/CardDetailPresenterSpy.swift b/SWDestinyTradesTests/Screens/CardDetail/Doubles/CardDetailPresenterSpy.swift new file mode 100644 index 00000000..a096cf3a --- /dev/null +++ b/SWDestinyTradesTests/Screens/CardDetail/Doubles/CardDetailPresenterSpy.swift @@ -0,0 +1,31 @@ +// +// CardDetailPresenterSpy.swift +// SWDestinyTradesTests +// +// Created by Diogo Autilio on 25/01/24. +// Copyright © 2024 Diogo Autilio. All rights reserved. +// + +import Foundation +import UIKit + +@testable import SWDestinyTrades + +final class CardDetailPresenterSpy: CardDetailPresenterProtocol { + + private(set) var didCallViewDidLoadCount = 0 + func viewDidLoad() { + didCallViewDidLoadCount += 1 + } + + private(set) var didCallSetNavigationTitleCount = 0 + func setNavigationTitle() { + didCallSetNavigationTitleCount += 1 + } + + private(set) var didCallSetupNavigationItemsCount = 0 + func setupNavigationItems(completion: ([UIBarButtonItem]?) -> Void) { + didCallSetupNavigationItemsCount += 1 + completion([]) + } +} diff --git a/SWDestinyTradesTests/Screens/CardDetail/Doubles/CardViewSpy.swift b/SWDestinyTradesTests/Screens/CardDetail/Doubles/CardViewSpy.swift new file mode 100644 index 00000000..946fd386 --- /dev/null +++ b/SWDestinyTradesTests/Screens/CardDetail/Doubles/CardViewSpy.swift @@ -0,0 +1,40 @@ +// +// CardViewSpy.swift +// SWDestinyTradesTests +// +// Created by Diogo Autilio on 25/01/24. +// Copyright © 2024 Diogo Autilio. All rights reserved. +// + +import Foundation +import ImageSlideshow +import UIKit + +@testable import SWDestinyTrades + +final class CardViewSpy: UIView, CardViewType { + + var currentPageChanged: ((Int) -> Void)? + + private(set) var didCallSetSlideshowImageInputs = [InputSource]() + func setSlideshowImageInputs(_ imageInputs: [InputSource]) { + didCallSetSlideshowImageInputs.append(contentsOf: imageInputs) + } + + private(set) var didCallSetCurrentPage = [(page: Int, animated: Bool)]() + func setCurrentPage(_ page: Int, animated: Bool) { + didCallSetCurrentPage.append((page, animated)) + } + + private(set) var didCallGetCurrentPageCount = 0 + func getCurrentPage() -> Int { + didCallGetCurrentPageCount += 1 + return 0 + } + + private(set) var didCallGetCurrentSlideshowItemCount = 0 + func getCurrentSlideshowItem() -> ImageSlideshowItem? { + didCallGetCurrentSlideshowItemCount += 1 + return nil + } +}