@@ -16,7 +16,7 @@ class MoviesListViewModelTests: XCTestCase {
16
16
} ( )
17
17
18
18
class SearchMoviesUseCaseMock : SearchMoviesUseCase {
19
- var executeCallCount : Int = 0
19
+ var callCount : Int = 0
20
20
21
21
typealias ExecuteBlock = (
22
22
SearchMoviesUseCaseRequestValue ,
@@ -33,13 +33,13 @@ class MoviesListViewModelTests: XCTestCase {
33
33
cached: @escaping ( MoviesPage ) -> Void ,
34
34
completion: @escaping ( Result < MoviesPage , Error > ) -> Void
35
35
) -> Cancellable ? {
36
- executeCallCount += 1
36
+ callCount += 1
37
37
_execute ( requestValue, cached, completion)
38
38
return nil
39
39
}
40
40
}
41
41
42
- func test_whenFetchUsersUseCaseRetrievesEmptyPage_thenViewModelIsEmpty ( ) {
42
+ func test_whenSearchMoviesUseCaseRetrievesEmptyPage_thenViewModelIsEmpty ( ) {
43
43
// given
44
44
let searchMoviesUseCaseMock = SearchMoviesUseCaseMock ( )
45
45
@@ -58,7 +58,7 @@ class MoviesListViewModelTests: XCTestCase {
58
58
XCTAssertEqual ( viewModel. currentPage, 1 )
59
59
XCTAssertFalse ( viewModel. hasMorePages)
60
60
XCTAssertTrue ( viewModel. items. value. isEmpty)
61
- XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount , 1 )
61
+ XCTAssertEqual ( searchMoviesUseCaseMock. callCount , 1 )
62
62
}
63
63
64
64
func test_whenSearchMoviesUseCaseRetrievesFirstPage_thenViewModelContainsOnlyFirstPage( ) {
@@ -77,13 +77,13 @@ class MoviesListViewModelTests: XCTestCase {
77
77
viewModel. didSearch ( query: " query " )
78
78
79
79
// then
80
- let expectedItems : [ MoviesListItemViewModel ] = moviesPages [ 0 ]
80
+ let expectedItems = moviesPages [ 0 ]
81
81
. movies
82
82
. map { MoviesListItemViewModel ( movie: $0) }
83
83
XCTAssertEqual ( viewModel. items. value, expectedItems)
84
84
XCTAssertEqual ( viewModel. currentPage, 1 )
85
85
XCTAssertTrue ( viewModel. hasMorePages)
86
- XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount , 1 )
86
+ XCTAssertEqual ( searchMoviesUseCaseMock. callCount , 1 )
87
87
}
88
88
89
89
func test_whenSearchMoviesUseCaseRetrievesFirstAndSecondPage_thenViewModelContainsTwoPages( ) {
@@ -99,9 +99,8 @@ class MoviesListViewModelTests: XCTestCase {
99
99
)
100
100
// when
101
101
viewModel. didSearch ( query: " query " )
102
- XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount , 1 )
102
+ XCTAssertEqual ( searchMoviesUseCaseMock. callCount , 1 )
103
103
104
- let testPage2 = 1
105
104
searchMoviesUseCaseMock. _execute = { requestValue, _, completion in
106
105
XCTAssertEqual ( requestValue. page, 2 )
107
106
completion ( . success( self . moviesPages [ 1 ] ) )
@@ -110,13 +109,13 @@ class MoviesListViewModelTests: XCTestCase {
110
109
viewModel. didLoadNextPage ( )
111
110
112
111
// then
113
- let expectedItems : [ MoviesListItemViewModel ] = moviesPages
112
+ let expectedItems = moviesPages
114
113
. flatMap { $0. movies }
115
114
. map { MoviesListItemViewModel ( movie: $0) }
116
115
XCTAssertEqual ( viewModel. items. value, expectedItems)
117
116
XCTAssertEqual ( viewModel. currentPage, 2 )
118
117
XCTAssertFalse ( viewModel. hasMorePages)
119
- XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount , 2 )
118
+ XCTAssertEqual ( searchMoviesUseCaseMock. callCount , 2 )
120
119
}
121
120
122
121
func test_whenSearchMoviesUseCaseReturnsError_thenViewModelContainsError( ) {
@@ -136,7 +135,7 @@ class MoviesListViewModelTests: XCTestCase {
136
135
// then
137
136
XCTAssertNotNil ( viewModel. error)
138
137
XCTAssertTrue ( viewModel. items. value. isEmpty)
139
- XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount , 1 )
138
+ XCTAssertEqual ( searchMoviesUseCaseMock. callCount , 1 )
140
139
}
141
140
142
141
func test_whenLastPage_thenHasNoPageIsTrue( ) {
@@ -151,7 +150,7 @@ class MoviesListViewModelTests: XCTestCase {
151
150
)
152
151
// when
153
152
viewModel. didSearch ( query: " query " )
154
- XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount , 1 )
153
+ XCTAssertEqual ( searchMoviesUseCaseMock. callCount , 1 )
155
154
156
155
searchMoviesUseCaseMock. _execute = { requestValue, _, completion in
157
156
XCTAssertEqual ( requestValue. page, 2 )
@@ -163,10 +162,84 @@ class MoviesListViewModelTests: XCTestCase {
163
162
// then
164
163
XCTAssertEqual ( viewModel. currentPage, 2 )
165
164
XCTAssertFalse ( viewModel. hasMorePages)
166
- XCTAssertEqual ( searchMoviesUseCaseMock. executeCallCount , 2 )
165
+ XCTAssertEqual ( searchMoviesUseCaseMock. callCount , 2 )
167
166
}
168
167
168
+ func test_whenSearchMoviesUseCaseReturnsCachedData_thenViewModelShowsFirstCachedDataAndAfterFreshData( ) {
169
+ // given
170
+ let cachedPage : MoviesPage = . init(
171
+ page: 1 ,
172
+ totalPages: 2 ,
173
+ movies: [ . stub( id: " cachedMovieId1 " ) ]
174
+ )
175
+ let searchMoviesUseCaseMock = SearchMoviesUseCaseMock ( )
176
+
177
+ let viewModel = DefaultMoviesListViewModel (
178
+ searchMoviesUseCase: searchMoviesUseCaseMock,
179
+ mainQueue: DispatchQueueTypeMock ( )
180
+ )
181
+
182
+ let testItemsBeforeFreshData = {
183
+ let expectedItems = cachedPage
184
+ . movies
185
+ . map { MoviesListItemViewModel ( movie: $0) }
186
+
187
+ XCTAssertEqual ( viewModel. items. value, expectedItems)
188
+ }
189
+
190
+ searchMoviesUseCaseMock. _execute = { requestValue, cached, completion in
191
+ XCTAssertEqual ( requestValue. page, 1 )
192
+ cached ( cachedPage)
193
+ testItemsBeforeFreshData ( )
194
+ completion ( . success( self . moviesPages [ 0 ] ) )
195
+ }
196
+
197
+ // when
198
+ viewModel. didSearch ( query: " query " )
199
+
200
+ // then
201
+ let expectedItems = moviesPages [ 0 ]
202
+ . movies
203
+ . map { MoviesListItemViewModel ( movie: $0) }
204
+ XCTAssertEqual ( viewModel. items. value, expectedItems)
205
+ XCTAssertEqual ( viewModel. currentPage, 1 )
206
+ XCTAssertTrue ( viewModel. hasMorePages)
207
+ XCTAssertEqual ( searchMoviesUseCaseMock. callCount, 1 )
208
+ }
169
209
210
+ func test_whenSearchMoviesUseCaseReturnsError_thenViewModelShowsCachedData( ) {
211
+ // given
212
+ let cachedPage : MoviesPage = . init(
213
+ page: 1 ,
214
+ totalPages: 2 ,
215
+ movies: [ . stub( id: " cachedMovieId1 " ) ]
216
+ )
217
+ let searchMoviesUseCaseMock = SearchMoviesUseCaseMock ( )
218
+
219
+ let viewModel = DefaultMoviesListViewModel (
220
+ searchMoviesUseCase: searchMoviesUseCaseMock,
221
+ mainQueue: DispatchQueueTypeMock ( )
222
+ )
223
+
224
+ searchMoviesUseCaseMock. _execute = { requestValue, cached, completion in
225
+ XCTAssertEqual ( requestValue. page, 1 )
226
+ cached ( cachedPage)
227
+ completion ( . failure( SearchMoviesUseCaseError . someError) )
228
+ }
229
+
230
+ // when
231
+ viewModel. didSearch ( query: " query " )
232
+
233
+ // then
234
+ let expectedItems = cachedPage
235
+ . movies
236
+ . map { MoviesListItemViewModel ( movie: $0) }
237
+ XCTAssertEqual ( viewModel. items. value, expectedItems)
238
+ XCTAssertEqual ( viewModel. currentPage, 1 )
239
+ XCTAssertTrue ( viewModel. hasMorePages)
240
+ XCTAssertEqual ( searchMoviesUseCaseMock. callCount, 1 )
241
+ }
242
+
170
243
}
171
244
172
245
extension DefaultMoviesListViewModel {
0 commit comments