Skip to content

Commit 77b2a57

Browse files
committed
test: HomeFeature에 맞도록 테스트코드 수정
1 parent e981b02 commit 77b2a57

4 files changed

Lines changed: 74 additions & 426 deletions

File tree

Application/DevLogPresentation/Tests/Home/HomeFeatureTestAssertions.swift

Lines changed: 11 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import DevLogDomain
1111
@testable import DevLogPresentation
1212

1313
@MainActor
14-
func verifyHomeFetchData<Adapter: HomeStateDriving>(
15-
adapter: Adapter,
14+
func verifyHomeFetchData(
15+
adapter: HomeStoreTestAdapter,
1616
fetchTodosUseCaseSpy: FetchTodosUseCaseSpy,
1717
fetchWebPagesUseCaseSpy: FetchWebPagesUseCaseSpy
1818
) async throws {
@@ -35,16 +35,16 @@ func verifyHomeFetchData<Adapter: HomeStateDriving>(
3535
}
3636

3737
@MainActor
38-
func verifyHomeWebPageInputAlert<Adapter: HomeStateDriving>(
39-
adapter: Adapter
38+
func verifyHomeWebPageInputAlert(
39+
adapter: HomeStoreTestAdapter
4040
) async throws {
4141
await adapter.setPresentation(.contentPicker, true)
4242

4343
#expect(adapter.showContentPicker)
4444

4545
await adapter.openWebPageInput()
4646

47-
#expect(!adapter.showContentPicker)
47+
#expect(adapter.showContentPicker)
4848
#expect(!adapter.showAlert)
4949

5050
await waitUntil {
@@ -56,25 +56,19 @@ func verifyHomeWebPageInputAlert<Adapter: HomeStateDriving>(
5656
}
5757

5858
@MainActor
59-
func verifyHomeTapTodoCategory<Adapter: HomeStateDriving>(
60-
adapter: Adapter
59+
func verifyHomeTapTodoCategory(
60+
adapter: HomeStoreTestAdapter
6161
) async throws {
6262
await adapter.setPresentation(.contentPicker, true)
6363
await adapter.tapTodoCategory(.system(.feature))
6464

6565
#expect(!adapter.showContentPicker)
66-
#expect(!adapter.showTodoEditor)
67-
68-
await waitUntil {
69-
adapter.showTodoEditor
70-
}
71-
7266
#expect(adapter.showTodoEditor)
7367
}
7468

7569
@MainActor
76-
func verifyHomeOrderTodoCategory<Adapter: HomeStateDriving>(
77-
adapter: Adapter,
70+
func verifyHomeOrderTodoCategory(
71+
adapter: HomeStoreTestAdapter,
7872
updatePreferencesUseCaseSpy: UpdateTodoCategoryPreferencesUseCaseSpy
7973
) async throws {
8074
await adapter.fetchData()
@@ -101,8 +95,8 @@ func verifyHomeOrderTodoCategory<Adapter: HomeStateDriving>(
10195
}
10296

10397
@MainActor
104-
func verifyHomeAddWebPage<Adapter: HomeStateDriving>(
105-
adapter: Adapter,
98+
func verifyHomeAddWebPage(
99+
adapter: HomeStoreTestAdapter,
106100
addWebPageUseCaseSpy: AddWebPageUseCaseSpy,
107101
fetchWebPagesUseCaseSpy: FetchWebPagesUseCaseSpy,
108102
trackAnalyticsEventUseCaseSpy: HomeTrackAnalyticsEventUseCaseSpy
@@ -125,38 +119,6 @@ func verifyHomeAddWebPage<Adapter: HomeStateDriving>(
125119
#expect(!adapter.showAlert)
126120
}
127121

128-
@MainActor
129-
func verifyHomeDeleteUndoWebPage<Adapter: HomeStateDriving>(
130-
adapter: Adapter,
131-
deleteWebPageUseCaseSpy: DeleteWebPageUseCaseSpy,
132-
undoDeleteWebPageUseCaseSpy: UndoDeleteWebPageUseCaseSpy
133-
) async throws {
134-
await adapter.fetchData()
135-
136-
let page = try #require(adapter.webPages.first)
137-
138-
await adapter.deleteWebPage(page)
139-
140-
#expect(adapter.webPages.first?.isHidden == true)
141-
142-
await waitUntil {
143-
deleteWebPageUseCaseSpy.calledUrlStrings == [page.url.absoluteString]
144-
}
145-
146-
await adapter.undoDeleteWebPage()
147-
148-
await waitUntil {
149-
undoDeleteWebPageUseCaseSpy.calledUrlStrings == [page.url.absoluteString]
150-
}
151-
152-
#expect(adapter.webPages.first?.isHidden == false)
153-
154-
await adapter.deleteWebPage(page)
155-
await adapter.finishDeleteWebPageToast(page.url.absoluteString)
156-
157-
#expect(adapter.webPages.isEmpty)
158-
}
159-
160122
struct HomeFetchDataContext {
161123
let fetchPreferencesUseCaseSpy: FetchTodoCategoryPreferencesUseCaseSpy
162124
let fetchTodosUseCaseSpy: FetchTodosUseCaseSpy

Application/DevLogPresentation/Tests/Home/HomeFeatureTestSupport.swift

Lines changed: 14 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -11,125 +11,12 @@ import ComposableArchitecture
1111
import DevLogCore
1212
import DevLogDomain
1313
@testable import DevLogPresentation
14+
import Foundation
1415

1516
@MainActor
16-
protocol HomeStateDriving {
17-
var preferences: [TodoCategoryItem] { get }
18-
var recentTodos: [RecentTodoItem] { get }
19-
var webPages: [WebPageItem] { get }
20-
var isNetworkConnected: Bool { get }
21-
var showContentPicker: Bool { get }
22-
var showWebPageInputNavigation: Bool { get }
23-
var showTodoEditor: Bool { get }
24-
var showAlert: Bool { get }
25-
var alertType: HomeFeature.AlertType? { get }
26-
var alertTitle: String { get }
27-
var webPageURLInput: String { get }
28-
29-
func startObserving() async
30-
func fetchData() async
31-
func openWebPageInput() async
32-
func setPresentation(_ presentation: HomeFeature.Presentation, _ isPresented: Bool) async
33-
func setAlert(isPresented: Bool, type: HomeFeature.AlertType?) async
34-
func tapTodoCategory(_ category: TodoCategory) async
35-
func orderTodoCategory(_ items: [TodoCategoryItem]) async
36-
func updateWebPageURLInput(_ input: String) async
37-
func addWebPage() async
38-
func deleteWebPage(_ page: WebPageItem) async
39-
func undoDeleteWebPage() async
40-
func finishDeleteWebPageToast(_ urlString: String) async
41-
}
42-
43-
@MainActor
44-
struct HomeViewModelTestAdapter: HomeStateDriving {
45-
private let viewModel: HomeViewModel
46-
47-
var preferences: [TodoCategoryItem] { viewModel.state.preferences }
48-
var recentTodos: [RecentTodoItem] { viewModel.state.recentTodos }
49-
var webPages: [WebPageItem] { viewModel.state.webPages }
50-
var isNetworkConnected: Bool { viewModel.state.isNetworkConnected }
51-
var showContentPicker: Bool { viewModel.state.showContentPicker }
52-
var showWebPageInputNavigation: Bool { false }
53-
var showTodoEditor: Bool { viewModel.state.showTodoEditor }
54-
var showAlert: Bool { viewModel.state.showAlert }
55-
var alertType: HomeFeature.AlertType? { viewModel.state.alertType?.featureValue }
56-
var alertTitle: String { viewModel.state.alertTitle }
57-
var webPageURLInput: String { viewModel.state.webPageURLInput }
58-
59-
init(
60-
fetchPreferencesUseCase: FetchTodoCategoryPreferencesUseCase = FetchTodoCategoryPreferencesUseCaseSpy(),
61-
updatePreferencesUseCase: UpdateTodoCategoryPreferencesUseCase = UpdateTodoCategoryPreferencesUseCaseSpy(),
62-
addWebPageUseCase: AddWebPageUseCase = AddWebPageUseCaseSpy(),
63-
deleteWebPageUseCase: DeleteWebPageUseCase = DeleteWebPageUseCaseSpy(),
64-
undoDeleteWebPageUseCase: UndoDeleteWebPageUseCase = UndoDeleteWebPageUseCaseSpy(),
65-
fetchTodosUseCase: FetchTodosUseCase = FetchTodosUseCaseSpy(),
66-
fetchWebPagesUseCase: FetchWebPagesUseCase = FetchWebPagesUseCaseSpy(webPages: []),
67-
networkConnectivityUseCase: ObserveNetworkConnectivityUseCase = ObserveNetworkConnectivityUseCaseSpy(),
68-
trackAnalyticsEventUseCase: TrackAnalyticsEventUseCase = HomeTrackAnalyticsEventUseCaseSpy()
69-
) {
70-
viewModel = HomeViewModel(
71-
fetchPreferencesUseCase: fetchPreferencesUseCase,
72-
updatePreferencesUseCase: updatePreferencesUseCase,
73-
addWebPageUseCase: addWebPageUseCase,
74-
deleteWebPageUseCase: deleteWebPageUseCase,
75-
undoDeleteWebPageUseCase: undoDeleteWebPageUseCase,
76-
fetchTodosUseCase: fetchTodosUseCase,
77-
fetchWebPagesUseCase: fetchWebPagesUseCase,
78-
networkConnectivityUseCase: networkConnectivityUseCase,
79-
trackAnalyticsEventUseCase: trackAnalyticsEventUseCase
80-
)
81-
}
82-
83-
func startObserving() async { }
84-
85-
func fetchData() async {
86-
viewModel.send(.fetchData)
87-
}
88-
89-
func openWebPageInput() async {
90-
viewModel.send(.setAlert(isPresented: true, type: .webPageInput))
91-
}
92-
93-
func setPresentation(_ presentation: HomeFeature.Presentation, _ isPresented: Bool) async {
94-
viewModel.send(.setPresentation(presentation.viewModelValue, isPresented))
95-
}
96-
97-
func setAlert(isPresented: Bool, type: HomeFeature.AlertType?) async {
98-
viewModel.send(.setAlert(isPresented: isPresented, type: type?.viewModelValue))
99-
}
100-
101-
func tapTodoCategory(_ category: TodoCategory) async {
102-
viewModel.send(.tapTodoCategory(category))
103-
}
104-
105-
func orderTodoCategory(_ items: [TodoCategoryItem]) async {
106-
viewModel.send(.orderTodoCategory(items))
107-
}
108-
109-
func updateWebPageURLInput(_ input: String) async {
110-
viewModel.send(.updateWebPageURLInput(input))
111-
}
112-
113-
func addWebPage() async {
114-
viewModel.send(.addWebPage)
115-
}
116-
117-
func deleteWebPage(_ page: WebPageItem) async {
118-
viewModel.send(.deleteWebPage(page))
119-
}
120-
121-
func undoDeleteWebPage() async {
122-
viewModel.send(.undoDeleteWebPage)
123-
}
124-
125-
func finishDeleteWebPageToast(_ urlString: String) async {
126-
viewModel.send(.finishDeleteWebPageToast(urlString))
127-
}
128-
}
129-
130-
@MainActor
131-
struct HomeStoreTestAdapter: HomeStateDriving {
17+
struct HomeStoreTestAdapter {
13218
private let store: TestStoreOf<HomeFeature>
19+
private let clock: TestClock<Duration>
13320

13421
var preferences: [TodoCategoryItem] { store.state.preferences }
13522
var recentTodos: [RecentTodoItem] { store.state.recentTodos }
@@ -171,6 +58,8 @@ struct HomeStoreTestAdapter: HomeStateDriving {
17158
trackAnalyticsEventUseCase: TrackAnalyticsEventUseCase? = HomeTrackAnalyticsEventUseCaseSpy(),
17259
configureDependencies: ((inout DependencyValues) -> Void)? = nil
17360
) {
61+
let clock = TestClock()
62+
self.clock = clock
17463
store = TestStore(initialState: HomeFeature.State()) {
17564
HomeFeature()
17665
} withDependencies: {
@@ -183,7 +72,7 @@ struct HomeStoreTestAdapter: HomeStateDriving {
18372
$0.homeFetchWebPagesUseCase = fetchWebPagesUseCase
18473
$0.networkConnectivityUseCase = networkConnectivityUseCase
18574
$0.trackAnalyticsEventUseCase = trackAnalyticsEventUseCase
186-
$0.continuousClock = ContinuousClock()
75+
$0.continuousClock = clock
18776
configureDependencies?(&$0)
18877
}
18978
store.exhaustivity = .off(showSkippedAssertions: false)
@@ -215,7 +104,8 @@ struct HomeStoreTestAdapter: HomeStateDriving {
215104

216105
func tapTodoCategory(_ category: TodoCategory) async {
217106
await store.send(.tapTodoCategory(category))
218-
await drainReceivedActions()
107+
await clock.advance(by: .seconds(1))
108+
await settle()
219109
}
220110

221111
func orderTodoCategory(_ items: [TodoCategoryItem]) async {
@@ -246,11 +136,16 @@ struct HomeStoreTestAdapter: HomeStateDriving {
246136
await store.send(.finishDeleteWebPageToast(urlString))
247137
}
248138

249-
private func drainReceivedActions() async {
139+
func drainReceivedActions() async {
250140
for _ in 0..<12 {
251141
await store.skipReceivedActions(strict: false)
252142
}
253143
}
144+
145+
func settle() async {
146+
await Task.yield()
147+
await drainReceivedActions()
148+
}
254149
}
255150

256151
final class HomeTrackAnalyticsEventUseCaseSpy: TrackAnalyticsEventUseCase {
@@ -301,38 +196,3 @@ func makeHomeWebPage(
301196
imageURL: nil
302197
)
303198
}
304-
305-
private extension HomeViewModel.AlertType {
306-
var featureValue: HomeFeature.AlertType {
307-
switch self {
308-
case .invalidURL:
309-
return .invalidURL
310-
case .error:
311-
return .error
312-
}
313-
}
314-
}
315-
316-
private extension HomeFeature.AlertType {
317-
var viewModelValue: HomeViewModel.AlertType {
318-
switch self {
319-
case .invalidURL:
320-
return .invalidURL
321-
case .error:
322-
return .error
323-
}
324-
}
325-
}
326-
327-
private extension HomeFeature.Presentation {
328-
var viewModelValue: HomeViewModel.Presentation {
329-
switch self {
330-
case .todoEditor:
331-
return .todoEditor
332-
case .contentPicker:
333-
return .contentPicker
334-
case .searchView:
335-
return .searchView
336-
}
337-
}
338-
}

0 commit comments

Comments
 (0)