From d34b387dd7594da2caa273cb6d7a32b9bbbf0739 Mon Sep 17 00:00:00 2001 From: Beemo Date: Tue, 28 Mar 2023 14:25:23 +0800 Subject: [PATCH 1/5] Add event key to configuration and pass to trackers in lockscreen widget Expand tracks for lockscreen stats entry Add rectangular widgets count and widgets update of the new widget --- .../WidgetConfiguration.swift | 1 + WordPress/Jetpack/WidgetConfiguration.swift | 1 + .../Configs/LockScreenStatsWidgetConfig.swift | 1 + ...LockScreenTodayViewsStatWidgetConfig.swift | 4 ++++ .../LockScreenStatsWidget.swift | 6 +++++ .../Tracks/Tracks+StatsWidgets.swift | 23 ++++++++++++++++++- 6 files changed, 35 insertions(+), 1 deletion(-) diff --git a/WordPress/Classes/Utility/App Configuration/WidgetConfiguration.swift b/WordPress/Classes/Utility/App Configuration/WidgetConfiguration.swift index b6c143f6c56a..e3efd5194abf 100644 --- a/WordPress/Classes/Utility/App Configuration/WidgetConfiguration.swift +++ b/WordPress/Classes/Utility/App Configuration/WidgetConfiguration.swift @@ -20,6 +20,7 @@ import Foundation @objc static let todayKind = "WordPressHomeWidgetToday" @objc static let allTimeKind = "WordPressHomeWidgetAllTime" @objc static let thisWeekKind = "WordPressHomeWidgetThisWeek" + @objc static let lockScreenTodayViewsProperties = "WordPressLockScreenWidgetTodayViewsProperties" @objc static let todayProperties = "WordPressHomeWidgetTodayProperties" @objc static let allTimeProperties = "WordPressHomeWidgetAllTimeProperties" @objc static let thisWeekProperties = "WordPressHomeWidgetThisWeekProperties" diff --git a/WordPress/Jetpack/WidgetConfiguration.swift b/WordPress/Jetpack/WidgetConfiguration.swift index d562e881b66e..a159f8c7fd9e 100644 --- a/WordPress/Jetpack/WidgetConfiguration.swift +++ b/WordPress/Jetpack/WidgetConfiguration.swift @@ -20,6 +20,7 @@ import Foundation @objc static let todayKind = "JetpackHomeWidgetToday" @objc static let allTimeKind = "JetpackHomeWidgetAllTime" @objc static let thisWeekKind = "JetpackHomeWidgetThisWeek" + @objc static let lockScreenTodayViewsProperties = "JetpackLockScreenWidgetTodayViewsProperties" @objc static let todayProperties = "JetpackHomeWidgetTodayProperties" @objc static let allTimeProperties = "JetpackHomeWidgetAllTimeProperties" @objc static let thisWeekProperties = "JetpackHomeWidgetThisWeekProperties" diff --git a/WordPress/WordPressStatsWidgets/LockScreenWidgets/Configs/LockScreenStatsWidgetConfig.swift b/WordPress/WordPressStatsWidgets/LockScreenWidgets/Configs/LockScreenStatsWidgetConfig.swift index 8bd2bd84760f..97c63e4f18e1 100644 --- a/WordPress/WordPressStatsWidgets/LockScreenWidgets/Configs/LockScreenStatsWidgetConfig.swift +++ b/WordPress/WordPressStatsWidgets/LockScreenWidgets/Configs/LockScreenStatsWidgetConfig.swift @@ -8,6 +8,7 @@ protocol LockScreenStatsWidgetConfig { var displayName: String { get } var description: String { get } var kind: String { get } + var countKey: String { get } var placeholderContent: WidgetData { get } var viewProvider: ViewProvider { get } } diff --git a/WordPress/WordPressStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayViewsStatWidgetConfig.swift b/WordPress/WordPressStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayViewsStatWidgetConfig.swift index c172c3bca759..09eb74f1fc7b 100644 --- a/WordPress/WordPressStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayViewsStatWidgetConfig.swift +++ b/WordPress/WordPressStatsWidgets/LockScreenWidgets/Configs/LockScreenTodayViewsStatWidgetConfig.swift @@ -24,6 +24,10 @@ struct LockScreenTodayViewsStatWidgetConfig: LockScreenStatsWidgetConfig { AppConfiguration.Widget.Stats.lockScreenTodayViewsKind } + var countKey: String { + AppConfiguration.Widget.Stats.lockScreenTodayViewsProperties + } + var placeholderContent: HomeWidgetTodayData { HomeWidgetTodayData( siteID: 0, diff --git a/WordPress/WordPressStatsWidgets/LockScreenWidgets/LockScreenStatsWidget.swift b/WordPress/WordPressStatsWidgets/LockScreenWidgets/LockScreenStatsWidget.swift index 8229eadacd77..bb17dc109898 100644 --- a/WordPress/WordPressStatsWidgets/LockScreenWidgets/LockScreenStatsWidget.swift +++ b/WordPress/WordPressStatsWidgets/LockScreenWidgets/LockScreenStatsWidget.swift @@ -3,6 +3,7 @@ import SwiftUI @available(iOS 16.0, *) struct LockScreenStatsWidget: Widget { + private let tracks = Tracks(appGroupName: WPAppGroupName) private let config: T init(config: T) { @@ -23,6 +24,11 @@ struct LockScreenStatsWidget: Widget { placeholderContent: config.placeholderContent ) ) { (entry: LockScreenStatsWidgetEntry) -> LockScreenStatsWidgetsView in + defer { + tracks.trackWidgetUpdatedIfNeeded(entry: entry, + widgetKind: config.kind, + widgetCountKey: config.countKey) + } return LockScreenStatsWidgetsView( timelineEntry: entry, viewProvider: config.viewProvider diff --git a/WordPress/WordPressStatsWidgets/Tracks/Tracks+StatsWidgets.swift b/WordPress/WordPressStatsWidgets/Tracks/Tracks+StatsWidgets.swift index 1545b2597209..59f7c50d2efa 100644 --- a/WordPress/WordPressStatsWidgets/Tracks/Tracks+StatsWidgets.swift +++ b/WordPress/WordPressStatsWidgets/Tracks/Tracks+StatsWidgets.swift @@ -5,6 +5,20 @@ import WidgetKit /// extension Tracks { + func trackWidgetUpdatedIfNeeded(entry: LockScreenStatsWidgetEntry, widgetKind: String, widgetCountKey: String) { + switch entry { + case .siteSelected(_, let context): + if !context.isPreview { + trackWidgetUpdated(widgetKind: widgetKind, + widgetCountKey: widgetCountKey) + } + + case .loggedOut, .noSite, .noData: + trackWidgetUpdated(widgetKind: widgetKind, + widgetCountKey: widgetCountKey) + } + } + func trackWidgetUpdatedIfNeeded(entry: StatsWidgetEntry, widgetKind: String, widgetCountKey: String) { switch entry { case .siteSelected(_, let context): @@ -39,10 +53,13 @@ extension Tracks { private func trackUpdatedWidgetInfo(widgetInfo: [WidgetInfo], widgetPropertiesKey: String) { - let properties = ["total_widgets": widgetInfo.count, + var properties = ["total_widgets": widgetInfo.count, "small_widgets": widgetInfo.filter { $0.family == .systemSmall }.count, "medium_widgets": widgetInfo.filter { $0.family == .systemMedium }.count, "large_widgets": widgetInfo.filter { $0.family == .systemLarge }.count] + if #available(iOS 16.0, *) { + properties["rectangular_widgets"] = widgetInfo.filter { $0.family == .accessoryRectangular }.count + } let previousProperties = UserDefaults(suiteName: WPAppGroupName)?.object(forKey: widgetPropertiesKey) as? [String: Int] @@ -71,6 +88,8 @@ extension Tracks { case allTimeWidgetUpdated = "alltime_home_extension_widget_updated" // Users installs an instance of the this week widget case thisWeekWidgetUpdated = "thisweek_home_extension_widget_updated" + // Users installs an instance of the lockscreen today views widget + case todayViewsLockScreenWidgetUpdated = "today_views_lockscreen_extension_widget_updated" case noEvent @@ -82,6 +101,8 @@ extension Tracks { return .allTimeWidgetUpdated case AppConfiguration.Widget.Stats.thisWeekProperties: return .thisWeekWidgetUpdated + case AppConfiguration.Widget.Stats.lockScreenTodayViewsProperties: + return .todayViewsLockScreenWidgetUpdated default: return .noEvent } From 25f230aa108896e76d0d560f05a89b74538853f9 Mon Sep 17 00:00:00 2001 From: Beemo Date: Tue, 28 Mar 2023 14:54:31 +0800 Subject: [PATCH 2/5] Add lockscreen_widget source to deeplink tracked Update statsUrl to widgetUrl for separating the url from homescreen widgets --- .../Classes/Utility/Universal Links/Route.swift | 3 +++ .../Universal Links/UniversalLinkRouter.swift | 2 ++ .../HomeWidgetData+LockScreenStatsWidgetData.swift | 12 ++++++++++++ .../Models/LockScreenStatsWidgetData.swift | 2 +- .../Views/LockScreenStatsWidgetsView.swift | 2 +- 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/WordPress/Classes/Utility/Universal Links/Route.swift b/WordPress/Classes/Utility/Universal Links/Route.swift index adde5cb10e06..a17391cca58e 100644 --- a/WordPress/Classes/Utility/Universal Links/Route.swift +++ b/WordPress/Classes/Utility/Universal Links/Route.swift @@ -94,6 +94,7 @@ enum DeepLinkSource: Equatable { case banner case email(campaign: String) case widget + case lockScreenWidget case inApp(presenter: UIViewController?) init?(sourceName: String) { @@ -102,6 +103,8 @@ enum DeepLinkSource: Equatable { // add others in the future if necessary. case "widget": self = .widget + case "lockscreen_widget": + self = .lockScreenWidget default: return nil } diff --git a/WordPress/Classes/Utility/Universal Links/UniversalLinkRouter.swift b/WordPress/Classes/Utility/Universal Links/UniversalLinkRouter.swift index 08a6e35002f1..594863496027 100644 --- a/WordPress/Classes/Utility/Universal Links/UniversalLinkRouter.swift +++ b/WordPress/Classes/Utility/Universal Links/UniversalLinkRouter.swift @@ -243,6 +243,8 @@ extension DeepLinkSource { return "email" case .widget: return "widget" + case .lockScreenWidget: + return "lockscreen_widget" case .inApp: return "internal" } diff --git a/WordPress/WordPressStatsWidgets/Extensions/HomeWidgetData+LockScreenStatsWidgetData.swift b/WordPress/WordPressStatsWidgets/Extensions/HomeWidgetData+LockScreenStatsWidgetData.swift index e213c27f7ce2..7ff748ea6eee 100644 --- a/WordPress/WordPressStatsWidgets/Extensions/HomeWidgetData+LockScreenStatsWidgetData.swift +++ b/WordPress/WordPressStatsWidgets/Extensions/HomeWidgetData+LockScreenStatsWidgetData.swift @@ -4,16 +4,28 @@ extension HomeWidgetTodayData: LockScreenStatsWidgetData { var views: Int? { stats.views } + + var widgetURL: URL? { + URL(string: HomeWidgetTodayData.statsUrl + "\(siteID)?source=lockscreen_widget") + } } extension HomeWidgetAllTimeData: LockScreenStatsWidgetData { var views: Int? { stats.views } + + var widgetURL: URL? { + URL(string: HomeWidgetAllTimeData.statsUrl + "\(siteID)?source=lockscreen_widget") + } } extension HomeWidgetThisWeekData: LockScreenStatsWidgetData { var views: Int? { nil } + + var widgetURL: URL? { + URL(string: HomeWidgetThisWeekData.statsUrl + "\(siteID)?source=lockscreen_widget") + } } diff --git a/WordPress/WordPressStatsWidgets/LockScreenWidgets/Models/LockScreenStatsWidgetData.swift b/WordPress/WordPressStatsWidgets/LockScreenWidgets/Models/LockScreenStatsWidgetData.swift index cf687ed3a07c..8ae8cd6c3c71 100644 --- a/WordPress/WordPressStatsWidgets/LockScreenWidgets/Models/LockScreenStatsWidgetData.swift +++ b/WordPress/WordPressStatsWidgets/LockScreenWidgets/Models/LockScreenStatsWidgetData.swift @@ -2,7 +2,7 @@ import Foundation protocol LockScreenStatsWidgetData { var siteName: String { get } - var statsURL: URL? { get } + var widgetURL: URL? { get } var views: Int? { get } var date: Date { get } } diff --git a/WordPress/WordPressStatsWidgets/LockScreenWidgets/Views/LockScreenStatsWidgetsView.swift b/WordPress/WordPressStatsWidgets/LockScreenWidgets/Views/LockScreenStatsWidgetsView.swift index 04c17426be0d..4d8e7527bb2e 100644 --- a/WordPress/WordPressStatsWidgets/LockScreenWidgets/Views/LockScreenStatsWidgetsView.swift +++ b/WordPress/WordPressStatsWidgets/LockScreenWidgets/Views/LockScreenStatsWidgetsView.swift @@ -30,7 +30,7 @@ struct LockScreenStatsWidgetsView: View { case let .siteSelected(data, _): viewProvider .buildSiteSelectedView(data) - .widgetURL(data.statsURL) + .widgetURL(data.widgetURL) case .loggedOut: viewProvider .buildLoggedOutView() From c06d35bdbc0947fdd6eb68aa52dc35bc0ee9aec1 Mon Sep 17 00:00:00 2001 From: Beemo Date: Tue, 28 Mar 2023 15:27:34 +0800 Subject: [PATCH 3/5] Update unitTests --- .../WordPressTest/Widgets/WidgetsViewModelMapperTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/WordPressTest/Widgets/WidgetsViewModelMapperTests.swift b/WordPress/WordPressTest/Widgets/WidgetsViewModelMapperTests.swift index a0395133275a..96fbd3f86e77 100644 --- a/WordPress/WordPressTest/Widgets/WidgetsViewModelMapperTests.swift +++ b/WordPress/WordPressTest/Widgets/WidgetsViewModelMapperTests.swift @@ -24,9 +24,9 @@ final class WidgetsViewModelMapperTests: XCTestCase { func testTodayViewsStatsURL() { let todayStats = makeTodayWidgetStats(views: 649) let data = makeTodayData(stats: todayStats, date: Date()) - let statsURL = data.statsURL + let statsURL = data.widgetURL - XCTAssertEqual(statsURL?.absoluteString, "https://wordpress.com/stats/day/0?source=widget") + XCTAssertEqual(statsURL?.absoluteString, "https://wordpress.com/stats/day/0?source=lockscreen_widget") } func testUnconfiguredViewModel() { From fb193e39ce6012c8de846d76b88b165308e72b79 Mon Sep 17 00:00:00 2001 From: Beemo Date: Tue, 28 Mar 2023 19:43:42 +0800 Subject: [PATCH 4/5] Remove separate widget url, move widget source from widget data extension Add widget source type, assign the type in widgetURL in the view --- WordPress/WordPress.xcodeproj/project.pbxproj | 6 ++++++ ...meWidgetData+LockScreenStatsWidgetData.swift | 12 ------------ .../Extensions/HomeWidgetData+StatsURL.swift | 6 +++--- .../Extensions/URL+WidgetSource.swift | 17 +++++++++++++++++ .../Models/LockScreenStatsWidgetData.swift | 2 +- .../Views/LockScreenStatsWidgetsView.swift | 2 +- .../Views/StatsWidgetsView.swift | 6 +++--- .../Widgets/WidgetsViewModelMapperTests.swift | 4 ++-- 8 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 WordPress/WordPressStatsWidgets/Extensions/URL+WidgetSource.swift diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index 3c20091b3631..cbcfeea99cc2 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -2857,6 +2857,8 @@ C94C0B1B25DCFA0100F2F69B /* FilterableCategoriesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94C0B1A25DCFA0100F2F69B /* FilterableCategoriesViewController.swift */; }; C957C20626DCC1770037628F /* LandInTheEditorHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C957C20526DCC1770037628F /* LandInTheEditorHelper.swift */; }; C957C20726DCC1770037628F /* LandInTheEditorHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C957C20526DCC1770037628F /* LandInTheEditorHelper.swift */; }; + C995C22229D306DD00ACEF43 /* URL+WidgetSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C995C22129D306DD00ACEF43 /* URL+WidgetSource.swift */; }; + C995C22329D306E100ACEF43 /* URL+WidgetSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C995C22129D306DD00ACEF43 /* URL+WidgetSource.swift */; }; C99B08FC26081AD600CA71EB /* TemplatePreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C99B08FB26081AD600CA71EB /* TemplatePreviewViewController.swift */; }; C9B4778429C85949008CBF49 /* LockScreenStatsWidgetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9B4778229C85948008CBF49 /* LockScreenStatsWidgetData.swift */; }; C9B4778529C85949008CBF49 /* LockScreenStatsWidgetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9B4778229C85948008CBF49 /* LockScreenStatsWidgetData.swift */; }; @@ -8132,6 +8134,7 @@ C9264D275F6288F66C33D2CE /* Pods-WordPressTest.release-internal.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WordPressTest.release-internal.xcconfig"; path = "../Pods/Target Support Files/Pods-WordPressTest/Pods-WordPressTest.release-internal.xcconfig"; sourceTree = ""; }; C94C0B1A25DCFA0100F2F69B /* FilterableCategoriesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterableCategoriesViewController.swift; sourceTree = ""; }; C957C20526DCC1770037628F /* LandInTheEditorHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandInTheEditorHelper.swift; sourceTree = ""; }; + C995C22129D306DD00ACEF43 /* URL+WidgetSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+WidgetSource.swift"; sourceTree = ""; }; C99B039B2602F3CB00CA71EB /* WordPress 117.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "WordPress 117.xcdatamodel"; sourceTree = ""; }; C99B08FB26081AD600CA71EB /* TemplatePreviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplatePreviewViewController.swift; sourceTree = ""; }; C9B4778229C85948008CBF49 /* LockScreenStatsWidgetData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockScreenStatsWidgetData.swift; sourceTree = ""; }; @@ -15733,6 +15736,7 @@ children = ( C9FE382129C2040600D39841 /* HomeWidgetData+StatsURL.swift */, C9B4778829C85956008CBF49 /* HomeWidgetData+LockScreenStatsWidgetData.swift */, + C995C22129D306DD00ACEF43 /* URL+WidgetSource.swift */, ); path = Extensions; sourceTree = ""; @@ -20532,6 +20536,7 @@ files = ( C9B4778729C85949008CBF49 /* LockScreenStatsWidgetEntry.swift in Sources */, 0107E0B428F97D5000DE87DB /* Constants.m in Sources */, + C995C22329D306E100ACEF43 /* URL+WidgetSource.swift in Sources */, 01CE5012290A890B00A9C2E0 /* TracksConfiguration.swift in Sources */, C9C21D7C29BED18C009F68E5 /* LockScreenStatsWidgetsView.swift in Sources */, C9FE382F29C204E700D39841 /* LockScreenSingleStatViewModel.swift in Sources */, @@ -22412,6 +22417,7 @@ files = ( C9B4778629C85949008CBF49 /* LockScreenStatsWidgetEntry.swift in Sources */, 3F1FD30D2548B0A80060C53A /* Constants.m in Sources */, + C995C22229D306DD00ACEF43 /* URL+WidgetSource.swift in Sources */, 01CE500C290A88BF00A9C2E0 /* TracksConfiguration.swift in Sources */, C9C21D7B29BED18C009F68E5 /* LockScreenStatsWidgetsView.swift in Sources */, C9FE382E29C204E700D39841 /* LockScreenSingleStatViewModel.swift in Sources */, diff --git a/WordPress/WordPressStatsWidgets/Extensions/HomeWidgetData+LockScreenStatsWidgetData.swift b/WordPress/WordPressStatsWidgets/Extensions/HomeWidgetData+LockScreenStatsWidgetData.swift index 7ff748ea6eee..e213c27f7ce2 100644 --- a/WordPress/WordPressStatsWidgets/Extensions/HomeWidgetData+LockScreenStatsWidgetData.swift +++ b/WordPress/WordPressStatsWidgets/Extensions/HomeWidgetData+LockScreenStatsWidgetData.swift @@ -4,28 +4,16 @@ extension HomeWidgetTodayData: LockScreenStatsWidgetData { var views: Int? { stats.views } - - var widgetURL: URL? { - URL(string: HomeWidgetTodayData.statsUrl + "\(siteID)?source=lockscreen_widget") - } } extension HomeWidgetAllTimeData: LockScreenStatsWidgetData { var views: Int? { stats.views } - - var widgetURL: URL? { - URL(string: HomeWidgetAllTimeData.statsUrl + "\(siteID)?source=lockscreen_widget") - } } extension HomeWidgetThisWeekData: LockScreenStatsWidgetData { var views: Int? { nil } - - var widgetURL: URL? { - URL(string: HomeWidgetThisWeekData.statsUrl + "\(siteID)?source=lockscreen_widget") - } } diff --git a/WordPress/WordPressStatsWidgets/Extensions/HomeWidgetData+StatsURL.swift b/WordPress/WordPressStatsWidgets/Extensions/HomeWidgetData+StatsURL.swift index 58ac96e28fcf..f15993413451 100644 --- a/WordPress/WordPressStatsWidgets/Extensions/HomeWidgetData+StatsURL.swift +++ b/WordPress/WordPressStatsWidgets/Extensions/HomeWidgetData+StatsURL.swift @@ -4,7 +4,7 @@ extension HomeWidgetTodayData { static let statsUrl = "https://wordpress.com/stats/day/" var statsURL: URL? { - URL(string: Self.statsUrl + "\(siteID)?source=widget") + URL(string: Self.statsUrl + "\(siteID)") } } @@ -12,7 +12,7 @@ extension HomeWidgetAllTimeData { static let statsUrl = "https://wordpress.com/stats/insights/" var statsURL: URL? { - URL(string: Self.statsUrl + "\(siteID)?source=widget") + URL(string: Self.statsUrl + "\(siteID)") } } @@ -20,6 +20,6 @@ extension HomeWidgetThisWeekData { static let statsUrl = "https://wordpress.com/stats/week/" var statsURL: URL? { - URL(string: Self.statsUrl + "\(siteID)?source=widget") + URL(string: Self.statsUrl + "\(siteID)") } } diff --git a/WordPress/WordPressStatsWidgets/Extensions/URL+WidgetSource.swift b/WordPress/WordPressStatsWidgets/Extensions/URL+WidgetSource.swift new file mode 100644 index 000000000000..071ce5966836 --- /dev/null +++ b/WordPress/WordPressStatsWidgets/Extensions/URL+WidgetSource.swift @@ -0,0 +1,17 @@ +import Foundation + +enum WidgetUrlSource: String { + case homeScreenWidget = "widget" + case lockScreenWidget = "lockscreen_widget" +} + +extension URL { + func appendingSource(_ source: WidgetUrlSource) -> URL { + var components = URLComponents(url: self, resolvingAgainstBaseURL: false) + var queryItems = components?.queryItems ?? [] + let sourceQuery = URLQueryItem(name: "source", value: source.rawValue) + queryItems.append(sourceQuery) + components?.queryItems = queryItems + return components?.url ?? self + } +} diff --git a/WordPress/WordPressStatsWidgets/LockScreenWidgets/Models/LockScreenStatsWidgetData.swift b/WordPress/WordPressStatsWidgets/LockScreenWidgets/Models/LockScreenStatsWidgetData.swift index 8ae8cd6c3c71..cf687ed3a07c 100644 --- a/WordPress/WordPressStatsWidgets/LockScreenWidgets/Models/LockScreenStatsWidgetData.swift +++ b/WordPress/WordPressStatsWidgets/LockScreenWidgets/Models/LockScreenStatsWidgetData.swift @@ -2,7 +2,7 @@ import Foundation protocol LockScreenStatsWidgetData { var siteName: String { get } - var widgetURL: URL? { get } + var statsURL: URL? { get } var views: Int? { get } var date: Date { get } } diff --git a/WordPress/WordPressStatsWidgets/LockScreenWidgets/Views/LockScreenStatsWidgetsView.swift b/WordPress/WordPressStatsWidgets/LockScreenWidgets/Views/LockScreenStatsWidgetsView.swift index 4d8e7527bb2e..4d3b21e45b4d 100644 --- a/WordPress/WordPressStatsWidgets/LockScreenWidgets/Views/LockScreenStatsWidgetsView.swift +++ b/WordPress/WordPressStatsWidgets/LockScreenWidgets/Views/LockScreenStatsWidgetsView.swift @@ -30,7 +30,7 @@ struct LockScreenStatsWidgetsView: View { case let .siteSelected(data, _): viewProvider .buildSiteSelectedView(data) - .widgetURL(data.widgetURL) + .widgetURL(data.statsURL?.appendingSource(.lockScreenWidget)) case .loggedOut: viewProvider .buildLoggedOutView() diff --git a/WordPress/WordPressStatsWidgets/Views/StatsWidgetsView.swift b/WordPress/WordPressStatsWidgets/Views/StatsWidgetsView.swift index 8a66d364f71b..d7f16d5a46ed 100644 --- a/WordPress/WordPressStatsWidgets/Views/StatsWidgetsView.swift +++ b/WordPress/WordPressStatsWidgets/Views/StatsWidgetsView.swift @@ -13,7 +13,7 @@ struct StatsWidgetsView: View { case .disabled(let kind): UnconfiguredView(timelineEntry: timelineEntry) - .widgetURL(kind.statsURL) + .widgetURL(kind.statsURL?.appendingSource(.homeScreenWidget)) case .loggedOut, .noSite, .noData: UnconfiguredView(timelineEntry: timelineEntry) .widgetURL(nil) @@ -25,12 +25,12 @@ struct StatsWidgetsView: View { case .systemSmall: SingleStatView(viewData: viewData) - .widgetURL(viewData.statsURL) + .widgetURL(viewData.statsURL?.appendingSource(.homeScreenWidget)) .padding() case .systemMedium: MultiStatsView(viewData: viewData) - .widgetURL(viewData.statsURL) + .widgetURL(viewData.statsURL?.appendingSource(.homeScreenWidget)) .padding() default: diff --git a/WordPress/WordPressTest/Widgets/WidgetsViewModelMapperTests.swift b/WordPress/WordPressTest/Widgets/WidgetsViewModelMapperTests.swift index 96fbd3f86e77..8a8b9a2da6b3 100644 --- a/WordPress/WordPressTest/Widgets/WidgetsViewModelMapperTests.swift +++ b/WordPress/WordPressTest/Widgets/WidgetsViewModelMapperTests.swift @@ -24,9 +24,9 @@ final class WidgetsViewModelMapperTests: XCTestCase { func testTodayViewsStatsURL() { let todayStats = makeTodayWidgetStats(views: 649) let data = makeTodayData(stats: todayStats, date: Date()) - let statsURL = data.widgetURL + let statsURL = data.statsURL - XCTAssertEqual(statsURL?.absoluteString, "https://wordpress.com/stats/day/0?source=lockscreen_widget") + XCTAssertEqual(statsURL?.absoluteString, "https://wordpress.com/stats/day/0") } func testUnconfiguredViewModel() { From eab43a64e634949ca2bcc6d04cd6a0fa5367d253 Mon Sep 17 00:00:00 2001 From: Beemo Date: Tue, 28 Mar 2023 19:56:47 +0800 Subject: [PATCH 5/5] Add widget url source test to verify the converting with DeepLinkSource --- WordPress/WordPress.xcodeproj/project.pbxproj | 6 ++++ .../Widgets/WidgetUrlSourceTests.swift | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 WordPress/WordPressTest/Widgets/WidgetUrlSourceTests.swift diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index cbcfeea99cc2..024efdb2748b 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -2859,6 +2859,8 @@ C957C20726DCC1770037628F /* LandInTheEditorHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C957C20526DCC1770037628F /* LandInTheEditorHelper.swift */; }; C995C22229D306DD00ACEF43 /* URL+WidgetSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C995C22129D306DD00ACEF43 /* URL+WidgetSource.swift */; }; C995C22329D306E100ACEF43 /* URL+WidgetSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C995C22129D306DD00ACEF43 /* URL+WidgetSource.swift */; }; + C995C22429D30A9900ACEF43 /* URL+WidgetSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C995C22129D306DD00ACEF43 /* URL+WidgetSource.swift */; }; + C995C22629D30AB000ACEF43 /* WidgetUrlSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C995C22529D30AB000ACEF43 /* WidgetUrlSourceTests.swift */; }; C99B08FC26081AD600CA71EB /* TemplatePreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C99B08FB26081AD600CA71EB /* TemplatePreviewViewController.swift */; }; C9B4778429C85949008CBF49 /* LockScreenStatsWidgetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9B4778229C85948008CBF49 /* LockScreenStatsWidgetData.swift */; }; C9B4778529C85949008CBF49 /* LockScreenStatsWidgetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9B4778229C85948008CBF49 /* LockScreenStatsWidgetData.swift */; }; @@ -8135,6 +8137,7 @@ C94C0B1A25DCFA0100F2F69B /* FilterableCategoriesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterableCategoriesViewController.swift; sourceTree = ""; }; C957C20526DCC1770037628F /* LandInTheEditorHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandInTheEditorHelper.swift; sourceTree = ""; }; C995C22129D306DD00ACEF43 /* URL+WidgetSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+WidgetSource.swift"; sourceTree = ""; }; + C995C22529D30AB000ACEF43 /* WidgetUrlSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetUrlSourceTests.swift; sourceTree = ""; }; C99B039B2602F3CB00CA71EB /* WordPress 117.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "WordPress 117.xcdatamodel"; sourceTree = ""; }; C99B08FB26081AD600CA71EB /* TemplatePreviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplatePreviewViewController.swift; sourceTree = ""; }; C9B4778229C85948008CBF49 /* LockScreenStatsWidgetData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockScreenStatsWidgetData.swift; sourceTree = ""; }; @@ -15766,6 +15769,7 @@ children = ( C9FE383629C2067E00D39841 /* WidgetsViewModelMapperTests.swift */, C9B477AF29CC35C5008CBF49 /* WidgetDataReaderTests.swift */, + C995C22529D30AB000ACEF43 /* WidgetUrlSourceTests.swift */, ); path = Widgets; sourceTree = ""; @@ -22015,6 +22019,7 @@ 010459E629153FFF000C7778 /* JetpackNotificationMigrationService.swift in Sources */, FAC1B82729B1F1EE00E0C542 /* BlazePostPreviewView.swift in Sources */, E61084C21B9B47BA008050C5 /* ReaderTagTopic.swift in Sources */, + C995C22429D30A9900ACEF43 /* URL+WidgetSource.swift in Sources */, F110239B2318479000C4E84A /* Media.swift in Sources */, 176CE91627FB44C100F1E32B /* StatsBaseCell.swift in Sources */, E1C2260723901AAD0021D03C /* WordPressOrgRestApi+WordPress.swift in Sources */, @@ -23221,6 +23226,7 @@ DC13DB7E293FD09F00E33561 /* StatsInsightsStoreTests.swift in Sources */, ACACE3AE28D729FA000992F9 /* NoResultsViewControllerTests.swift in Sources */, 8BFE36FF230F1C850061EBA8 /* AbstractPost+fixLocalMediaURLsTests.swift in Sources */, + C995C22629D30AB000ACEF43 /* WidgetUrlSourceTests.swift in Sources */, 08A2AD791CCED2A800E84454 /* PostTagServiceTests.m in Sources */, F543AF5723A84E4D0022F595 /* PublishSettingsControllerTests.swift in Sources */, 027AC5212278983F0033E56E /* DomainCreditEligibilityTests.swift in Sources */, diff --git a/WordPress/WordPressTest/Widgets/WidgetUrlSourceTests.swift b/WordPress/WordPressTest/Widgets/WidgetUrlSourceTests.swift new file mode 100644 index 000000000000..c416acfa2868 --- /dev/null +++ b/WordPress/WordPressTest/Widgets/WidgetUrlSourceTests.swift @@ -0,0 +1,28 @@ +import XCTest +@testable import WordPress + +final class WidgetUrlSourceTests: XCTestCase { + func testHomeScreenWidgetSource() throws { + let url = try XCTUnwrap(URL(string: "https://test")) + let widgetUrl = url.appendingSource(.homeScreenWidget) + XCTAssertEqual(widgetUrl.absoluteString, "https://test?source=widget") + } + + func testLockScreenWidgetSource() throws { + let url = try XCTUnwrap(URL(string: "https://test")) + let widgetUrl = url.appendingSource(.lockScreenWidget) + XCTAssertEqual(widgetUrl.absoluteString, "https://test?source=lockscreen_widget") + } + + func testHomeScreenWidgetSourceType() { + let source = WidgetUrlSource.homeScreenWidget.rawValue + let deepLinkSource = DeepLinkSource(sourceName: source) + XCTAssertEqual(deepLinkSource, .widget) + } + + func testLockScreenWidgetSourceType() { + let source = WidgetUrlSource.lockScreenWidget.rawValue + let deepLinkSource = DeepLinkSource(sourceName: source) + XCTAssertEqual(deepLinkSource, .lockScreenWidget) + } +}