From 84c60818e87413466ddfa1532820afd7a87a04dc Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Fri, 8 Sep 2023 16:00:35 +0300 Subject: [PATCH 1/6] Remove widget-related feature flags --- .../Utility/BuildInformation/FeatureFlag.swift | 14 -------------- ...reenAllTimePostsBestViewsStatWidgetConfig.swift | 7 ------- .../LockScreenAllTimeViewsStatWidgetConfig.swift | 7 ------- ...creenAllTimeViewsVisitorsStatWidgetConfig.swift | 7 ------- .../Configs/LockScreenStatsWidgetConfig.swift | 10 ++++++++++ ...kScreenTodayLikesCommentsStatWidgetConfig.swift | 7 ------- .../LockScreenTodayViewsStatWidgetConfig.swift | 7 ------- ...kScreenTodayViewsVisitorsStatWidgetConfig.swift | 7 ------- .../Widgets/HomeWidgetAllTime.swift | 2 +- .../Widgets/HomeWidgetThisWeek.swift | 2 +- .../Widgets/HomeWidgetToday.swift | 2 +- 11 files changed, 13 insertions(+), 59 deletions(-) diff --git a/WordPress/Classes/Utility/BuildInformation/FeatureFlag.swift b/WordPress/Classes/Utility/BuildInformation/FeatureFlag.swift index f391dbacba29..cc4f0297f416 100644 --- a/WordPress/Classes/Utility/BuildInformation/FeatureFlag.swift +++ b/WordPress/Classes/Utility/BuildInformation/FeatureFlag.swift @@ -9,8 +9,6 @@ enum FeatureFlag: Int, CaseIterable { case readerCSS case homepageSettings case unifiedPrologueCarousel - case todayWidget - case lockScreenWidget case milestoneNotifications case bloggingReminders case siteIconCreator @@ -67,10 +65,6 @@ enum FeatureFlag: Int, CaseIterable { return true case .unifiedPrologueCarousel: return true - case .todayWidget: - return true - case .lockScreenWidget: - return false case .milestoneNotifications: return true case .bloggingReminders: @@ -179,10 +173,6 @@ extension FeatureFlag { return "Homepage Settings" case .unifiedPrologueCarousel: return "Unified Prologue Carousel" - case .todayWidget: - return "iOS 14 Today Widget" - case .lockScreenWidget: - return "iOS 16 Widget in Lock Screen" case .milestoneNotifications: return "Milestone notifications" case .bloggingReminders: @@ -265,10 +255,6 @@ extension FeatureFlag: OverridableFlag { switch self { case .debugMenu: return false - case .todayWidget: - return false - case .lockScreenWidget: - return false case .weeklyRoundup: return false case .weeklyRoundupStaticNotification: diff --git a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenAllTimePostsBestViewsStatWidgetConfig.swift b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenAllTimePostsBestViewsStatWidgetConfig.swift index fba6b1e1273f..732676ad0f8d 100644 --- a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenAllTimePostsBestViewsStatWidgetConfig.swift +++ b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenAllTimePostsBestViewsStatWidgetConfig.swift @@ -5,13 +5,6 @@ struct LockScreenAllTimePostsBestViewsStatWidgetConfig: LockScreenStatsWidgetCon typealias WidgetData = HomeWidgetAllTimeData typealias ViewProvider = LockScreenMultiStatWidgetViewProvider - var supportFamilies: [WidgetFamily] { - guard AppConfiguration.isJetpack, FeatureFlag.lockScreenWidget.enabled else { - return [] - } - return [.accessoryRectangular] - } - var displayName: String { LocalizableStrings.allTimePostMostViewsWidgetPreviewTitle } diff --git a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenAllTimeViewsStatWidgetConfig.swift b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenAllTimeViewsStatWidgetConfig.swift index e2ea1dedee90..0fc38ce0c383 100644 --- a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenAllTimeViewsStatWidgetConfig.swift +++ b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenAllTimeViewsStatWidgetConfig.swift @@ -5,13 +5,6 @@ struct LockScreenAllTimeViewsStatWidgetConfig: LockScreenStatsWidgetConfig { typealias WidgetData = HomeWidgetAllTimeData typealias ViewProvider = LockScreenSingleStatWidgetViewProvider - var supportFamilies: [WidgetFamily] { - guard AppConfiguration.isJetpack, FeatureFlag.lockScreenWidget.enabled else { - return [] - } - return [.accessoryRectangular] - } - var displayName: String { LocalizableStrings.allTimeViewsWidgetPreviewTitle } diff --git a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenAllTimeViewsVisitorsStatWidgetConfig.swift b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenAllTimeViewsVisitorsStatWidgetConfig.swift index 349423efcfcd..d04b549ca3a0 100644 --- a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenAllTimeViewsVisitorsStatWidgetConfig.swift +++ b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenAllTimeViewsVisitorsStatWidgetConfig.swift @@ -5,13 +5,6 @@ struct LockScreenAllTimeViewsVisitorsStatWidgetConfig: LockScreenStatsWidgetConf typealias WidgetData = HomeWidgetAllTimeData typealias ViewProvider = LockScreenMultiStatWidgetViewProvider - var supportFamilies: [WidgetFamily] { - guard AppConfiguration.isJetpack, FeatureFlag.lockScreenWidget.enabled else { - return [] - } - return [.accessoryRectangular] - } - var displayName: String { LocalizableStrings.allTimeViewsVisitorsWidgetPreviewTitle } diff --git a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenStatsWidgetConfig.swift b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenStatsWidgetConfig.swift index f7f764b8a68e..ed7605d08582 100644 --- a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenStatsWidgetConfig.swift +++ b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenStatsWidgetConfig.swift @@ -12,3 +12,13 @@ protocol LockScreenStatsWidgetConfig { var placeholderContent: WidgetData { get } var viewProvider: ViewProvider { get } } + +extension LockScreenStatsWidgetConfig { + var supportFamilies: [WidgetFamily] { + if #available(iOSApplicationExtension 16.0, *) { + return [.accessoryRectangular] + } else { + return [] + } + } +} diff --git a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayLikesCommentsStatWidgetConfig.swift b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayLikesCommentsStatWidgetConfig.swift index 64c4d26e7dae..22478081a0b2 100644 --- a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayLikesCommentsStatWidgetConfig.swift +++ b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayLikesCommentsStatWidgetConfig.swift @@ -5,13 +5,6 @@ struct LockScreenTodayLikesCommentsStatWidgetConfig: LockScreenStatsWidgetConfig typealias WidgetData = HomeWidgetTodayData typealias ViewProvider = LockScreenMultiStatWidgetViewProvider - var supportFamilies: [WidgetFamily] { - guard AppConfiguration.isJetpack, FeatureFlag.lockScreenWidget.enabled else { - return [] - } - return [.accessoryRectangular] - } - var displayName: String { LocalizableStrings.todayLikesCommentsWidgetPreviewTitle } diff --git a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayViewsStatWidgetConfig.swift b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayViewsStatWidgetConfig.swift index c3807b61b1de..292be01f51bc 100644 --- a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayViewsStatWidgetConfig.swift +++ b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayViewsStatWidgetConfig.swift @@ -5,13 +5,6 @@ struct LockScreenTodayViewsStatWidgetConfig: LockScreenStatsWidgetConfig { typealias WidgetData = HomeWidgetTodayData typealias ViewProvider = LockScreenSingleStatWidgetViewProvider - var supportFamilies: [WidgetFamily] { - guard AppConfiguration.isJetpack, FeatureFlag.lockScreenWidget.enabled else { - return [] - } - return [.accessoryRectangular] - } - var displayName: String { LocalizableStrings.todayViewsWidgetPreviewTitle } diff --git a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayViewsVisitorsStatWidgetConfig.swift b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayViewsVisitorsStatWidgetConfig.swift index 7222e839216b..fce0e1cd182c 100644 --- a/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayViewsVisitorsStatWidgetConfig.swift +++ b/WordPress/JetpackStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayViewsVisitorsStatWidgetConfig.swift @@ -5,13 +5,6 @@ struct LockScreenTodayViewsVisitorsStatWidgetConfig: LockScreenStatsWidgetConfig typealias WidgetData = HomeWidgetTodayData typealias ViewProvider = LockScreenMultiStatWidgetViewProvider - var supportFamilies: [WidgetFamily] { - guard AppConfiguration.isJetpack, FeatureFlag.lockScreenWidget.enabled else { - return [] - } - return [.accessoryRectangular] - } - var displayName: String { LocalizableStrings.todayViewsVisitorsWidgetPreviewTitle } diff --git a/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetAllTime.swift b/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetAllTime.swift index 6c25f42d5a8f..42d3c3ff54c5 100644 --- a/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetAllTime.swift +++ b/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetAllTime.swift @@ -33,6 +33,6 @@ struct HomeWidgetAllTime: Widget { } .configurationDisplayName(LocalizableStrings.allTimeWidgetTitle) .description(LocalizableStrings.allTimePreviewDescription) - .supportedFamilies(FeatureFlag.todayWidget.enabled ? [.systemSmall, .systemMedium] : []) + .supportedFamilies([.systemSmall, .systemMedium]) } } diff --git a/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetThisWeek.swift b/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetThisWeek.swift index c0a921790419..dfa46107abd7 100644 --- a/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetThisWeek.swift +++ b/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetThisWeek.swift @@ -53,6 +53,6 @@ struct HomeWidgetThisWeek: Widget { } .configurationDisplayName(LocalizableStrings.thisWeekWidgetTitle) .description(LocalizableStrings.thisWeekPreviewDescription) - .supportedFamilies(FeatureFlag.todayWidget.enabled ? [.systemMedium, .systemLarge] : []) + .supportedFamilies([.systemMedium, .systemLarge]) } } diff --git a/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetToday.swift b/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetToday.swift index 782ff6226448..8f8643725e05 100644 --- a/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetToday.swift +++ b/WordPress/JetpackStatsWidgets/Widgets/HomeWidgetToday.swift @@ -34,6 +34,6 @@ struct HomeWidgetToday: Widget { } .configurationDisplayName(LocalizableStrings.todayWidgetTitle) .description(LocalizableStrings.todayPreviewDescription) - .supportedFamilies(FeatureFlag.todayWidget.enabled ? [.systemSmall, .systemMedium] : []) + .supportedFamilies([.systemSmall, .systemMedium]) } } From afc48fcf5bb6043756bf7b76c7e2ed787a1a8af6 Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Fri, 8 Sep 2023 16:15:30 +0300 Subject: [PATCH 2/6] Update RELEASE-NOTES.txt --- RELEASE-NOTES.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 4735844425e5..83fba4faf5bf 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -1,6 +1,7 @@ 23.3 ----- +* [***] [Jetpack-only] Lock Screen Widgets are now available on Jetpack. Quickly view your site stats without unlocking your phone. [#21535] 23.2 ----- From 81ce636ce945c7071d6ee0c7fc77d76d7d7cfb39 Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Thu, 14 Sep 2023 13:34:53 +0300 Subject: [PATCH 3/6] Store Credentials to keychain so widgets could update information by themselves After removing iOS13 today widget-related code, we also removed a commonly reused credential storing functionality. Re-adding it to StatsWidgetsStore --- .../Classes/Stores/StatsWidgetsStore.swift | 19 +++++++++++++++++++ WordPress/Classes/Utility/AccountHelper.swift | 6 ++++++ 2 files changed, 25 insertions(+) diff --git a/WordPress/Classes/Stores/StatsWidgetsStore.swift b/WordPress/Classes/Stores/StatsWidgetsStore.swift index cfe9b2bbac47..0f8c7cb2974c 100644 --- a/WordPress/Classes/Stores/StatsWidgetsStore.swift +++ b/WordPress/Classes/Stores/StatsWidgetsStore.swift @@ -36,6 +36,7 @@ class StatsWidgetsStore { /// Initialize the local cache for widgets, if it does not exist @objc func initializeStatsWidgetsIfNeeded() { UserDefaults(suiteName: WPAppGroupName)?.setValue(AccountHelper.defaultSiteId, forKey: AppConfiguration.Widget.Stats.userDefaultsSiteIdKey) + storeCredentials() if !HomeWidgetTodayData.cacheDataExists() { DDLogInfo("StatsWidgets: Writing initialization data into HomeWidgetTodayData.plist") @@ -319,6 +320,24 @@ private extension StatsWidgetsStore { } } +private extension StatsWidgetsStore { + func storeCredentials() { + guard let token = AccountHelper.authToken else { return } + + do { + try SFHFKeychainUtils.storeUsername( + AppConfiguration.Widget.Stats.keychainTokenKey, + andPassword: token, + forServiceName: AppConfiguration.Widget.Stats.keychainServiceName, + accessGroup: WPAppKeychainAccessGroup, + updateExisting: true + ) + } catch { + DDLogDebug("Error while saving Widgets OAuth token: \(error)") + } + } +} + extension StatsViewController { @objc func initializeStatsWidgetsIfNeeded() { diff --git a/WordPress/Classes/Utility/AccountHelper.swift b/WordPress/Classes/Utility/AccountHelper.swift index 4493fd8c99d6..47548faa89e1 100644 --- a/WordPress/Classes/Utility/AccountHelper.swift +++ b/WordPress/Classes/Utility/AccountHelper.swift @@ -43,6 +43,12 @@ import Foundation return account?.defaultBlog?.dotComID } + static var authToken: String? { + let context = ContextManager.sharedInstance().mainContext + let account = try? WPAccount.lookupDefaultWordPressComAccount(in: context) + return account?.authToken + } + static func logBlogsAndAccounts(context: NSManagedObjectContext) { let allBlogs = (try? BlogQuery().blogs(in: context)) ?? [] let blogsByAccount = Dictionary(grouping: allBlogs, by: { $0.account }) From 92c232a40fdcf934bec341f1d239f452255af839 Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Fri, 15 Sep 2023 11:50:34 +0300 Subject: [PATCH 4/6] Reload all timelines after login/logout When using WidgetBundle and dealing with account state changes Apple recommends using reloadAllTimelines() https://developer.apple.com/documentation/widgetkit/keeping-a-widget-up-to-date --- .../Classes/Stores/StatsWidgetsStore.swift | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/WordPress/Classes/Stores/StatsWidgetsStore.swift b/WordPress/Classes/Stores/StatsWidgetsStore.swift index 0f8c7cb2974c..a358b4af6418 100644 --- a/WordPress/Classes/Stores/StatsWidgetsStore.swift +++ b/WordPress/Classes/Stores/StatsWidgetsStore.swift @@ -38,22 +38,28 @@ class StatsWidgetsStore { UserDefaults(suiteName: WPAppGroupName)?.setValue(AccountHelper.defaultSiteId, forKey: AppConfiguration.Widget.Stats.userDefaultsSiteIdKey) storeCredentials() + var isReloadRequired = false + if !HomeWidgetTodayData.cacheDataExists() { DDLogInfo("StatsWidgets: Writing initialization data into HomeWidgetTodayData.plist") HomeWidgetTodayData.write(items: initializeHomeWidgetData(type: HomeWidgetTodayData.self)) - WidgetCenter.shared.reloadTodayTimelines() + isReloadRequired = true } if !HomeWidgetThisWeekData.cacheDataExists() { DDLogInfo("StatsWidgets: Writing initialization data into HomeWidgetThisWeekData.plist") HomeWidgetThisWeekData.write(items: initializeHomeWidgetData(type: HomeWidgetThisWeekData.self)) - WidgetCenter.shared.reloadThisWeekTimelines() + isReloadRequired = true } if !HomeWidgetAllTimeData.cacheDataExists() { DDLogInfo("StatsWidgets: Writing initialization data into HomeWidgetAllTimeData.plist") HomeWidgetAllTimeData.write(items: initializeHomeWidgetData(type: HomeWidgetAllTimeData.self)) - WidgetCenter.shared.reloadAllTimeTimelines() + isReloadRequired = true + } + + if isReloadRequired { + WidgetCenter.shared.reloadAllTimelines() } } @@ -274,9 +280,8 @@ private extension StatsWidgetsStore { HomeWidgetAllTimeData.delete() userDefaults?.setValue(nil, forKey: AppConfiguration.Widget.Stats.userDefaultsSiteIdKey) - WidgetCenter.shared.reloadTodayTimelines() - WidgetCenter.shared.reloadThisWeekTimelines() - WidgetCenter.shared.reloadAllTimeTimelines() + + WidgetCenter.shared.reloadAllTimelines() } /// Observes WPSigninDidFinishNotification and wordpressLoginFinishedJetpackLogin notifications and initializes the widget. From 3d30474c5b74e3d364a3152403b83f65dcf8085d Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Fri, 15 Sep 2023 15:54:31 +0300 Subject: [PATCH 5/6] Update WidgetDataReader to handle the case with no default site - In rare cases with no default site, simply show the first site in the data - Restructured WidgetDataReader to only use a single method for snapshot and timeline for consistent data loading logic --- .../Classes/Stores/StatsWidgetsStore.swift | 1 + .../Helpers/HomeWidgetDataFileReader.swift | 4 ++ .../Helpers/WidgetDataReader.swift | 38 ++++++++----------- .../LockScreenSiteListProvider.swift | 11 ++++-- .../SiteListProvider.swift | 12 +++--- .../Widgets/WidgetDataReaderTests.swift | 34 +++++++++++++---- 6 files changed, 61 insertions(+), 39 deletions(-) diff --git a/WordPress/Classes/Stores/StatsWidgetsStore.swift b/WordPress/Classes/Stores/StatsWidgetsStore.swift index a358b4af6418..0e5279dcd4e8 100644 --- a/WordPress/Classes/Stores/StatsWidgetsStore.swift +++ b/WordPress/Classes/Stores/StatsWidgetsStore.swift @@ -35,6 +35,7 @@ class StatsWidgetsStore { /// Initialize the local cache for widgets, if it does not exist @objc func initializeStatsWidgetsIfNeeded() { + UserDefaults(suiteName: WPAppGroupName)?.setValue(AccountHelper.isLoggedIn, forKey: AppConfiguration.Widget.Stats.userDefaultsLoggedInKey) UserDefaults(suiteName: WPAppGroupName)?.setValue(AccountHelper.defaultSiteId, forKey: AppConfiguration.Widget.Stats.userDefaultsSiteIdKey) storeCredentials() diff --git a/WordPress/JetpackStatsWidgets/Helpers/HomeWidgetDataFileReader.swift b/WordPress/JetpackStatsWidgets/Helpers/HomeWidgetDataFileReader.swift index 0cd91b1652f3..aa223220fa80 100644 --- a/WordPress/JetpackStatsWidgets/Helpers/HomeWidgetDataFileReader.swift +++ b/WordPress/JetpackStatsWidgets/Helpers/HomeWidgetDataFileReader.swift @@ -9,4 +9,8 @@ final class HomeWidgetDataFileReader: WidgetDataCacheReader { return T.read()?[siteID] } + + func widgetData() -> [T]? { + return T.read()?.map { $0.value } + } } diff --git a/WordPress/JetpackStatsWidgets/Helpers/WidgetDataReader.swift b/WordPress/JetpackStatsWidgets/Helpers/WidgetDataReader.swift index 1790fcb4ccdf..327c5b36fe3e 100644 --- a/WordPress/JetpackStatsWidgets/Helpers/WidgetDataReader.swift +++ b/WordPress/JetpackStatsWidgets/Helpers/WidgetDataReader.swift @@ -2,6 +2,7 @@ import Foundation protocol WidgetDataCacheReader { func widgetData(for siteID: String) -> T? + func widgetData() -> [T]? } enum WidgetDataReadError: Error { @@ -30,40 +31,33 @@ final class WidgetDataReader { /// - configuration: Configuration of the Widget Site Selection Intent /// - defaultSiteID: ID of the default site in the account /// - Returns: Widget data - func widgetData(for configuration: SelectSiteIntent, defaultSiteID: Int?) -> T? { - - /// If configuration.site.identifier has value but there's no widgetData, it means that this identifier comes from previously logged in account - if let selectedSite = configuration.site?.identifier, - let widgetData: T = cacheReader.widgetData(for: selectedSite) { - return widgetData - } else if let defaultSiteID = defaultSiteID { - return cacheReader.widgetData(for: String(defaultSiteID)) - } else { - return nil - } - } - func widgetData( for configuration: SelectSiteIntent, - defaultSiteID: Int?, - isJetpack: Bool + defaultSiteID: Int? ) -> Result { guard let defaults = userDefaults else { return .failure(.noData) } - guard let defaultSiteID = defaultSiteID else { + + if let selectedSite = configuration.site?.identifier, + let widgetData: T = cacheReader.widgetData(for: selectedSite) { + return .success(widgetData) + } else if let defaultSiteID = defaultSiteID, + let widgetData: T = cacheReader.widgetData(for: String(defaultSiteID)) { + return .success(widgetData) + } else { let loggedIn = defaults.bool(forKey: AppConfiguration.Widget.Stats.userDefaultsLoggedInKey) if loggedIn { - return .failure(.noSite) + /// In rare cases there could be no default site and no defaultSiteId set + if let firstSiteData: T = cacheReader.widgetData()?.sorted(by: { $0.siteID < $1.siteID }).first { + return .success(firstSiteData) + } else { + return .failure(.noSite) + } } else { return .failure(.loggedOut) } } - guard let widgetData = widgetData(for: configuration, defaultSiteID: defaultSiteID) else { - return .failure(.noData) - } - - return .success(widgetData) } } diff --git a/WordPress/JetpackStatsWidgets/LockScreenWidgets/LockScreenSiteListProvider.swift b/WordPress/JetpackStatsWidgets/LockScreenWidgets/LockScreenSiteListProvider.swift index e824de4ab251..7e7803487681 100644 --- a/WordPress/JetpackStatsWidgets/LockScreenWidgets/LockScreenSiteListProvider.swift +++ b/WordPress/JetpackStatsWidgets/LockScreenWidgets/LockScreenSiteListProvider.swift @@ -21,15 +21,18 @@ struct LockScreenSiteListProvider: IntentTimelineProvider { } func getSnapshot(for configuration: SelectSiteIntent, in context: Context, completion: @escaping (LockScreenStatsWidgetEntry) -> Void) { - let content = widgetDataLoader.widgetData(for: configuration, defaultSiteID: defaultSiteID) ?? placeholderContent - completion(.siteSelected(content, context)) + switch widgetDataLoader.widgetData(for: configuration, defaultSiteID: defaultSiteID) { + case .success(let widgetData): + completion(.siteSelected(widgetData, context)) + case .failure: + completion(.siteSelected(placeholderContent, context)) + } } func getTimeline(for configuration: SelectSiteIntent, in context: Context, completion: @escaping (Timeline>) -> Void) { switch widgetDataLoader.widgetData( for: configuration, - defaultSiteID: defaultSiteID, - isJetpack: AppConfiguration.isJetpack + defaultSiteID: defaultSiteID ) { case .success(let widgetData): let date = Date() diff --git a/WordPress/JetpackStatsWidgets/SiteListProvider.swift b/WordPress/JetpackStatsWidgets/SiteListProvider.swift index b9cf4680e269..b5ef54f7834c 100644 --- a/WordPress/JetpackStatsWidgets/SiteListProvider.swift +++ b/WordPress/JetpackStatsWidgets/SiteListProvider.swift @@ -24,16 +24,18 @@ struct SiteListProvider: IntentTimelineProvider { } func getSnapshot(for configuration: SelectSiteIntent, in context: Context, completion: @escaping (StatsWidgetEntry) -> Void) { - - let content = widgetDataLoader.widgetData(for: configuration, defaultSiteID: defaultSiteID) ?? placeholderContent - completion(.siteSelected(content, context)) + switch widgetDataLoader.widgetData(for: configuration, defaultSiteID: defaultSiteID) { + case .success(let widgetData): + completion(.siteSelected(widgetData, context)) + case .failure: + completion(.siteSelected(placeholderContent, context)) + } } func getTimeline(for configuration: SelectSiteIntent, in context: Context, completion: @escaping (Timeline) -> Void) { switch widgetDataLoader.widgetData( for: configuration, - defaultSiteID: defaultSiteID, - isJetpack: AppConfiguration.isJetpack + defaultSiteID: defaultSiteID ) { case .success(let widgetData): let date = Date() diff --git a/WordPress/WordPressTest/Widgets/WidgetDataReaderTests.swift b/WordPress/WordPressTest/Widgets/WidgetDataReaderTests.swift index c58eea2f92df..0c7cf66caa3f 100644 --- a/WordPress/WordPressTest/Widgets/WidgetDataReaderTests.swift +++ b/WordPress/WordPressTest/Widgets/WidgetDataReaderTests.swift @@ -3,6 +3,18 @@ import XCTest final class WidgetDataReaderTests: XCTestCase { func testNoSite() { + let intent = SelectSiteIntent() + intent.site = Site(identifier: nil, display: "") + let sut = makeSUT( + makeUserDefaults(suiteName: #function), + makeCacheReader(isCacheExisted: false), + isLoggedIn: true + ) + + verifyWidgetStatus(sut, configuration: intent, defaultSiteID: nil, expectNoSite: true) + } + + func testSiteSelectedWithNoDefaultSiteAvailable() { let intent = SelectSiteIntent() intent.site = Site(identifier: nil, display: "") let sut = makeSUT( @@ -11,7 +23,7 @@ final class WidgetDataReaderTests: XCTestCase { isLoggedIn: true ) - verifyWidgetStatus(sut, configuration: intent, defaultSiteID: nil, isJetpack: true, expectNoSite: true) + verifyWidgetStatus(sut, configuration: intent, defaultSiteID: nil, expectSiteSelected: true) } func testLoggedOut() { @@ -23,7 +35,7 @@ final class WidgetDataReaderTests: XCTestCase { isLoggedIn: false ) - verifyWidgetStatus(sut, configuration: intent, defaultSiteID: nil, isJetpack: true, expectLoggedOut: true) + verifyWidgetStatus(sut, configuration: intent, defaultSiteID: nil, expectLoggedOut: true) } func testNoDataWhenNoUserDefaults() { @@ -35,7 +47,7 @@ final class WidgetDataReaderTests: XCTestCase { isLoggedIn: false ) - verifyWidgetStatus(sut, configuration: intent, defaultSiteID: 123, isJetpack: true, expectNoData: true) + verifyWidgetStatus(sut, configuration: intent, defaultSiteID: 123, expectNoData: true) } func testNoDataWhenWidgetDataNotFound() { @@ -47,7 +59,7 @@ final class WidgetDataReaderTests: XCTestCase { isLoggedIn: true ) - verifyWidgetStatus(sut, configuration: intent, defaultSiteID: 123, isJetpack: true, expectNoData: true) + verifyWidgetStatus(sut, configuration: intent, defaultSiteID: 123, expectNoData: true) } func testSiteSelected() { @@ -59,7 +71,7 @@ final class WidgetDataReaderTests: XCTestCase { isLoggedIn: true ) - verifyWidgetStatus(sut, configuration: intent, defaultSiteID: 123, isJetpack: true, expectSiteSelected: true) + verifyWidgetStatus(sut, configuration: intent, defaultSiteID: 123, expectSiteSelected: true) } } @@ -87,7 +99,6 @@ extension WidgetDataReaderTests { _ sut: WidgetDataReader, configuration: SelectSiteIntent, defaultSiteID: Int?, - isJetpack: Bool, expectDisabled: Bool = false, expectNoData: Bool = false, expectNoSite: Bool = false, @@ -107,8 +118,7 @@ extension WidgetDataReaderTests { switch sut.widgetData( for: configuration, - defaultSiteID: defaultSiteID, - isJetpack: isJetpack + defaultSiteID: defaultSiteID ) { case .success: siteSelectedExpectation.fulfill() @@ -155,4 +165,12 @@ struct MockHomeWidgetDataFileReader: WidgetDataCacheReader { return nil } } + + func widgetData() -> [T]? { + if isMockDataReturned { + return [mockData] as? [T] + } else { + return nil + } + } } From b7dacc2717350f57b17c403d52344430fad4e716 Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Fri, 15 Sep 2023 16:50:52 +0300 Subject: [PATCH 6/6] Update WidgetDataReaderTests.swift --- .../Widgets/WidgetDataReaderTests.swift | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/WordPress/WordPressTest/Widgets/WidgetDataReaderTests.swift b/WordPress/WordPressTest/Widgets/WidgetDataReaderTests.swift index 0c7cf66caa3f..4c00034a0bc2 100644 --- a/WordPress/WordPressTest/Widgets/WidgetDataReaderTests.swift +++ b/WordPress/WordPressTest/Widgets/WidgetDataReaderTests.swift @@ -2,16 +2,16 @@ import XCTest @testable import WordPress final class WidgetDataReaderTests: XCTestCase { - func testNoSite() { + func testNoSiteWhenWidgetDataNotFound() { let intent = SelectSiteIntent() - intent.site = Site(identifier: nil, display: "") + intent.site = Site(identifier: "test", display: "") let sut = makeSUT( makeUserDefaults(suiteName: #function), makeCacheReader(isCacheExisted: false), isLoggedIn: true ) - verifyWidgetStatus(sut, configuration: intent, defaultSiteID: nil, expectNoSite: true) + verifyWidgetStatus(sut, configuration: intent, defaultSiteID: 123, expectNoSite: true) } func testSiteSelectedWithNoDefaultSiteAvailable() { @@ -50,18 +50,6 @@ final class WidgetDataReaderTests: XCTestCase { verifyWidgetStatus(sut, configuration: intent, defaultSiteID: 123, expectNoData: true) } - func testNoDataWhenWidgetDataNotFound() { - let intent = SelectSiteIntent() - intent.site = Site(identifier: "test", display: "") - let sut = makeSUT( - makeUserDefaults(suiteName: #function), - makeCacheReader(isCacheExisted: false), - isLoggedIn: true - ) - - verifyWidgetStatus(sut, configuration: intent, defaultSiteID: 123, expectNoData: true) - } - func testSiteSelected() { let intent = SelectSiteIntent() intent.site = Site(identifier: "test", display: "")