Skip to content

Commit

Permalink
Add SearchViewType
Browse files Browse the repository at this point in the history
Add SearchView unit tests
  • Loading branch information
dogo committed Mar 17, 2024
1 parent bbac5b7 commit 98d4c27
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ protocol SearchDelegate: AnyObject {
final class SearchListViewController: UIViewController {
private let destinyService: SWDestinyServiceProtocol
private let database: DatabaseProtocol?
private let searchView = SearchView()
private let searchView: SearchViewType = SearchView()
private var cards = [CardDTO]()
private lazy var navigator = SearchNavigator(self)

Expand All @@ -46,11 +46,11 @@ final class SearchListViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

searchView.searchTableView.didSelectCard = { [weak self] card in
searchView.didSelectCard = { [weak self] card in
self?.navigateToNextController(with: card)
}

searchView.searchBar.doingSearch = { [weak self] query in
searchView.doingSearch = { [weak self] query in
self?.search(query: query)
}
}
Expand All @@ -62,17 +62,17 @@ final class SearchListViewController: UIViewController {
}

private func search(query: String) {
searchView.activityIndicator.startAnimating()
searchView.startLoading()
Task { [weak self] in
guard let self else { return }

defer {
self.searchView.activityIndicator.stopAnimating()
self.searchView.stopLoading()
}

do {
let allCards = try await destinyService.search(query: query)
searchView.searchTableView.updateSearchList(allCards)
searchView.updateSearchList(allCards)
cards = allCards
} catch {
ToastMessages.showNetworkErrorMessage()
Expand Down
20 changes: 20 additions & 0 deletions SWDestinyTrades/Classes/Search/Protocol/SearchViewType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// SearchViewType.swift
// SWDestinyTrades
//
// Created by Diogo Autilio on 17/03/24.
// Copyright © 2024 Diogo Autilio. All rights reserved.
//

import Foundation
import UIKit

protocol SearchViewType where Self: UIView {

var didSelectCard: ((CardDTO) -> Void)? { get set }
var doingSearch: ((String) -> Void)? { get set }

func startLoading()
func stopLoading()
func updateSearchList(_ cards: [CardDTO])
}
34 changes: 30 additions & 4 deletions SWDestinyTrades/Classes/Search/View/SearchView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,25 @@

import UIKit

final class SearchView: UIView {
let searchBar = SearchBar()
final class SearchView: UIView, SearchViewType {

let searchTableView = SearchTableView()
var didSelectCard: ((CardDTO) -> Void)? {
didSet {
searchTableView.didSelectCard = didSelectCard
}
}

var doingSearch: ((String) -> Void)? {
didSet {
searchBar.doingSearch = doingSearch
}
}

private let searchBar = SearchBar()

private let searchTableView = SearchTableView()

let activityIndicator: UIActivityIndicatorView = {
private let activityIndicator: UIActivityIndicatorView = {
let view = UIActivityIndicatorView(style: .medium)
view.color = .whiteBlack
return view
Expand All @@ -28,9 +41,22 @@ final class SearchView: UIView {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func startLoading() {
activityIndicator.startAnimating()
}

func stopLoading() {
activityIndicator.stopAnimating()
}

func updateSearchList(_ cards: [CardDTO]) {
searchTableView.updateSearchList(cards)
}
}

extension SearchView: BaseViewConfiguration {

func buildViewHierarchy() {
addSubview(searchBar)
addSubview(searchTableView)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions SWDestinyTradesTests/Screens/Search/Mirror/SearchView+Mirror.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// SearchView+Mirror.swift
// SWDestinyTradesTests
//
// Created by Diogo Autilio on 17/03/24.
// Copyright © 2024 Diogo Autilio. All rights reserved.
//

import Foundation
import UIKit

@testable import SWDestinyTrades

extension SearchView {

var activityIndicator: UIActivityIndicatorView {
Mirror.extract(variable: "activityIndicator", from: self)!
}

var searchTableView: SearchTableView {
Mirror.extract(variable: "searchTableView", from: self)!
}

var searchBar: SearchBar {
Mirror.extract(variable: "searchBar", from: self)!
}
}
64 changes: 64 additions & 0 deletions SWDestinyTradesTests/Screens/Search/View/SearchViewTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// SearchViewTests.swift
// SWDestinyTradesTests
//
// Created by Diogo Autilio on 17/03/24.
// Copyright © 2024 Diogo Autilio. All rights reserved.
//

import UIKit
import XCTest

@testable import SWDestinyTrades

final class SearchViewTests: XCSnapshotableTestCase {

private var sut: SearchView!

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

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

func test_searchView_layout() {
XCTAssertTrue(snapshot(sut, named: "Search View layout"))
}

func test_startLoading() {
sut.startLoading()

XCTAssertTrue(sut.activityIndicator.isAnimating)
}

func test_stopLoading() {
sut.stopLoading()

XCTAssertFalse(sut.activityIndicator.isAnimating)
}

func test_updateSearchList() {
sut.updateSearchList([.stub()])

let datasourceCount = sut.searchTableView.searchDatasource?.tableView(sut.searchTableView,
numberOfRowsInSection: 0)

XCTAssertEqual(datasourceCount, 1)
}

func test_didSelectCard_is_set() {
sut.didSelectCard = { _ in }

XCTAssertNotNil(sut.searchTableView.didSelectCard)
}

func test_doingSearch_is_set() {
sut.doingSearch = { _ in }

XCTAssertNotNil(sut.searchBar.doingSearch)
}
}

0 comments on commit 98d4c27

Please sign in to comment.