Skip to content

Commit

Permalink
Add NewPersonView unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dogo committed Mar 1, 2024
1 parent 876d2fa commit 3694996
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import UIKit

final class NewPersonViewController: UIViewController {

private let newPersonView: NewPersonView
private let newPersonView: NewPersonViewType

var presenter: NewPersonPresenterProtocol?

// MARK: - Life Cycle

init(with view: NewPersonView = NewPersonView()) {
init(with view: NewPersonViewType) {
newPersonView = view
super.init(nibName: nil, bundle: nil)
}
Expand Down Expand Up @@ -52,9 +52,7 @@ extension NewPersonViewController: NewPersonViewControllerProtocol {
}

func retriveUserInput() -> (name: String, lastName: String) {
let name = newPersonView.firstNameTextField.nonOptionalText
let lastName = newPersonView.lastNameTextField.nonOptionalText
return (name, lastName)
return newPersonView.retriveUserInput()
}

func closeViewController() {
Expand Down
14 changes: 10 additions & 4 deletions SWDestinyTrades/Classes/NewPerson/View/NewPersonView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,19 @@

import UIKit

final class NewPersonView: UIView {
final class NewPersonView: UIView, NewPersonViewType {

lazy var firstNameTextField: FloatingTextfield = {
private let firstNameTextField: FloatingTextfield = {
let textField = FloatingTextfield(frame: .zero)
textField.textColor = .whiteBlack
textField.autocapitalizationType = .sentences
textField.font = UIFont.systemFont(ofSize: 17)
textField.placeholder = L10n.firstName
textField.placeholderTextColor = .secondaryLabel
textField.delegate = self
return textField
}()

var lastNameTextField: FloatingTextfield = {
private let lastNameTextField: FloatingTextfield = {
let textField = FloatingTextfield(frame: .zero)
textField.textColor = .whiteBlack
textField.autocapitalizationType = .sentences
Expand All @@ -40,6 +39,12 @@ final class NewPersonView: UIView {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func retriveUserInput() -> (name: String, lastName: String) {
let name = firstNameTextField.nonOptionalText
let lastName = lastNameTextField.nonOptionalText
return (name, lastName)
}
}

extension NewPersonView: BaseViewConfiguration {
Expand Down Expand Up @@ -67,6 +72,7 @@ extension NewPersonView: BaseViewConfiguration {

func configureViews() {
backgroundColor = .blackWhite
firstNameTextField.delegate = self
}
}

Expand Down
15 changes: 15 additions & 0 deletions SWDestinyTrades/Classes/NewPerson/View/NewPersonViewType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// NewPersonViewType.swift
// SWDestinyTrades
//
// Created by Diogo Autilio on 29/02/24.
// Copyright © 2024 Diogo Autilio. All rights reserved.
//

import Foundation
import UIKit

protocol NewPersonViewType where Self: UIView {

func retriveUserInput() -> (name: String, lastName: String)
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ final class PeopleListNavigator: Navigator {
case let .loanDetail(database, person):
return LoansDetailViewControllerFactory(database: database, person: person).createViewController()
case let .newPerson(delegate):
let viewController = NewPersonViewController()
let viewController = NewPersonViewController(with: NewPersonView())
let presenter = NewPersonPresenter(controller: viewController, delegate: delegate)
viewController.presenter = presenter
return viewController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,24 @@ final class NewPersonViewControllerTests: XCTestCase {

private var sut: NewPersonViewController!
private var presenter: NewPersonPresenterSpy!
private var view: NewPersonViewSpy!
private var navigationController: UINavigationControllerMock!
private var keyWindow: UIWindow!

override func setUp() {
super.setUp()
keyWindow = UIWindow(frame: .testDevice)
presenter = NewPersonPresenterSpy()
sut = NewPersonViewController()
view = NewPersonViewSpy()
sut = NewPersonViewController(with: view)
sut.presenter = presenter
navigationController = UINavigationControllerMock(rootViewController: sut)
keyWindow.showTestWindow(controller: navigationController)
}

override func tearDown() {
navigationController = nil
view = nil
sut = nil
keyWindow.cleanTestWindow()
super.tearDown()
Expand All @@ -38,7 +41,7 @@ final class NewPersonViewControllerTests: XCTestCase {
func test_loadView() {
sut.loadView()

XCTAssertTrue(sut.view is NewPersonView)
XCTAssertTrue(sut.view is NewPersonViewType)
}

func test_viewDidLoad() {
Expand All @@ -60,10 +63,12 @@ final class NewPersonViewControllerTests: XCTestCase {
}

func test_retriveUserInput() {
view.userInput = ("Darth", "Vader")

let userInput = sut.retriveUserInput()

XCTAssertEqual(userInput.name, "")
XCTAssertEqual(userInput.lastName, "")
XCTAssertEqual(userInput.name, "Darth")
XCTAssertEqual(userInput.lastName, "Vader")
}

func test_closeViewController() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// NewPersonViewSpy.swift
// SWDestinyTradesTests
//
// Created by Diogo Autilio on 29/02/24.
// Copyright © 2024 Diogo Autilio. All rights reserved.
//

import Foundation
import UIKit

@testable import SWDestinyTrades

final class NewPersonViewSpy: UIView, NewPersonViewType {

private(set) var didCallRetriveUserInputCount = 0
var userInput: (name: String, lastName: String) = ("", "")
func retriveUserInput() -> (name: String, lastName: String) {
didCallRetriveUserInputCount += 1
return userInput
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// NewPersonView+Mirror.swift
// SWDestinyTradesTests
//
// Created by Diogo Autilio on 29/02/24.
// Copyright © 2024 Diogo Autilio. All rights reserved.
//

import Foundation
import UIKit

@testable import SWDestinyTrades

extension NewPersonView {

var firstNameTextField: FloatingTextfield {
Mirror.extract(variable: "firstNameTextField", from: self)!
}

var lastNameTextField: FloatingTextfield {
Mirror.extract(variable: "lastNameTextField", from: self)!
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// NewPersonViewTests.swift
// SWDestinyTradesTests
//
// Created by Diogo Autilio on 29/02/24.
// Copyright © 2024 Diogo Autilio. All rights reserved.
//

import UIKit
import XCTest

@testable import SWDestinyTrades

final class NewPersonViewTests: XCTestCase {

private var sut: NewPersonView!

override func setUp() {
super.setUp()
sut = NewPersonView(frame: .testDevice)
}

override func tearDown() {
sut = nil
super.tearDown()
}

func test_retriveUserInput() {
sut.firstNameTextField.text = "Darth"
sut.lastNameTextField.text = "Vader"

let userInput = sut.retriveUserInput()

XCTAssertEqual(userInput.name, "Darth")
XCTAssertEqual(userInput.lastName, "Vader")
}

func test_textFieldShouldReturn() {
// isFirstResponder needs a UIWindow to work properly
let controller = UIViewController()
let keyWindow = UIWindow(frame: .testDevice)
controller.view = sut
keyWindow.showTestWindow(controller: controller)

XCTAssertFalse(sut.lastNameTextField.isFirstResponder)

let result = sut.textFieldShouldReturn(sut.firstNameTextField)

XCTAssertTrue(sut.lastNameTextField.isFirstResponder)
XCTAssertTrue(result)
}
}

0 comments on commit 3694996

Please sign in to comment.