From bbadc9a62118e293ab8c566a33b90336140d134d Mon Sep 17 00:00:00 2001 From: opficdev <162981733+opficdev@users.noreply.github.com> Date: Sun, 14 Jun 2026 00:14:09 +0900 Subject: [PATCH 1/2] =?UTF-8?q?chore:=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EA=B3=A0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tuist/ProjectDescriptionHelpers/Project+Packages.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tuist/ProjectDescriptionHelpers/Project+Packages.swift b/Tuist/ProjectDescriptionHelpers/Project+Packages.swift index 3e7f449c..6c9bbdb1 100644 --- a/Tuist/ProjectDescriptionHelpers/Project+Packages.swift +++ b/Tuist/ProjectDescriptionHelpers/Project+Packages.swift @@ -3,19 +3,19 @@ import ProjectDescription public enum DevLogPackages { public static let markdownUIPackage: Package = .package( url: "https://github.com/gonzalezreal/swift-markdown-ui.git", - .upToNextMajor(from: "2.4.1") + .exact("2.4.1") ) public static let swiftCollectionsPackage: Package = .package( url: "https://github.com/apple/swift-collections.git", - .upToNextMajor(from: "1.3.0") + .exact("1.3.0") ) public static let composableArchitecturePackage: Package = .package( url: "https://github.com/pointfreeco/swift-composable-architecture", - .upToNextMinor(from: "1.25.5") + .exact("1.25.5") ) public static let firebasePackage: Package = .package( url: "https://github.com/firebase/firebase-ios-sdk", - .upToNextMajor(from: "11.15.0") + .exact("11.15.0") ) public static let googleSignInPackage: Package = .package( url: "https://github.com/google/GoogleSignIn-iOS", From 6546103a0b9a4b5b72cfff86a3644b774711d10b Mon Sep 17 00:00:00 2001 From: opficdev <162981733+opficdev@users.noreply.github.com> Date: Sun, 14 Jun 2026 00:20:42 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20PushNotificationSettings=20fetch=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EB=B0=98=EC=98=81=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PushNotificationSettingsFeature.swift | 15 +++++---- ...PushNotificationSettingsFeatureTests.swift | 33 ++++++++++--------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/Application/DevLogPresentation/Sources/Settings/PushNotificationSettingsFeature.swift b/Application/DevLogPresentation/Sources/Settings/PushNotificationSettingsFeature.swift index 93e8a4ce..bd45e1f0 100644 --- a/Application/DevLogPresentation/Sources/Settings/PushNotificationSettingsFeature.swift +++ b/Application/DevLogPresentation/Sources/Settings/PushNotificationSettingsFeature.swift @@ -42,6 +42,7 @@ struct PushNotificationSettingsFeature { case binding(BindingAction) case timePicker(PresentationAction) case fetchSettings + case applyFetchedSettings(PushNotificationSettings) case setAlert case tapCustomTime case selectPresetTime(Date) @@ -86,6 +87,13 @@ struct PushNotificationSettingsFeature { break case .fetchSettings: return fetchPushNotificationSettingsEffect() + case .applyFetchedSettings(let settings): + state.pushNotificationEnable = settings.isEnabled + if let hour = settings.scheduledTime.hour, + let minute = settings.scheduledTime.minute, + let date = Calendar.current.date(bySettingHour: hour, minute: minute, second: 0, of: Date()) { + state.viewPushNotificationTime = date + } case .setAlert: state.alert = Self.alertState() case .tapCustomTime: @@ -154,12 +162,7 @@ private extension PushNotificationSettingsFeature { await send(.loading(.begin(target: .default, mode: .delayed))) do { let settings = try await fetchPushSettingsUseCase.execute() - await send(.binding(.set(\.pushNotificationEnable, settings.isEnabled))) - if let hour = settings.scheduledTime.hour, - let minute = settings.scheduledTime.minute, - let date = Calendar.current.date(bySettingHour: hour, minute: minute, second: 0, of: Date()) { - await send(.binding(.set(\.viewPushNotificationTime, date))) - } + await send(.applyFetchedSettings(settings)) await send(.loading(.end(target: .default, mode: .delayed))) } catch { await send(.loading(.end(target: .default, mode: .delayed))) diff --git a/Application/DevLogPresentation/Tests/Settings/PushNotificationSettingsFeatureTests.swift b/Application/DevLogPresentation/Tests/Settings/PushNotificationSettingsFeatureTests.swift index 8eea3e01..63e43082 100644 --- a/Application/DevLogPresentation/Tests/Settings/PushNotificationSettingsFeatureTests.swift +++ b/Application/DevLogPresentation/Tests/Settings/PushNotificationSettingsFeatureTests.swift @@ -19,21 +19,31 @@ struct PushNotificationSettingsFeatureTests { settings: makePushNotificationSettings(isEnabled: true, hour: 9, minute: 0) ) let adapter = PushNotificationSettingsStoreTestAdapter(fetchUseCase: fetchSpy) - await adapter.fetchSettings() - #expect(adapter.pushNotificationEnable) #expect(adapter.pushNotificationHour == 9) #expect(adapter.pushNotificationMinute == 0) #expect(adapter.sheetPushNotificationTime == adapter.viewPushNotificationTime) } + @Test("fetchSettings는 서버 상태 반영 중 설정 업데이트를 다시 호출하지 않는다") + func fetchSettings는_서버_상태_반영_중_설정_업데이트를_다시_호출하지_않는다() async { + let fetchSpy = FetchPushSettingsUseCaseSpy( + settings: makePushNotificationSettings(isEnabled: true, hour: 9, minute: 0) + ) + let updateSpy = UpdatePushSettingsUseCaseSpy() + let adapter = PushNotificationSettingsStoreTestAdapter( + fetchUseCase: fetchSpy, + updateUseCase: updateSpy + ) + await adapter.fetchSettings() + #expect(updateSpy.executeCallCount == 0) + } + @Test("setPushNotificationEnable은 활성화 상태를 변경한다") func setPushNotificationEnable은_활성화_상태를_변경한다() async { let adapter = PushNotificationSettingsStoreTestAdapter() - await adapter.setPushNotificationEnable(true) - #expect(adapter.pushNotificationEnable) } @@ -41,9 +51,7 @@ struct PushNotificationSettingsFeatureTests { func selectPresetTime은_화면과_시트_시간을_함께_변경한다() async { let adapter = PushNotificationSettingsStoreTestAdapter() let date = makeDate(hour: 15, minute: 0) - await adapter.selectPresetTime(date) - #expect(adapter.viewPushNotificationTime == date) #expect(adapter.sheetPushNotificationTime == date) #expect(adapter.pushNotificationHour == 15) @@ -54,10 +62,8 @@ struct PushNotificationSettingsFeatureTests { func setShowTimePicker는_현재_화면_시간으로_시트를_연다() async { let adapter = PushNotificationSettingsStoreTestAdapter() let date = makeDate(hour: 18, minute: 0) - await adapter.setPushNotificationTime(view: date) await adapter.setShowTimePicker(true) - #expect(adapter.showTimePicker) #expect(adapter.sheetPushNotificationTime == date) } @@ -111,10 +117,8 @@ struct PushNotificationSettingsFeatureTests { @Test("setSheetHeight는 시트 높이 상태를 변경한다") func setSheetHeight는_시트_높이_상태를_변경한다() async { let adapter = PushNotificationSettingsStoreTestAdapter() - await adapter.setShowTimePicker(true) await adapter.setSheetHeight(240) - #expect(adapter.sheetHeight == 240) } @@ -345,8 +349,10 @@ private final class FetchPushSettingsUseCaseSpy: FetchPushSettingsUseCase { private final class UpdatePushSettingsUseCaseSpy: UpdatePushSettingsUseCase { var error: Error? + private(set) var executeCallCount = 0 func execute(_: PushNotificationSettings) async throws { + executeCallCount += 1 if let error { self.error = nil throw error @@ -374,12 +380,7 @@ private func makeDate( minute: Int ) -> Date { let baseDate = Date(timeIntervalSince1970: 0) - return Calendar.current.date( - bySettingHour: hour, - minute: minute, - second: 0, - of: baseDate - ) ?? baseDate + return Calendar.current.date(bySettingHour: hour, minute: minute, second: 0, of: baseDate) ?? baseDate } private func expectedPushNotificationSettingsErrorAlert() -> AlertState {