From 15529c0028dbe9de5e6a41c58453d18e9a8ff706 Mon Sep 17 00:00:00 2001 From: Momo Ozawa Date: Thu, 16 May 2024 17:17:29 +0100 Subject: [PATCH 1/9] Add remote config param for flexible interval --- .../Utility/BuildInformation/RemoteConfigParameter.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/WordPress/Classes/Utility/BuildInformation/RemoteConfigParameter.swift b/WordPress/Classes/Utility/BuildInformation/RemoteConfigParameter.swift index 172df6e20fbb..16250dbbec69 100644 --- a/WordPress/Classes/Utility/BuildInformation/RemoteConfigParameter.swift +++ b/WordPress/Classes/Utility/BuildInformation/RemoteConfigParameter.swift @@ -36,6 +36,7 @@ enum RemoteConfigParameter: CaseIterable, RemoteParameter { case phaseFourOverlayFrequency case wordPressInAppUpdateBlockingVersion case jetpackInAppUpdateBlockingVersion + case inAppUpdateFlexibleIntervalInDays var key: String { switch self { @@ -63,6 +64,8 @@ enum RemoteConfigParameter: CaseIterable, RemoteParameter { return "wp_in_app_update_blocking_version_ios" case .jetpackInAppUpdateBlockingVersion: return "jp_in_app_update_blocking_version_ios" + case .inAppUpdateFlexibleIntervalInDays: + return "in_app_update_flexible_interval_in_days_ios" } } @@ -92,6 +95,8 @@ enum RemoteConfigParameter: CaseIterable, RemoteParameter { return nil case .jetpackInAppUpdateBlockingVersion: return nil + case .inAppUpdateFlexibleIntervalInDays: + return nil } } @@ -121,6 +126,8 @@ enum RemoteConfigParameter: CaseIterable, RemoteParameter { return "WP In-App Update Blocking Version" case .jetpackInAppUpdateBlockingVersion: return "JP In-App Update Blocking Version" + case .inAppUpdateFlexibleIntervalInDays: + return "In-App Update Flexible Interval (Days)" } } } From 0487e789a7c31e48d00d4020b1874668819f0259 Mon Sep 17 00:00:00 2001 From: Momo Ozawa Date: Thu, 16 May 2024 17:18:34 +0100 Subject: [PATCH 2/9] Show flexible update after interval has passed --- .../AppUpdate/AppUpdateCoordinator.swift | 48 +++++++++++++++++-- .../AppUpdate/AppUpdatePresenter.swift | 1 - 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift b/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift index 6522cb80e3e1..8869b8a28a21 100644 --- a/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift +++ b/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift @@ -6,12 +6,12 @@ struct AppUpdateType { } final class AppUpdateCoordinator { - private let currentVersion: String? private let currentOsVersion: String private let service: AppStoreSearchProtocol private let presenter: AppUpdatePresenterProtocol private let remoteConfigStore: RemoteConfigStore + private let store: UserPersistentRepository private let isJetpack: Bool private let isLoggedIn: Bool private let isInAppUpdatesEnabled: Bool @@ -23,6 +23,7 @@ final class AppUpdateCoordinator { service: AppStoreSearchProtocol = AppStoreSearchService(), presenter: AppUpdatePresenterProtocol = AppUpdatePresenter(), remoteConfigStore: RemoteConfigStore = RemoteConfigStore(), + store: UserPersistentRepository = UserDefaults.standard, isJetpack: Bool = AppConfiguration.isJetpack, isLoggedIn: Bool = AccountHelper.isLoggedIn, isInAppUpdatesEnabled: Bool = RemoteFeatureFlag.inAppUpdates.enabled(), @@ -33,6 +34,7 @@ final class AppUpdateCoordinator { self.service = service self.presenter = presenter self.remoteConfigStore = remoteConfigStore + self.store = store self.isJetpack = isJetpack self.isLoggedIn = isLoggedIn self.isInAppUpdatesEnabled = isInAppUpdatesEnabled @@ -51,10 +53,12 @@ final class AppUpdateCoordinator { return } + let appStoreInfo = updateType.appStoreInfo if updateType.isRequired { - presenter.showBlockingUpdate(using: updateType.appStoreInfo) + presenter.showBlockingUpdate(using: appStoreInfo) } else { - presenter.showNotice(using: updateType.appStoreInfo) + presenter.showNotice(using: appStoreInfo) + setLastSeenFlexibleUpdateDate(Date.now, for: appStoreInfo.version) } } @@ -76,7 +80,7 @@ final class AppUpdateCoordinator { if let blockingVersion, currentVersion.isLower(than: blockingVersion), blockingVersion.isLowerThanOrEqual(to: appStoreInfo.version) { return AppUpdateType(appStoreInfo: appStoreInfo, isRequired: true) } - if currentVersion.isLower(than: appStoreInfo.version) { + if currentVersion.isLower(than: appStoreInfo.version), shouldShowFlexibleUpdate(for: appStoreInfo.version) { return AppUpdateType(appStoreInfo: appStoreInfo, isRequired: false) } return nil @@ -101,6 +105,42 @@ final class AppUpdateCoordinator { } } +// MARK: - Flexible Interval + +extension AppUpdateCoordinator { + private var flexibleIntervalInDays: Int? { + RemoteConfigParameter.inAppUpdateFlexibleIntervalInDays.value(using: remoteConfigStore) + } + + private func lastSeenFlexibleUpdateKey(for version: String) -> String { + return "\(version)-\(Constants.lastSeenFlexibleUpdateDateKey)" + } + + private func getLastSeenFlexibleUpdateDate(for version: String) -> Date? { + store.object(forKey: lastSeenFlexibleUpdateKey(for: version)) as? Date + } + + private func setLastSeenFlexibleUpdateDate(_ date: Date, for version: String) { + store.set(date, forKey: lastSeenFlexibleUpdateKey(for: version)) + } + + private func shouldShowFlexibleUpdate(for version: String) -> Bool { + guard let flexibleIntervalInDays else { + return false + } + guard let lastSeenFlexibleUpdateDate = getLastSeenFlexibleUpdateDate(for: version) else { + return true + } + let secondsInDay: TimeInterval = 86_400 + let secondsSinceLastSeen = -lastSeenFlexibleUpdateDate.timeIntervalSinceNow + return secondsSinceLastSeen > Double(flexibleIntervalInDays) * secondsInDay + } +} + +private enum Constants { + static let lastSeenFlexibleUpdateDateKey = "last-seen-flexible-update-date-key" +} + private extension String { func isLower(than anotherVersionString: String) -> Bool { self.compare(anotherVersionString, options: .numeric) == .orderedAscending diff --git a/WordPress/Classes/Services/AppUpdate/AppUpdatePresenter.swift b/WordPress/Classes/Services/AppUpdate/AppUpdatePresenter.swift index 959ade8ccdb0..4a684f8ac8fd 100644 --- a/WordPress/Classes/Services/AppUpdate/AppUpdatePresenter.swift +++ b/WordPress/Classes/Services/AppUpdate/AppUpdatePresenter.swift @@ -27,7 +27,6 @@ final class AppUpdatePresenter: AppUpdatePresenterProtocol { } ActionDispatcher.dispatch(NoticeAction.post(notice)) WPAnalytics.track(.inAppUpdateShown, properties: ["type": "flexible"]) - // Todo: if the notice is dismissed, show notice again after a defined interval } func showBlockingUpdate(using appStoreInfo: AppStoreLookupResponse.AppStoreInfo) { From 352fe351cd3b9314be5da1f9433555a998c8f0e6 Mon Sep 17 00:00:00 2001 From: Momo Ozawa Date: Thu, 16 May 2024 19:50:16 +0100 Subject: [PATCH 3/9] Update tests --- .../AppUpdate/AppUpdateCoordinatorTests.swift | 22 ++++++++++++++++++- .../WordPressTest/RemoteConfigStoreMock.swift | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/WordPress/WordPressTest/AppUpdate/AppUpdateCoordinatorTests.swift b/WordPress/WordPressTest/AppUpdate/AppUpdateCoordinatorTests.swift index 8da4a3d4e420..72795cada119 100644 --- a/WordPress/WordPressTest/AppUpdate/AppUpdateCoordinatorTests.swift +++ b/WordPress/WordPressTest/AppUpdate/AppUpdateCoordinatorTests.swift @@ -7,6 +7,12 @@ final class AppUpdateCoordinatorTests: XCTestCase { private let service = MockAppStoreSearchService() private let presenter = MockAppUpdatePresenter() private let remoteConfigStore = RemoteConfigStoreMock() + private var store = UserDefaults(suiteName: "app-update-coordinator-tests")! + + override func tearDown() { + super.tearDown() + store.removePersistentDomain(forName: "app-update-coordinator-tests") + } func testInAppUpdatesDisabled() async { // Given @@ -58,6 +64,7 @@ final class AppUpdateCoordinatorTests: XCTestCase { service: service, presenter: presenter, remoteConfigStore: remoteConfigStore, + store: store, isLoggedIn: false, isInAppUpdatesEnabled: true, delayInDays: Int.max @@ -80,6 +87,7 @@ final class AppUpdateCoordinatorTests: XCTestCase { service: service, presenter: presenter, remoteConfigStore: remoteConfigStore, + store: store, isJetpack: true, isLoggedIn: true, isInAppUpdatesEnabled: true @@ -102,6 +110,7 @@ final class AppUpdateCoordinatorTests: XCTestCase { service: service, presenter: presenter, remoteConfigStore: remoteConfigStore, + store: store, isJetpack: true, isLoggedIn: true, isInAppUpdatesEnabled: true @@ -117,7 +126,7 @@ final class AppUpdateCoordinatorTests: XCTestCase { XCTAssertFalse(presenter.didShowBlockingUpdate) } - func testFlexibleUpdateAvailable() async { + func testFlexibleUpdateAvailableShownOnceWithinInterval() async { // Given let coordinator = AppUpdateCoordinator( currentVersion: "24.6", @@ -125,10 +134,12 @@ final class AppUpdateCoordinatorTests: XCTestCase { service: service, presenter: presenter, remoteConfigStore: remoteConfigStore, + store: store, isJetpack: true, isLoggedIn: true, isInAppUpdatesEnabled: true ) + remoteConfigStore.inAppUpdateFlexibleIntervalInDays = 5 // When await coordinator.checkForAppUpdates() @@ -137,6 +148,15 @@ final class AppUpdateCoordinatorTests: XCTestCase { XCTAssertTrue(service.didLookup) XCTAssertTrue(presenter.didShowNotice) XCTAssertFalse(presenter.didShowBlockingUpdate) + + // When we check for updates again within the flexible interval + presenter.didShowNotice = false // Reset + await coordinator.checkForAppUpdates() + + // Then the flexible notice isn't shown again + XCTAssertTrue(service.didLookup) + XCTAssertFalse(presenter.didShowNotice) + XCTAssertFalse(presenter.didShowBlockingUpdate) } func testBlockingUpdateAvailable() async { diff --git a/WordPress/WordPressTest/RemoteConfigStoreMock.swift b/WordPress/WordPressTest/RemoteConfigStoreMock.swift index ccbdc6bd20cf..ee3c818122bf 100644 --- a/WordPress/WordPressTest/RemoteConfigStoreMock.swift +++ b/WordPress/WordPressTest/RemoteConfigStoreMock.swift @@ -10,6 +10,7 @@ class RemoteConfigStoreMock: RemoteConfigStore { var blazeNonDismissibleStep: String? var blazeFlowCompletedStep: String? var jetpackInAppUpdateBlockingVersion: String? + var inAppUpdateFlexibleIntervalInDays: Int? override func value(for key: String) -> Any? { if key == "phase_three_blog_post" { @@ -33,6 +34,9 @@ class RemoteConfigStoreMock: RemoteConfigStore { if key == "jp_in_app_update_blocking_version_ios" { return jetpackInAppUpdateBlockingVersion } + if key == "in_app_update_flexible_interval_in_days_ios" { + return inAppUpdateFlexibleIntervalInDays + } return super.value(for: key) } } From fd296ad615501c9ddfdf81f349fa85215167da97 Mon Sep 17 00:00:00 2001 From: Momo Ozawa Date: Tue, 21 May 2024 12:49:07 +0100 Subject: [PATCH 4/9] =?UTF-8?q?Don=E2=80=99t=20show=20flexible=20update=20?= =?UTF-8?q?every=20time=20a=20new=20release=20is=20available?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AppUpdate/AppUpdateCoordinator.swift | 32 +++++++++---------- .../AppUpdate/AppUpdateCoordinatorTests.swift | 2 +- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift b/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift index 8869b8a28a21..46ff9e9ef342 100644 --- a/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift +++ b/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift @@ -58,7 +58,7 @@ final class AppUpdateCoordinator { presenter.showBlockingUpdate(using: appStoreInfo) } else { presenter.showNotice(using: appStoreInfo) - setLastSeenFlexibleUpdateDate(Date.now, for: appStoreInfo.version) + lastSeenFlexibleUpdateDate = Date.now } } @@ -80,7 +80,7 @@ final class AppUpdateCoordinator { if let blockingVersion, currentVersion.isLower(than: blockingVersion), blockingVersion.isLowerThanOrEqual(to: appStoreInfo.version) { return AppUpdateType(appStoreInfo: appStoreInfo, isRequired: true) } - if currentVersion.isLower(than: appStoreInfo.version), shouldShowFlexibleUpdate(for: appStoreInfo.version) { + if currentVersion.isLower(than: appStoreInfo.version), shouldShowFlexibleUpdate { return AppUpdateType(appStoreInfo: appStoreInfo, isRequired: false) } return nil @@ -112,28 +112,26 @@ extension AppUpdateCoordinator { RemoteConfigParameter.inAppUpdateFlexibleIntervalInDays.value(using: remoteConfigStore) } - private func lastSeenFlexibleUpdateKey(for version: String) -> String { - return "\(version)-\(Constants.lastSeenFlexibleUpdateDateKey)" - } - - private func getLastSeenFlexibleUpdateDate(for version: String) -> Date? { - store.object(forKey: lastSeenFlexibleUpdateKey(for: version)) as? Date - } - - private func setLastSeenFlexibleUpdateDate(_ date: Date, for version: String) { - store.set(date, forKey: lastSeenFlexibleUpdateKey(for: version)) + private var lastSeenFlexibleUpdateDate: Date? { + get { + store.object(forKey: Constants.lastSeenFlexibleUpdateDateKey) as? Date + } + set { + store.set(newValue, forKey: Constants.lastSeenFlexibleUpdateDateKey) + } } - private func shouldShowFlexibleUpdate(for version: String) -> Bool { + private var shouldShowFlexibleUpdate: Bool { guard let flexibleIntervalInDays else { return false } - guard let lastSeenFlexibleUpdateDate = getLastSeenFlexibleUpdateDate(for: version) else { + guard let lastSeenFlexibleUpdateDate else { return true } - let secondsInDay: TimeInterval = 86_400 - let secondsSinceLastSeen = -lastSeenFlexibleUpdateDate.timeIntervalSinceNow - return secondsSinceLastSeen > Double(flexibleIntervalInDays) * secondsInDay + guard let daysElapsed = Calendar.current.dateComponents([.day], from: lastSeenFlexibleUpdateDate, to: Date.now).day else { + return false + } + return daysElapsed > flexibleIntervalInDays } } diff --git a/WordPress/WordPressTest/AppUpdate/AppUpdateCoordinatorTests.swift b/WordPress/WordPressTest/AppUpdate/AppUpdateCoordinatorTests.swift index 72795cada119..901f0b27775b 100644 --- a/WordPress/WordPressTest/AppUpdate/AppUpdateCoordinatorTests.swift +++ b/WordPress/WordPressTest/AppUpdate/AppUpdateCoordinatorTests.swift @@ -139,7 +139,7 @@ final class AppUpdateCoordinatorTests: XCTestCase { isLoggedIn: true, isInAppUpdatesEnabled: true ) - remoteConfigStore.inAppUpdateFlexibleIntervalInDays = 5 + remoteConfigStore.inAppUpdateFlexibleIntervalInDays = 90 // When await coordinator.checkForAppUpdates() From 1c51fa154460d016edfb1b03828407a993d58865 Mon Sep 17 00:00:00 2001 From: Momo Ozawa Date: Tue, 21 May 2024 12:49:28 +0100 Subject: [PATCH 5/9] Use Calendar API to calculate days elapsed --- .../Classes/Services/AppUpdate/AppStoreSearchService.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/WordPress/Classes/Services/AppUpdate/AppStoreSearchService.swift b/WordPress/Classes/Services/AppUpdate/AppStoreSearchService.swift index 2b69019d1fcb..799844cd282e 100644 --- a/WordPress/Classes/Services/AppUpdate/AppStoreSearchService.swift +++ b/WordPress/Classes/Services/AppUpdate/AppStoreSearchService.swift @@ -13,9 +13,10 @@ struct AppStoreLookupResponse: Decodable { let currentVersionReleaseDate: Date func currentVersionHasBeenReleased(for days: Int) -> Bool { - let secondsInDay: TimeInterval = 86_400 - let secondsSinceRelease = -currentVersionReleaseDate.timeIntervalSinceNow - return secondsSinceRelease > Double(days) * secondsInDay + guard let daysElapsed = Calendar.current.dateComponents([.day], from: currentVersionReleaseDate, to: Date.now).day else { + return false + } + return daysElapsed > days } } } From d9a4e626487be5f25f957cc9592c9d3dd6ff0e62 Mon Sep 17 00:00:00 2001 From: Momo Ozawa Date: Tue, 21 May 2024 12:51:19 +0100 Subject: [PATCH 6/9] Rename app update type --- .../Classes/Services/AppUpdate/AppUpdateCoordinator.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift b/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift index 46ff9e9ef342..6bd44338393c 100644 --- a/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift +++ b/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift @@ -49,7 +49,7 @@ final class AppUpdateCoordinator { guard isLoggedIn else { return } - guard let updateType = await inAppUpdateType else { + guard let updateType = await appUpdateType else { return } @@ -62,7 +62,7 @@ final class AppUpdateCoordinator { } } - private var inAppUpdateType: AppUpdateType? { + private var appUpdateType: AppUpdateType? { get async { guard let currentVersion else { return nil From 843740902a8c81fe6afb39f5d42cf6ae66c6c420 Mon Sep 17 00:00:00 2001 From: Momo Ozawa Date: Tue, 21 May 2024 13:31:22 +0100 Subject: [PATCH 7/9] Fetch app store info once a day --- .../AppUpdate/AppUpdateCoordinator.swift | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift b/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift index 6bd44338393c..9a1290524e11 100644 --- a/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift +++ b/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift @@ -64,7 +64,7 @@ final class AppUpdateCoordinator { private var appUpdateType: AppUpdateType? { get async { - guard let currentVersion else { + guard let currentVersion, shouldFetchAppStoreInfo else { return nil } guard let appStoreInfo = await fetchAppStoreInfo() else { @@ -97,6 +97,7 @@ final class AppUpdateCoordinator { private func fetchAppStoreInfo() async -> AppStoreLookupResponse.AppStoreInfo? { do { let response = try await service.lookup() + lastFetchedAppStoreInfoDate = Date.now return response.results.first { $0.trackId == Int(service.appID) } } catch { DDLogError("Error fetching app store info: \(error)") @@ -105,9 +106,28 @@ final class AppUpdateCoordinator { } } -// MARK: - Flexible Interval +// MARK: - Store extension AppUpdateCoordinator { + private var lastFetchedAppStoreInfoDate: Date? { + get { + store.object(forKey: Constants.lastFetchedAppStoreInfoDateKey) as? Date + } + set { + store.set(newValue, forKey: Constants.lastFetchedAppStoreInfoDateKey) + } + } + + private var shouldFetchAppStoreInfo: Bool { + guard let lastFetchedAppStoreInfoDate else { + return true + } + guard let daysElapsed = Calendar.current.dateComponents([.day], from: lastFetchedAppStoreInfoDate, to: Date.now).day else { + return false + } + return daysElapsed > Constants.lastFetchedAppStoreInfoThresholdInDays + } + private var flexibleIntervalInDays: Int? { RemoteConfigParameter.inAppUpdateFlexibleIntervalInDays.value(using: remoteConfigStore) } @@ -137,6 +157,8 @@ extension AppUpdateCoordinator { private enum Constants { static let lastSeenFlexibleUpdateDateKey = "last-seen-flexible-update-date-key" + static let lastFetchedAppStoreInfoDateKey = "last-fetched-app-store-info-date-key" + static let lastFetchedAppStoreInfoThresholdInDays = 1 } private extension String { From bdf6cdbce759982afd51b88a8905f0e0e9b4f51a Mon Sep 17 00:00:00 2001 From: Momo Ozawa Date: Tue, 21 May 2024 15:24:26 +0100 Subject: [PATCH 8/9] Update tests --- .../AppUpdate/AppUpdateCoordinatorTests.swift | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/WordPress/WordPressTest/AppUpdate/AppUpdateCoordinatorTests.swift b/WordPress/WordPressTest/AppUpdate/AppUpdateCoordinatorTests.swift index 901f0b27775b..5a37e3d9b3ba 100644 --- a/WordPress/WordPressTest/AppUpdate/AppUpdateCoordinatorTests.swift +++ b/WordPress/WordPressTest/AppUpdate/AppUpdateCoordinatorTests.swift @@ -7,11 +7,15 @@ final class AppUpdateCoordinatorTests: XCTestCase { private let service = MockAppStoreSearchService() private let presenter = MockAppUpdatePresenter() private let remoteConfigStore = RemoteConfigStoreMock() - private var store = UserDefaults(suiteName: "app-update-coordinator-tests")! - - override func tearDown() { - super.tearDown() - store.removePersistentDomain(forName: "app-update-coordinator-tests") + private var store: InMemoryUserDefaults! + + override func setUp() { + store = InMemoryUserDefaults() + service.didLookup = false + presenter.didShowNotice = false + presenter.didShowBlockingUpdate = false + presenter.didOpenAppStore = false + super.setUp() } func testInAppUpdatesDisabled() async { @@ -126,7 +130,7 @@ final class AppUpdateCoordinatorTests: XCTestCase { XCTAssertFalse(presenter.didShowBlockingUpdate) } - func testFlexibleUpdateAvailableShownOnceWithinInterval() async { + func testFlexibleUpdateAvailableShownOnce() async { // Given let coordinator = AppUpdateCoordinator( currentVersion: "24.6", @@ -149,12 +153,16 @@ final class AppUpdateCoordinatorTests: XCTestCase { XCTAssertTrue(presenter.didShowNotice) XCTAssertFalse(presenter.didShowBlockingUpdate) - // When we check for updates again within the flexible interval - presenter.didShowNotice = false // Reset + // Reset service and presenter + service.didLookup = false + presenter.didShowNotice = false + + // When we check for updates again await coordinator.checkForAppUpdates() - // Then the flexible notice isn't shown again - XCTAssertTrue(service.didLookup) + // Then the service doesn't fetch the app store info, and the + // presenter doesn't show the flexible notice + XCTAssertFalse(service.didLookup) XCTAssertFalse(presenter.didShowNotice) XCTAssertFalse(presenter.didShowBlockingUpdate) } @@ -167,6 +175,7 @@ final class AppUpdateCoordinatorTests: XCTestCase { service: service, presenter: presenter, remoteConfigStore: remoteConfigStore, + store: store, isJetpack: true, isLoggedIn: true, isInAppUpdatesEnabled: true From bec3387200744a6d88744b8f04445b90eebb323f Mon Sep 17 00:00:00 2001 From: Momo Ozawa Date: Wed, 22 May 2024 09:17:53 +0100 Subject: [PATCH 9/9] Add assertion failure --- WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift b/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift index 9a1290524e11..744f866cab1d 100644 --- a/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift +++ b/WordPress/Classes/Services/AppUpdate/AppUpdateCoordinator.swift @@ -143,6 +143,7 @@ extension AppUpdateCoordinator { private var shouldShowFlexibleUpdate: Bool { guard let flexibleIntervalInDays else { + wpAssertionFailure("Remote config value missing or invalid") return false } guard let lastSeenFlexibleUpdateDate else {