@@ -17,28 +17,58 @@ class MoviesListViewModelTests: XCTestCase {
17
17
18
18
class SearchMoviesUseCaseMock : SearchMoviesUseCase {
19
19
var executeCallCount : Int = 0
20
- var error : Error ?
21
- var page = MoviesPage ( page: 0 , totalPages: 0 , movies: [ ] )
20
+
21
+ typealias ExecuteBlock = (
22
+ SearchMoviesUseCaseRequestValue ,
23
+ ( MoviesPage ) -> Void ,
24
+ ( Result < MoviesPage , Error > ) -> Void
25
+ ) -> Void
26
+
27
+ lazy var _execute : ExecuteBlock = { _, _, _ in
28
+ XCTFail ( " not implemented " )
29
+ }
22
30
23
31
func execute(
24
32
requestValue: SearchMoviesUseCaseRequestValue ,
25
33
cached: @escaping ( MoviesPage ) -> Void ,
26
34
completion: @escaping ( Result < MoviesPage , Error > ) -> Void
27
35
) -> Cancellable ? {
28
- if let error = error {
29
- completion ( . failure( error) )
30
- } else {
31
- completion ( . success( page) )
32
- }
33
36
executeCallCount += 1
37
+ _execute ( requestValue, cached, completion)
34
38
return nil
35
39
}
36
40
}
37
41
42
+ func test_whenFetchUsersUseCaseRetrievesEmptyPage_thenViewModelIsEmpty( ) {
43
+ // given
44
+ let searchMoviesUseCaseMock = SearchMoviesUseCaseMock ( )
45
+
46
+ searchMoviesUseCaseMock. _execute = { requestValue, _, completion in
47
+ XCTAssertEqual ( requestValue. page, 1 )
48
+ completion ( . success( MoviesPage ( page: 1 , totalPages: 0 , movies: [ ] ) ) )
49
+ }
50
+ let viewModel = DefaultMoviesListViewModel (
51
+ searchMoviesUseCase: searchMoviesUseCaseMock,
52
+ mainQueue: DispatchQueueTypeMock ( )
53
+ )
54
+ // when
55
+ viewModel. didSearch ( query: " query " )
56
+
57
+ // then
58
+ XCTAssertEqual ( viewModel. currentPage, 1 )
59
+ XCTAssertFalse ( viewModel. hasMorePages)
60
+ XCTAssertTrue ( viewModel. items. value. isEmpty)
61
+ XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount, 1 )
62
+ }
63
+
38
64
func test_whenSearchMoviesUseCaseRetrievesFirstPage_thenViewModelContainsOnlyFirstPage( ) {
39
65
// given
40
66
let searchMoviesUseCaseMock = SearchMoviesUseCaseMock ( )
41
- searchMoviesUseCaseMock. page = MoviesPage ( page: 1 , totalPages: 2 , movies: moviesPages [ 0 ] . movies)
67
+
68
+ searchMoviesUseCaseMock. _execute = { requestValue, _, completion in
69
+ XCTAssertEqual ( requestValue. page, 1 )
70
+ completion ( . success( self . moviesPages [ 0 ] ) )
71
+ }
42
72
let viewModel = DefaultMoviesListViewModel (
43
73
searchMoviesUseCase: searchMoviesUseCaseMock,
44
74
mainQueue: DispatchQueueTypeMock ( )
@@ -47,6 +77,10 @@ class MoviesListViewModelTests: XCTestCase {
47
77
viewModel. didSearch ( query: " query " )
48
78
49
79
// then
80
+ let expectedItems : [ MoviesListItemViewModel ] = moviesPages [ 0 ]
81
+ . movies
82
+ . map { MoviesListItemViewModel ( movie: $0) }
83
+ XCTAssertEqual ( viewModel. items. value, expectedItems)
50
84
XCTAssertEqual ( viewModel. currentPage, 1 )
51
85
XCTAssertTrue ( viewModel. hasMorePages)
52
86
XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount, 1 )
@@ -55,59 +89,84 @@ class MoviesListViewModelTests: XCTestCase {
55
89
func test_whenSearchMoviesUseCaseRetrievesFirstAndSecondPage_thenViewModelContainsTwoPages( ) {
56
90
// given
57
91
let searchMoviesUseCaseMock = SearchMoviesUseCaseMock ( )
58
- searchMoviesUseCaseMock. page = MoviesPage ( page: 1 , totalPages: 2 , movies: moviesPages [ 0 ] . movies)
92
+
93
+ searchMoviesUseCaseMock. _execute = { requestValue, _, completion in
94
+ XCTAssertEqual ( requestValue. page, 1 )
95
+ completion ( . success( self . moviesPages [ 0 ] ) )
96
+ }
59
97
let viewModel = DefaultMoviesListViewModel . make (
60
98
searchMoviesUseCase: searchMoviesUseCaseMock
61
99
)
62
100
// when
63
101
viewModel. didSearch ( query: " query " )
64
102
XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount, 1 )
65
103
66
- searchMoviesUseCaseMock. page = MoviesPage ( page: 2 , totalPages: 2 , movies: moviesPages [ 1 ] . movies)
67
-
104
+ let testPage2 = 1
105
+ searchMoviesUseCaseMock. _execute = { requestValue, _, completion in
106
+ XCTAssertEqual ( requestValue. page, 2 )
107
+ completion ( . success( self . moviesPages [ 1 ] ) )
108
+ }
109
+
68
110
viewModel. didLoadNextPage ( )
69
-
111
+
70
112
// then
113
+ let expectedItems : [ MoviesListItemViewModel ] = moviesPages
114
+ . flatMap { $0. movies }
115
+ . map { MoviesListItemViewModel ( movie: $0) }
116
+ XCTAssertEqual ( viewModel. items. value, expectedItems)
71
117
XCTAssertEqual ( viewModel. currentPage, 2 )
72
118
XCTAssertFalse ( viewModel. hasMorePages)
73
119
XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount, 2 )
74
120
}
75
-
121
+
76
122
func test_whenSearchMoviesUseCaseReturnsError_thenViewModelContainsError( ) {
77
123
// given
78
124
let searchMoviesUseCaseMock = SearchMoviesUseCaseMock ( )
79
- searchMoviesUseCaseMock. error = SearchMoviesUseCaseError . someError
125
+
126
+ searchMoviesUseCaseMock. _execute = { requestValue, _, completion in
127
+ XCTAssertEqual ( requestValue. page, 1 )
128
+ completion ( . failure( SearchMoviesUseCaseError . someError) )
129
+ }
80
130
let viewModel = DefaultMoviesListViewModel . make (
81
131
searchMoviesUseCase: searchMoviesUseCaseMock
82
132
)
83
133
// when
84
134
viewModel. didSearch ( query: " query " )
85
-
135
+
86
136
// then
87
137
XCTAssertNotNil ( viewModel. error)
138
+ XCTAssertTrue ( viewModel. items. value. isEmpty)
88
139
XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount, 1 )
89
140
}
90
-
141
+
91
142
func test_whenLastPage_thenHasNoPageIsTrue( ) {
92
143
// given
93
144
let searchMoviesUseCaseMock = SearchMoviesUseCaseMock ( )
94
- searchMoviesUseCaseMock. page = MoviesPage ( page: 1 , totalPages: 2 , movies: moviesPages [ 0 ] . movies)
145
+ searchMoviesUseCaseMock. _execute = { requestValue, _, completion in
146
+ XCTAssertEqual ( requestValue. page, 1 )
147
+ completion ( . success( self . moviesPages [ 0 ] ) )
148
+ }
95
149
let viewModel = DefaultMoviesListViewModel . make (
96
150
searchMoviesUseCase: searchMoviesUseCaseMock
97
151
)
98
152
// when
99
153
viewModel. didSearch ( query: " query " )
100
154
XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount, 1 )
101
-
102
- searchMoviesUseCaseMock. page = MoviesPage ( page: 2 , totalPages: 2 , movies: moviesPages [ 1 ] . movies)
155
+
156
+ searchMoviesUseCaseMock. _execute = { requestValue, _, completion in
157
+ XCTAssertEqual ( requestValue. page, 2 )
158
+ completion ( . success( self . moviesPages [ 1 ] ) )
159
+ }
103
160
104
161
viewModel. didLoadNextPage ( )
105
-
162
+
106
163
// then
107
164
XCTAssertEqual ( viewModel. currentPage, 2 )
108
165
XCTAssertFalse ( viewModel. hasMorePages)
109
166
XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount, 2 )
110
167
}
168
+
169
+
111
170
}
112
171
113
172
extension DefaultMoviesListViewModel {
0 commit comments