[Framework] Feed List improvements (#19)
This PR contains the work done to improve the overall implementation of the `FeedListViewModel` view model in the `Feed` framework by utilising unit tests. Reviewed-on: rock-n-code/app-reviews#19 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
This commit was merged in pull request #19.
This commit is contained in:
@@ -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 = [:]
|
||||
@@ -57,50 +57,51 @@ extension FeedListViewController {
|
||||
|
||||
var isWordsShowing: Bool {
|
||||
filter != .all
|
||||
&& !words.isEmpty
|
||||
&& !words.isEmpty
|
||||
}
|
||||
|
||||
// MARK: Functions
|
||||
func fetch() {
|
||||
Task {
|
||||
isFilterEnabled = false
|
||||
isLoading = items.isEmpty
|
||||
func fetch() async {
|
||||
isFilterEnabled = false
|
||||
isLoading = items.isEmpty
|
||||
|
||||
do {
|
||||
let output = try await iTunesService.getReviews(.init(
|
||||
appID: configuration.appID,
|
||||
countryCode: configuration.countryCode
|
||||
))
|
||||
|
||||
reviewsAll = output.reviews.map(Review.init)
|
||||
reviewsFiltered = FilterOption.allCases
|
||||
.reduce(into: FilteredReviews()) { partialResult, option in
|
||||
partialResult[option] = reviewsAll.filter { $0.rating.stars == option.rawValue }
|
||||
}
|
||||
reviewsTopWords = reviewsFiltered
|
||||
.mapValues { reviews in
|
||||
reviews.map(\.comment)
|
||||
.compactMap { try? filterWords($0) }
|
||||
}
|
||||
.mapValues {
|
||||
topWords($0).map(TopWord.init)
|
||||
}
|
||||
do {
|
||||
let output = try await iTunesService.getReviews(.init(
|
||||
appID: configuration.appID,
|
||||
countryCode: configuration.countryCode
|
||||
))
|
||||
|
||||
reviewsAll = output.reviews.map(Review.init)
|
||||
reviewsFiltered = FilterOption.allCases
|
||||
.reduce(into: FilteredReviews()) { partialResult, option in
|
||||
partialResult[option] = reviewsAll.filter { $0.rating.stars == option.rawValue }
|
||||
}
|
||||
reviewsTopWords = reviewsFiltered
|
||||
.mapValues { reviews in
|
||||
reviews.map(\.comment)
|
||||
.compactMap { try? filterWords($0) }
|
||||
}
|
||||
.mapValues {
|
||||
topWords($0).map(TopWord.init)
|
||||
}
|
||||
|
||||
items = filter == .all
|
||||
? reviewsAll
|
||||
: reviewsFiltered[filter] ?? []
|
||||
items = filter == .all
|
||||
? reviewsAll
|
||||
: reviewsFiltered[filter] ?? []
|
||||
words = filter == .all
|
||||
? []
|
||||
: reviewsTopWords[filter] ?? []
|
||||
|
||||
isFilterEnabled = !items.isEmpty
|
||||
state = items.isEmpty
|
||||
? .empty
|
||||
: .populated
|
||||
} catch {
|
||||
items = []
|
||||
state = .error
|
||||
}
|
||||
|
||||
isLoading = false
|
||||
isFilterEnabled = !items.isEmpty
|
||||
state = items.isEmpty
|
||||
? .empty
|
||||
: .populated
|
||||
} catch {
|
||||
items = []
|
||||
state = .error
|
||||
}
|
||||
|
||||
isLoading = false
|
||||
}
|
||||
|
||||
func filter(by option: FilterOption) {
|
||||
@@ -115,16 +116,19 @@ extension FeedListViewController {
|
||||
}
|
||||
|
||||
func item(for index: Int) -> Review? {
|
||||
guard
|
||||
!items.isEmpty,
|
||||
index < items.count
|
||||
else {
|
||||
guard !items.isEmpty else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return isWordsShowing
|
||||
? items[index - 1]
|
||||
: items[index]
|
||||
let indexToUse = isWordsShowing
|
||||
? index - 1
|
||||
: index
|
||||
|
||||
guard indexToUse < items.count else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return items[indexToUse]
|
||||
}
|
||||
|
||||
func openItem(at index: Int) {
|
||||
|
||||
Reference in New Issue
Block a user