From e1769aa0edb6304bbe1206bb6a3c4009249b2ea0 Mon Sep 17 00:00:00 2001 From: Yusuke Uchida <65172567+ewa1989@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:34:46 +0900 Subject: [PATCH] fix to enable to test favorite filter via Reducer. --- .../Sources/ScheduleFeature/Schedule.swift | 89 +++++++++++-------- .../Sources/SharedModels/Conference.swift | 2 + .../ScheduleFeatureTests/ScheduleTests.swift | 24 +++-- 3 files changed, 68 insertions(+), 47 deletions(-) diff --git a/MyLibrary/Sources/ScheduleFeature/Schedule.swift b/MyLibrary/Sources/ScheduleFeature/Schedule.swift index 649eec3..196f72e 100644 --- a/MyLibrary/Sources/ScheduleFeature/Schedule.swift +++ b/MyLibrary/Sources/ScheduleFeature/Schedule.swift @@ -36,7 +36,37 @@ public struct Schedule { var favorites: Favorites = [:] @Presents var destination: Destination.State? + var day1ToShow: Conference? { + filteredConference(of: .day1) + } + var day2ToShow: Conference? { + filteredConference(of: .day2) + } + var workshopToShow: Conference? { + filteredConference(of: .day3) + } + public init() {} + + func filteredConference(of day: Days) -> Conference? { + let conference = + switch selectedDay { + case .day1: + day1 + case .day2: + day2 + case .day3: + workshop + } + guard let conference = conference else { return nil } + switch selectedFilter { + case .all: + return conference + case .favorite: + let schedules = conference.schedules.filtered(using: favorites, in: conference) + return Conference(id: conference.id, title: conference.title, date: conference.date, schedules: schedules) + } + } } public enum Action: BindableAction, ViewAction { @@ -170,6 +200,21 @@ private extension Favorites { } } +extension [SharedModels.Schedule] { + func filtered(using favorites: Favorites, in conference: Conference) -> Self { + self + .map { + SharedModels.Schedule(time: $0.time, sessions: $0.sessions.filter { + guard let favorites = favorites[conference.title] else { + return false + } + return favorites.contains($0) + }) + } + .filter { $0.sessions.count > 0 } + } +} + @ViewAction(for: Schedule.self) public struct ScheduleView: View { @@ -204,19 +249,19 @@ public struct ScheduleView: View { .padding(.horizontal) switch store.selectedDay { case .day1: - if let day1 = store.day1 { + if let day1 = store.day1ToShow { conferenceList(conference: day1) } else { Text("") } case .day2: - if let day2 = store.day2 { + if let day2 = store.day2ToShow { conferenceList(conference: day2) } else { Text("") } case .day3: - if let workshop = store.workshop { + if let workshop = store.workshopToShow { conferenceList(conference: workshop) } else { Text("") @@ -253,9 +298,8 @@ public struct ScheduleView: View { Text(conference.date, style: .date) .font(.title2) - let schedules = extractFilteredSchedules(from: conference) - if schedules.count > 0 { - ForEach(schedules, id: \.self) { schedule in + if conference.schedules.count > 0 { + ForEach(conference.schedules, id: \.self) { schedule in VStack(alignment: .leading, spacing: 4) { Text(schedule.time, style: .time) .font(.subheadline.bold()) @@ -387,24 +431,6 @@ public struct ScheduleView: View { } } - func extractFilteredSchedules(from conference: Conference) -> [SharedModels.Schedule] { - switch store.selectedFilter { - case .all: - return conference.schedules - case .favorite: - let conference = - switch store.selectedDay { - case .day1: - store.day1! - case .day2: - store.day2! - case .day3: - store.workshop! - } - return conference.schedules.filtered(using: store.favorites, in: conference) - } - } - func officeHourTitle(speakers: [Speaker]) -> String { let names = givenNameList(speakers: speakers) return String(localized: "Office hour \(names)", bundle: .module) @@ -426,21 +452,6 @@ public struct ScheduleView: View { } } -extension [SharedModels.Schedule] { - func filtered(using favorites: Favorites, in conference: Conference) -> Self { - self - .map { - SharedModels.Schedule(time: $0.time, sessions: $0.sessions.filter { - guard let favorites = favorites[conference.title] else { - return false - } - return favorites.contains($0) - }) - } - .filter { $0.sessions.count > 0 } - } -} - #Preview { ScheduleView( store: .init( diff --git a/MyLibrary/Sources/SharedModels/Conference.swift b/MyLibrary/Sources/SharedModels/Conference.swift index 17c470a..460eada 100644 --- a/MyLibrary/Sources/SharedModels/Conference.swift +++ b/MyLibrary/Sources/SharedModels/Conference.swift @@ -1,11 +1,13 @@ import Foundation public struct Conference: Codable, Equatable, Hashable, Sendable { + public var id: Int public var title: String public var date: Date public var schedules: [Schedule] public init(id: Int, title: String, date: Date, schedules: [Schedule]) { + self.id = id self.title = title self.date = date self.schedules = schedules diff --git a/MyLibrary/Tests/ScheduleFeatureTests/ScheduleTests.swift b/MyLibrary/Tests/ScheduleFeatureTests/ScheduleTests.swift index db257cf..9ab6581 100644 --- a/MyLibrary/Tests/ScheduleFeatureTests/ScheduleTests.swift +++ b/MyLibrary/Tests/ScheduleFeatureTests/ScheduleTests.swift @@ -117,14 +117,22 @@ final class ScheduleTests: XCTestCase { }() @MainActor - func testSchedulesFiltered() { - let schedulesWith2Sessions = [Schedule(time: Date(timeIntervalSince1970: 10_000), sessions: [.mock1, .mock2])] - let conference = Conference(id: 1, title: "conference", date: Date(timeIntervalSince1970: 1_000), schedules: schedulesWith2Sessions) - let favoritesMock1Only: Favorites = [conference.title: [.mock1]] - - let actual = schedulesWith2Sessions.filtered(using: favoritesMock1Only, in: conference) - + func testSchedulesFilteredFavoritesOnly() async { + let initialState: ScheduleFeature.Schedule.State = ScheduleTests.selectingDay1ScheduleWithOneFavorite + let store = TestStore(initialState: initialState) { + Schedule() + } let schedulesMock1Only = [Schedule(time: Date(timeIntervalSince1970: 10_000), sessions: [.mock1])] - XCTAssertEqual(actual, schedulesMock1Only) + let expected = Conference( + id: 1, + title: "conference1", + date: Date(timeIntervalSince1970: 1_000), + schedules: schedulesMock1Only + ) + + await store.send(.binding(.set(\.selectedFilter, Schedule.FilterItem.favorite))) { + $0.selectedFilter = .favorite + XCTAssertEqual($0.day1ToShow, expected) + } } }