Implemented some test cases for the "filter(by:)" function of the FeedListViewModel view model in the Feed framework.

This commit is contained in:
Javier Cicchelli 2024-03-22 14:58:13 +01:00
parent 5de35984dc
commit a1abe1f4ae
2 changed files with 169 additions and 30 deletions

View File

@ -20,14 +20,14 @@ extension FeedListViewController {
private let topWords: TopWordsUseCase = .init()
// MARK: Properties
@Published var filter: FilterOption = .all
@Published var isFilterEnabled: Bool = false
@Published var isFiltering: Bool = false
@Published var isLoading: Bool = false
@Published var state: FeedListState = .initial
@Published private(set) var filter: FilterOption = .all
@Published private(set) var isFilterEnabled: Bool = false
@Published private(set) var isFiltering: Bool = false
@Published private(set) var isLoading: Bool = false
@Published private(set) var state: FeedListState = .initial
var items: [Review] = []
var words: [TopWord] = []
private(set) var items: [Review] = []
private(set) var words: [TopWord] = []
private var reviewsAll: [Review] = []
private var reviewsFiltered: FilteredReviews = [:]

View File

@ -61,8 +61,6 @@ final class FeedListViewModelTests: XCTestCase {
)
// WHEN
sut.fetch()
sut.$isLoading
.collect(3)
.sink { value in
@ -72,6 +70,8 @@ final class FeedListViewModelTests: XCTestCase {
}
.store(in: &cancellables)
sut.fetch()
wait(for: [expectation], timeout: 2)
// THEN
@ -96,8 +96,6 @@ final class FeedListViewModelTests: XCTestCase {
)
// WHEN
sut.fetch()
sut.$isLoading
.collect(3)
.sink { value in
@ -107,6 +105,8 @@ final class FeedListViewModelTests: XCTestCase {
}
.store(in: &cancellables)
sut.fetch()
wait(for: [expectation], timeout: 2)
// THEN
@ -127,8 +127,6 @@ final class FeedListViewModelTests: XCTestCase {
MockURLProtocol.response = .init(statusCode: 404)
// WHEN
sut.fetch()
sut.$isLoading
.collect(3)
.sink { value in
@ -138,6 +136,8 @@ final class FeedListViewModelTests: XCTestCase {
}
.store(in: &cancellables)
sut.fetch()
wait(for: [expectation], timeout: 2)
// THEN
@ -155,16 +155,12 @@ final class FeedListViewModelTests: XCTestCase {
var isLoading: [Bool] = []
// GIVEN
sut.filter = .only1Star
MockURLProtocol.response = .init(
statusCode: 200,
object: Feed(entries: .sample)
)
// WHEN
sut.fetch()
sut.$isLoading
.collect(3)
.sink { value in
@ -174,10 +170,14 @@ final class FeedListViewModelTests: XCTestCase {
}
.store(in: &cancellables)
sut.filter(by: .only1Star)
sut.fetch()
wait(for: [expectation], timeout: 2)
// THEN
XCTAssertEqual(isLoading, [false, true, false])
XCTAssertEqual(sut.filter, .only1Star)
XCTAssertTrue(sut.isFilterEnabled)
XCTAssertTrue(sut.isWordsShowing)
XCTAssertFalse(sut.items.isEmpty)
@ -194,16 +194,12 @@ final class FeedListViewModelTests: XCTestCase {
var isLoading: [Bool] = []
// GIVEN
sut.filter = .only1Star
MockURLProtocol.response = .init(
statusCode: 200,
object: Feed(entries: .none)
)
// WHEN
sut.fetch()
sut.$isLoading
.collect(3)
.sink { value in
@ -213,10 +209,14 @@ final class FeedListViewModelTests: XCTestCase {
}
.store(in: &cancellables)
sut.filter(by: .only1Star)
sut.fetch()
wait(for: [expectation], timeout: 2)
// THEN
XCTAssertEqual(isLoading, [false, true, false])
XCTAssertEqual(sut.filter, .only1Star)
XCTAssertFalse(sut.isFilterEnabled)
XCTAssertFalse(sut.isWordsShowing)
XCTAssertTrue(sut.items.isEmpty)
@ -231,13 +231,9 @@ final class FeedListViewModelTests: XCTestCase {
var isLoading: [Bool] = []
// GIVEN
sut.filter = .only1Star
MockURLProtocol.response = .init(statusCode: 404)
// WHEN
sut.fetch()
sut.$isLoading
.collect(3)
.sink { value in
@ -247,10 +243,14 @@ final class FeedListViewModelTests: XCTestCase {
}
.store(in: &cancellables)
sut.filter(by: .only1Star)
sut.fetch()
wait(for: [expectation], timeout: 2)
// THEN
XCTAssertEqual(isLoading, [false, true, false])
XCTAssertEqual(sut.filter, .only1Star)
XCTAssertFalse(sut.isFilterEnabled)
XCTAssertFalse(sut.isWordsShowing)
XCTAssertTrue(sut.items.isEmpty)
@ -259,6 +259,145 @@ final class FeedListViewModelTests: XCTestCase {
XCTAssertTrue(sut.words.isEmpty)
}
func test
func testFilter_forNewOption_withSomeItems() {
let expectation = XCTestExpectation()
var filter: [FilterOption] = []
// GIVEN
MockURLProtocol.response = .init(
statusCode: 200,
object: Feed(entries: .sample)
)
// WHEN
sut.$filter
.dropFirst()
.sink { value in
filter.append(value)
expectation.fulfill()
}
.store(in: &cancellables)
sut.fetch()
sut.filter(by: .only1Star)
wait(for: [expectation], timeout: 2)
// THEN
XCTAssertEqual(filter, [.only1Star])
XCTAssertFalse(sut.items.isEmpty)
XCTAssertEqual(sut.items.count, 1)
XCTAssertEqual(sut.itemsCount, 2)
XCTAssertFalse(sut.words.isEmpty)
XCTAssertEqual(sut.words.count, 3)
}
func testFilter_forNewOption_withNoItems() {
let expectation = XCTestExpectation()
var filter: [FilterOption] = []
// GIVEN
MockURLProtocol.response = .init(
statusCode: 200,
object: Feed(entries: .none)
)
// WHEN
sut.$filter
.dropFirst()
.sink { value in
filter.append(value)
expectation.fulfill()
}
.store(in: &cancellables)
sut.fetch()
sut.filter(by: .only1Star)
wait(for: [expectation], timeout: 2)
// THEN
XCTAssertEqual(filter, [.only1Star])
XCTAssertTrue(sut.items.isEmpty)
XCTAssertEqual(sut.items.count, 0)
XCTAssertEqual(sut.itemsCount, 0)
XCTAssertTrue(sut.words.isEmpty)
XCTAssertEqual(sut.words.count, 0)
}
func testFilter_forSameOption_withSomeItems() {
let expectation = XCTestExpectation()
var filter: [FilterOption] = []
// GIVEN
MockURLProtocol.response = .init(
statusCode: 200,
object: Feed(entries: .sample)
)
// WHEN
sut.$filter
.dropFirst()
.sink { value in
filter.append(value)
expectation.fulfill()
}
.store(in: &cancellables)
sut.fetch()
sut.filter(by: .only1Star)
sut.filter(by: .only1Star)
wait(for: [expectation], timeout: 2)
// THEN
XCTAssertEqual(filter, [.only1Star])
XCTAssertFalse(sut.items.isEmpty)
XCTAssertEqual(sut.items.count, 1)
XCTAssertEqual(sut.itemsCount, 2)
XCTAssertFalse(sut.words.isEmpty)
XCTAssertEqual(sut.words.count, 3)
}
func testFilter_forSameOption_withNoItems() {
let expectation = XCTestExpectation()
var filter: [FilterOption] = []
// GIVEN
MockURLProtocol.response = .init(
statusCode: 200,
object: Feed(entries: .none)
)
// WHEN
sut.$filter
.dropFirst()
.sink { value in
filter.append(value)
expectation.fulfill()
}
.store(in: &cancellables)
sut.fetch()
sut.filter(by: .only1Star)
wait(for: [expectation], timeout: 2)
// THEN
XCTAssertEqual(filter, [.only1Star])
XCTAssertTrue(sut.items.isEmpty)
XCTAssertEqual(sut.items.count, 0)
XCTAssertEqual(sut.itemsCount, 0)
XCTAssertTrue(sut.words.isEmpty)
XCTAssertEqual(sut.words.count, 0)
}
}