Skip to content

Commit 00b46c1

Browse files
committed
refactor: TodoDetail 시트 Store 스코프 정리
1 parent 16424fd commit 00b46c1

3 files changed

Lines changed: 62 additions & 19 deletions

File tree

Application/DevLogPresentation/Sources/Home/Detail/TodoDetailFeature.swift

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,33 @@ struct TodoDetailFeature {
2727
struct SheetState: Equatable {
2828
var destination: Destination
2929

30+
var todoDetail: TodoDetailFeature.State? {
31+
get {
32+
guard case .todo(let state) = destination else { return nil }
33+
return state
34+
}
35+
set {
36+
guard let newValue else { return }
37+
destination = .todo(newValue)
38+
}
39+
}
40+
3041
enum Destination: Equatable {
3142
case info
32-
case todo(TodoIdItem)
43+
case todo(TodoDetailFeature.State)
3344
}
3445

3546
static let info = Self(destination: .info)
3647

3748
static func todo(_ todoId: TodoIdItem) -> Self {
38-
Self(destination: .todo(todoId))
49+
Self(
50+
destination: .todo(
51+
TodoDetailFeature.State(
52+
todoId: todoId.id,
53+
showEditButton: false
54+
)
55+
)
56+
)
3957
}
4058
}
4159

@@ -62,8 +80,10 @@ struct TodoDetailFeature {
6280
case setReferenceItems([Int: TodoReferenceItem])
6381
case setLoading(Bool)
6482

65-
enum Sheet: Equatable {
83+
@CasePathable
84+
enum Sheet {
6685
case tapCloseButton
86+
case todo(TodoDetailFeature.Action)
6787
}
6888
}
6989

@@ -107,6 +127,21 @@ struct TodoDetailFeature {
107127
return .none
108128
}
109129
.ifLet(\.$alert, action: \.alert)
130+
.ifLet(\.$sheet, action: \.sheet) {
131+
TodoDetailSheetFeature()
132+
}
133+
}
134+
}
135+
136+
private struct TodoDetailSheetFeature: Reducer {
137+
typealias State = TodoDetailFeature.SheetState
138+
typealias Action = TodoDetailFeature.Action.Sheet
139+
140+
var body: some ReducerOf<Self> {
141+
EmptyReducer()
142+
.ifLet(\.todoDetail, action: \.todo) {
143+
TodoDetailFeature()
144+
}
110145
}
111146
}
112147

Application/DevLogPresentation/Sources/Home/Detail/TodoDetailView.swift

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -118,20 +118,15 @@ struct TodoDetailView: View {
118118
sheetStore.send(.tapCloseButton)
119119
}
120120
}
121-
case .todo(let item):
121+
case .todo:
122122
NavigationStack {
123-
TodoDetailView(store: Store(
124-
initialState: TodoDetailFeature.State(todoId: item.id, showEditButton: false)
125-
) {
126-
TodoDetailFeature()
127-
} withDependencies: {
128-
$0.fetchTodoByIdUseCase = container.resolve(FetchTodoByIdUseCase.self)
129-
$0.fetchReferenceItemsUseCase = container.resolve(FetchReferenceItemsUseCase.self)
130-
})
131-
.toolbar {
132-
ToolbarLeadingButton {
133-
sheetStore.send(.tapCloseButton)
134-
}
123+
if let todoStore = sheetStore.scope(state: \.todoDetail, action: \.todo) {
124+
TodoDetailView(store: todoStore)
125+
.toolbar {
126+
ToolbarLeadingButton {
127+
sheetStore.send(.tapCloseButton)
128+
}
129+
}
135130
}
136131
}
137132
.background(Color(.systemGroupedBackground))

Application/DevLogPresentation/Tests/Home/TodoDetailFeatureTests.swift

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,10 @@ struct TodoDetailFeatureTests {
140140
}
141141

142142
@Test("시트와 편집 화면 상태를 액션에 맞게 변경한다")
143-
func 시트와_편집_화면_상태를_액션에_맞게_변경한다() {
143+
func 시트와_편집_화면_상태를_액션에_맞게_변경한다() async {
144+
let fetchSpy = FetchTodoByIdUseCaseSpy(todo: makeTodo(id: "todo-2"))
144145
let adapter = TodoDetailStoreTestAdapter(
145-
fetchUseCase: FetchTodoByIdUseCaseSpy(todo: makeTodo()),
146+
fetchUseCase: fetchSpy,
146147
referenceUseCase: FetchReferenceItemsUseCaseSpy(),
147148
todoId: "todo-1",
148149
showEditButton: false
@@ -157,7 +158,16 @@ struct TodoDetailFeatureTests {
157158

158159
adapter.setSheet(.todo(TodoIdItem(id: "todo-2")))
159160

160-
#expect(adapter.sheet == .todo(TodoIdItem(id: "todo-2")))
161+
#expect(adapter.sheet?.todoDetail?.todoId == "todo-2")
162+
#expect(adapter.sheet?.todoDetail?.showEditButton == false)
163+
164+
adapter.onSheetTodoAppear()
165+
166+
await waitUntil {
167+
adapter.sheet?.todoDetail?.todo?.id == "todo-2"
168+
}
169+
170+
#expect(fetchSpy.todoIds == ["todo-2"])
161171

162172
adapter.dismissSheet()
163173
adapter.dismissFullScreenCover()
@@ -179,6 +189,7 @@ private protocol TodoDetailTestAdapter {
179189
var fullScreenCover: TodoDetailFeature.FullScreenCoverState? { get }
180190

181191
func onAppear()
192+
func onSheetTodoAppear()
182193
func setSheet(_ sheet: TodoDetailFeature.SheetState?)
183194
func dismissSheet()
184195
func setFullScreenCover(_ cover: TodoDetailFeature.FullScreenCoverState?)
@@ -246,6 +257,8 @@ private struct TodoDetailStoreTestAdapter: TodoDetailTestAdapter {
246257
store.send(.onAppear)
247258
}
248259

260+
func onSheetTodoAppear() { store.send(.sheet(.presented(.todo(.onAppear)))) }
261+
249262
func setSheet(_ sheet: TodoDetailFeature.SheetState?) {
250263
store.send(.setSheet(sheet))
251264
}

0 commit comments

Comments
 (0)