diff --git a/Core/UserAgentManager.swift b/Core/UserAgentManager.swift index 9c9225e6eb..fecbbbf503 100644 --- a/Core/UserAgentManager.swift +++ b/Core/UserAgentManager.swift @@ -32,6 +32,8 @@ public protocol UserAgentManager { func userAgent(isDesktop: Bool) -> String + func userAgent(isDesktop: Bool, url: URL?) -> String + } public class DefaultUserAgentManager: UserAgentManager { @@ -60,6 +62,10 @@ public class DefaultUserAgentManager: UserAgentManager { return userAgent.agent(forUrl: nil, isDesktop: isDesktop) } + public func userAgent(isDesktop: Bool, url: URL?) -> String { + return userAgent.agent(forUrl: url, isDesktop: isDesktop) + } + public func update(request: inout URLRequest, isDesktop: Bool) { request.addValue(userAgent.agent(forUrl: nil, isDesktop: isDesktop), forHTTPHeaderField: "User-Agent") } diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index d1dc4b5679..b71c65a6e4 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -213,7 +213,7 @@ 4B6484F327FD1E350050A7A1 /* MenuControllerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6484E927FD1E340050A7A1 /* MenuControllerView.swift */; }; 4B6ED9452B992FE4007F5CAA /* vpn-dark-mode.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B6ED9442B992FE4007F5CAA /* vpn-dark-mode.json */; }; 4B75EA9226A266CB00018634 /* PrintingUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B75EA9126A266CB00018634 /* PrintingUserScript.swift */; }; - 4B78074E2B183A1F009DB2CF /* SurveyURLBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B78074D2B183A1F009DB2CF /* SurveyURLBuilder.swift */; }; + 4B78074E2B183A1F009DB2CF /* RemoteMessagingSurveyURLBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B78074D2B183A1F009DB2CF /* RemoteMessagingSurveyURLBuilder.swift */; }; 4B948E2629DCCDB9002531FA /* Persistence in Frameworks */ = {isa = PBXBuildFile; productRef = 4B948E2529DCCDB9002531FA /* Persistence */; }; 4BB7CBB02AF59C310014A35F /* VPNWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB7CBAF2AF59C310014A35F /* VPNWidget.swift */; }; 4BBBBA872B02E85400D965DA /* DesignResourcesKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4BBBBA862B02E85400D965DA /* DesignResourcesKit */; }; @@ -1300,7 +1300,7 @@ 4B6484E927FD1E340050A7A1 /* MenuControllerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuControllerView.swift; sourceTree = ""; }; 4B6ED9442B992FE4007F5CAA /* vpn-dark-mode.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "vpn-dark-mode.json"; sourceTree = ""; }; 4B75EA9126A266CB00018634 /* PrintingUserScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrintingUserScript.swift; sourceTree = ""; }; - 4B78074D2B183A1F009DB2CF /* SurveyURLBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SurveyURLBuilder.swift; sourceTree = ""; }; + 4B78074D2B183A1F009DB2CF /* RemoteMessagingSurveyURLBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteMessagingSurveyURLBuilder.swift; sourceTree = ""; }; 4BB7CBAF2AF59C310014A35F /* VPNWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNWidget.swift; sourceTree = ""; }; 4BBBBA912B03291700D965DA /* VPNWaitlistUserText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNWaitlistUserText.swift; sourceTree = ""; }; 4BC21A2C272388BD00229F0E /* RunLoopExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunLoopExtensionTests.swift; sourceTree = ""; }; @@ -4292,6 +4292,7 @@ C1B7B52028941F2A0098FD6A /* RemoteMessageRequest.swift */, C1B7B52128941F2A0098FD6A /* RemoteMessaging.swift */, C1B7B51F28941F2A0098FD6A /* RemoteMessagingStore.swift */, + 4B78074D2B183A1F009DB2CF /* RemoteMessagingSurveyURLBuilder.swift */, ); name = RemoteMessaging; sourceTree = ""; @@ -6407,7 +6408,7 @@ F1386BA41E6846C40062FC3C /* TabDelegate.swift in Sources */, 37CF91602BB4737300BADCAE /* CrashCollectionOnboarding.swift in Sources */, C1B924B72ACD6E6800EE7B06 /* AutofillNeverSavedTableViewCell.swift in Sources */, - 4B78074E2B183A1F009DB2CF /* SurveyURLBuilder.swift in Sources */, + 4B78074E2B183A1F009DB2CF /* RemoteMessagingSurveyURLBuilder.swift in Sources */, 3132FA2A27A0788F00DD7A12 /* QuickLookPreviewHelper.swift in Sources */, D670E5BB2BB6A75300941A42 /* SubscriptionNavigationCoordinator.swift in Sources */, C1D21E2D293A5965006E5A05 /* AutofillLoginSession.swift in Sources */, diff --git a/DuckDuckGo/AutofillLoginSettingsListViewController.swift b/DuckDuckGo/AutofillLoginSettingsListViewController.swift index 7078a65db4..df88b9ef0f 100644 --- a/DuckDuckGo/AutofillLoginSettingsListViewController.swift +++ b/DuckDuckGo/AutofillLoginSettingsListViewController.swift @@ -220,7 +220,7 @@ final class AutofillLoginSettingsListViewController: UIViewController { let messageView = PasswordsSurveyView(surveyButtonAction: { [weak self] in let survey = "https://selfserve.decipherinc.com/survey/selfserve/32ab/240409" if let surveyURL = URL(string: survey) { - let surveyURLBuilder = DefaultSurveyURLBuilder() + let surveyURLBuilder = DefaultRemoteMessagingSurveyURLBuilder() let surveyURLWithParameters = surveyURLBuilder.addPasswordsCountSurveyParameter(to: surveyURL) LaunchTabNotification.postLaunchTabNotification(urlString: surveyURLWithParameters.absoluteString) } else { diff --git a/DuckDuckGo/HomeMessageViewModel.swift b/DuckDuckGo/HomeMessageViewModel.swift index e108700468..e6c7bbdd0c 100644 --- a/DuckDuckGo/HomeMessageViewModel.swift +++ b/DuckDuckGo/HomeMessageViewModel.swift @@ -139,20 +139,9 @@ struct HomeMessageViewModel { LaunchTabNotification.postLaunchTabNotification(urlString: value) onDidClose(buttonAction) } - case .surveyURL(let value): + case .survey(let value): return { -#if NETWORK_PROTECTION - if let surveyURL = URL(string: value) { - let surveyURLBuilder = DefaultSurveyURLBuilder() - let surveyURLWithParameters = surveyURLBuilder.addSurveyParameters(to: surveyURL) - LaunchTabNotification.postLaunchTabNotification(urlString: surveyURLWithParameters.absoluteString) - } else { - LaunchTabNotification.postLaunchTabNotification(urlString: value) - } -#else LaunchTabNotification.postLaunchTabNotification(urlString: value) -#endif - onDidClose(buttonAction) } case .appStore: diff --git a/DuckDuckGo/HomeMessageViewModelBuilder.swift b/DuckDuckGo/HomeMessageViewModelBuilder.swift index 4f54c60548..641be47a10 100644 --- a/DuckDuckGo/HomeMessageViewModelBuilder.swift +++ b/DuckDuckGo/HomeMessageViewModelBuilder.swift @@ -49,7 +49,7 @@ extension RemoteAction { case .share(let value, let title): return .share(value: value, title: title) - case .appStore, .url, .surveyURL: + case .appStore, .url, .survey: if isSecondaryAction { return .cancel } diff --git a/DuckDuckGo/RemoteMessaging.swift b/DuckDuckGo/RemoteMessaging.swift index c6117d0d14..a7ebf8dc4b 100644 --- a/DuckDuckGo/RemoteMessaging.swift +++ b/DuckDuckGo/RemoteMessaging.swift @@ -26,6 +26,7 @@ import Persistence import Bookmarks import RemoteMessaging import NetworkProtection +import Subscription struct RemoteMessaging { @@ -153,15 +154,12 @@ struct RemoteMessaging { case .success(let statusResponse): os_log("Successfully fetched remote messages", log: .remoteMessaging, type: .debug) - let daysSinceNetworkProtectionEnabled: Int + let isPrivacyProSubscriber = AppDependencyProvider.shared.subscriptionManager.accountManager.isUserAuthenticated + let canPurchase = AppDependencyProvider.shared.subscriptionManager.canPurchase -#if NETWORK_PROTECTION let activationDateStore = DefaultVPNActivationDateStore() - - daysSinceNetworkProtectionEnabled = activationDateStore.daysSinceActivation() ?? -1 -#else - daysSinceNetworkProtectionEnabled = -1 -#endif + let daysSinceNetworkProtectionEnabled = activationDateStore.daysSinceActivation() ?? -1 + let surveyActionMapper = DefaultRemoteMessagingSurveyURLBuilder(statisticsStore: statisticsStore) let remoteMessagingConfigMatcher = RemoteMessagingConfigMatcher( appAttributeMatcher: AppAttributeMatcher(statisticsStore: statisticsStore, @@ -173,8 +171,11 @@ struct RemoteMessaging { favoritesCount: favoritesCount, appTheme: AppUserDefaults().currentThemeName.rawValue, isWidgetInstalled: isWidgetInstalled, - daysSinceNetPEnabled: daysSinceNetworkProtectionEnabled), + daysSinceNetPEnabled: daysSinceNetworkProtectionEnabled, + isPrivacyProEligibleUser: canPurchase, + isPrivacyProSubscriber: isPrivacyProSubscriber), percentileStore: RemoteMessagingPercentileUserDefaultsStore(userDefaults: .standard), + surveyActionMapper: surveyActionMapper, dismissedMessageIds: remoteMessagingStore.fetchDismissedRemoteMessageIds() ) diff --git a/DuckDuckGo/SurveyURLBuilder.swift b/DuckDuckGo/RemoteMessagingSurveyURLBuilder.swift similarity index 82% rename from DuckDuckGo/SurveyURLBuilder.swift rename to DuckDuckGo/RemoteMessagingSurveyURLBuilder.swift index 6b072ce276..05b75d6118 100644 --- a/DuckDuckGo/SurveyURLBuilder.swift +++ b/DuckDuckGo/RemoteMessagingSurveyURLBuilder.swift @@ -1,5 +1,5 @@ // -// SurveyURLBuilder.swift +// RemoteMessagingSurveyURLBuilder.swift // DuckDuckGo // // Copyright © 2023 DuckDuckGo. All rights reserved. @@ -17,28 +17,13 @@ // limitations under the License. // -#if NETWORK_PROTECTION - import Foundation import BrowserServicesKit +import RemoteMessaging import Core import Common -protocol SurveyURLBuilder { - func addSurveyParameters(to url: URL) -> URL -} - -struct DefaultSurveyURLBuilder: SurveyURLBuilder { - - enum SurveyURLParameters: String, CaseIterable { - case atb = "atb" - case atbVariant = "var" - case daysSinceActivated = "delta" - case iosVersion = "mv" - case appVersion = "ddgv" - case hardwareModel = "mo" - case lastActiveDate = "da" - } +struct DefaultRemoteMessagingSurveyURLBuilder: RemoteMessagingSurveyActionMapping { private let statisticsStore: StatisticsStore private let activationDateStore: VPNActivationDateStore @@ -50,7 +35,7 @@ struct DefaultSurveyURLBuilder: SurveyURLBuilder { } // swiftlint:disable:next cyclomatic_complexity - func addSurveyParameters(to surveyURL: URL) -> URL { + func add(parameters: [RemoteMessagingSurveyActionParameter], to surveyURL: URL) -> URL { guard var components = URLComponents(string: surveyURL.absoluteString) else { assertionFailure("Could not build URL components from survey URL") return surveyURL @@ -58,7 +43,7 @@ struct DefaultSurveyURLBuilder: SurveyURLBuilder { var queryItems = components.queryItems ?? [] - for parameter in SurveyURLParameters.allCases { + for parameter in parameters { switch parameter { case .atb: if let atb = statisticsStore.atb { @@ -68,11 +53,7 @@ struct DefaultSurveyURLBuilder: SurveyURLBuilder { if let variant = statisticsStore.variant { queryItems.append(URLQueryItem(name: parameter.rawValue, value: variant)) } - case .daysSinceActivated: - if let daysSinceActivated = activationDateStore.daysSinceActivation() { - queryItems.append(URLQueryItem(name: parameter.rawValue, value: String(describing: daysSinceActivated))) - } - case .iosVersion: + case .osVersion: queryItems.append(URLQueryItem(name: parameter.rawValue, value: AppVersion.shared.osVersion)) case .appVersion: queryItems.append(URLQueryItem(name: parameter.rawValue, value: AppVersion.shared.versionAndBuildNumber)) @@ -83,6 +64,11 @@ struct DefaultSurveyURLBuilder: SurveyURLBuilder { if let daysSinceLastActive = activationDateStore.daysSinceLastActive() { queryItems.append(URLQueryItem(name: parameter.rawValue, value: String(describing: daysSinceLastActive))) } + case .daysInstalled: + if let installDate = statisticsStore.installDate, + let daysSinceInstall = Calendar.current.numberOfDaysBetween(installDate, and: Date()) { + queryItems.append(URLQueryItem(name: parameter.rawValue, value: String(describing: daysSinceInstall))) + } } } @@ -92,7 +78,7 @@ struct DefaultSurveyURLBuilder: SurveyURLBuilder { } func addPasswordsCountSurveyParameter(to surveyURL: URL) -> URL { - let surveyURLWithParameters = addSurveyParameters(to: surveyURL) + let surveyURLWithParameters = add(parameters: RemoteMessagingSurveyActionParameter.allCases, to: surveyURL) guard var components = URLComponents(string: surveyURLWithParameters.absoluteString), let bucket = passwordsCountBucket() else { return surveyURLWithParameters @@ -129,5 +115,3 @@ struct DefaultSurveyURLBuilder: SurveyURLBuilder { } } - -#endif diff --git a/DuckDuckGo/Subscription/ViewModel/SubscriptionContainerViewModel.swift b/DuckDuckGo/Subscription/ViewModel/SubscriptionContainerViewModel.swift index bf4042ebf6..9eaaa63130 100644 --- a/DuckDuckGo/Subscription/ViewModel/SubscriptionContainerViewModel.swift +++ b/DuckDuckGo/Subscription/ViewModel/SubscriptionContainerViewModel.swift @@ -36,6 +36,7 @@ final class SubscriptionContainerViewModel: ObservableObject { userScript: SubscriptionPagesUserScript, subFeature: SubscriptionPagesUseSubscriptionFeature) { self.userScript = userScript + subFeature.cleanup() self.subFeature = subFeature self.flow = SubscriptionFlowViewModel(origin: origin, userScript: userScript, @@ -49,7 +50,4 @@ final class SubscriptionContainerViewModel: ObservableObject { subscriptionManager: subscriptionManager) } - deinit { - subFeature.cleanup() - } } diff --git a/DuckDuckGo/Subscription/ViewModel/SubscriptionFlowViewModel.swift b/DuckDuckGo/Subscription/ViewModel/SubscriptionFlowViewModel.swift index b3469edc2a..1e4bc0f48d 100644 --- a/DuckDuckGo/Subscription/ViewModel/SubscriptionFlowViewModel.swift +++ b/DuckDuckGo/Subscription/ViewModel/SubscriptionFlowViewModel.swift @@ -102,7 +102,9 @@ final class SubscriptionFlowViewModel: ObservableObject { subFeature.onBackToSettings = { - self.state.shouldGoBackToSettings = true + DispatchQueue.main.async { + self.state.shouldGoBackToSettings = true + } } subFeature.onActivateSubscription = { diff --git a/DuckDuckGo/URLDownloadSession.swift b/DuckDuckGo/URLDownloadSession.swift index 85e4d5e6ae..c30169a6b2 100644 --- a/DuckDuckGo/URLDownloadSession.swift +++ b/DuckDuckGo/URLDownloadSession.swift @@ -39,7 +39,7 @@ class URLDownloadSession: NSObject, DownloadSession { self.session = session } else { let configuration = URLSessionConfiguration.ephemeral - let userAgent = DefaultUserAgentManager.shared.userAgent(isDesktop: false) + let userAgent = DefaultUserAgentManager.shared.userAgent(isDesktop: false, url: url) configuration.httpAdditionalHeaders = ["user-agent": userAgent] self.session = URLSession(configuration: configuration, delegate: self, delegateQueue: .main) } diff --git a/DuckDuckGo/UserText.swift b/DuckDuckGo/UserText.swift index b17f39e115..2336b71c83 100644 --- a/DuckDuckGo/UserText.swift +++ b/DuckDuckGo/UserText.swift @@ -985,7 +985,7 @@ But if you *do* want a peek under the hood, you can find more information about // Subscription Section public static let settingsPProSection = NSLocalizedString("settings.ppro", value: "Privacy Pro", comment: "Product name for the subscription bundle") public static let settingsPProSubscribe = NSLocalizedString("settings.subscription.subscribe", value: "Subscribe to Privacy Pro", comment: "Call to action title for Privacy Pro") - public static let settingsPProDescription = NSLocalizedString("settings.subscription.description", value:"More seamless privacy with three new protections, including:", comment: "Privacy pro description subtext") + public static let settingsPProDescription = NSLocalizedString("settings.subscription.description", value:"More seamless privacy with three new protections:", comment: "Privacy pro description subtext") public static let settingsPProFeatures = NSLocalizedString("settings.subscription.features", value: """ • VPN @@ -1004,7 +1004,7 @@ But if you *do* want a peek under the hood, you can find more information about public static let settingsPProITRTitle = NSLocalizedString("settings.subscription.ITR.title", value: "Identity Theft Restoration", comment: "Identity theft restoration cell title for privacy pro") public static let settingsPProITRSubTitle = NSLocalizedString("settings.subscription.ITR.subtitle", value: "If your identity is stolen, we'll help restore it", comment: "Identity theft restoration cell subtitle for privacy pro") - public static let settingsPProActivationPendingTitle = NSLocalizedString("settings.subscription.activation.pending.title", value: "Your Subscription is Being Activated", comment: "Subscription activation pending title") + public static let settingsPProActivationPendingTitle = NSLocalizedString("settings.subscription.activation.pending.title", value: "Your Subscription is being activated", comment: "Subscription activation pending title") public static let settingsPProActivationPendingDescription = NSLocalizedString("settings.subscription.activation.pending.description", value: "This is taking longer than usual, please check back later.", comment: "Subscription activation pending description") // Expired Subscription @@ -1122,7 +1122,7 @@ But if you *do* want a peek under the hood, you can find more information about public static let subscriptionRestoreAddEmailTitle = NSLocalizedString("subscription.add.email.title", value: "Add Email", comment: "View title for adding email to subscription") // Manage Subscription Email - public static let subscriptionManageEmailDescription = NSLocalizedString("subscription.manage.email.description", value: "You can use this email to activate your subscription from browser settings in the DuckDuckGo app on your other devices.", comment: "Description for Email Management options") + public static let subscriptionManageEmailDescription = NSLocalizedString("subscription.manage.email.description", value: "Use this email to activate your subscription from browser settings in the DuckDuckGo app on other devices..", comment: "Description for Email Management options") public static let subscriptionManageEmailButton = NSLocalizedString("subscription.activate.manage.email.button", value: "Manage", comment: "Restore button title for Managing Email") public static let subscriptionManageEmailTitle = NSLocalizedString("subscription.activate.manage.email.title", value: "Manage Email", comment: "View Title for managing your email account") public static let subscriptionManageEmailCancelButton = NSLocalizedString("subscription.activate.manage.email.cancel", value: "Cancel", comment: "Button title for cancelling email deletion") @@ -1161,7 +1161,7 @@ But if you *do* want a peek under the hood, you can find more information about public static let subscriptionPIRHeroDesktopMenuLocation = NSLocalizedString("subscription.pir.heroTextLocation", value: "Settings > Privacy Pro", comment: "Settings references a menu in the Desktop app, Privacy Pro, references our product name") public static let subscriptionPIRHeroDesktopMenuItem = NSLocalizedString("subscription.pir.heroTextMenyEntry", value: "I have a subscription", comment: "Menu item for enabling Personal Information Removal on Desktop") public static let subscriptionPIRWindows = NSLocalizedString("subscription.pir.windows", value: "Windows", comment: "Text for the 'Windows' button") - public static let subscriptionPIRMacOS = NSLocalizedString("subscription.pir.macos", value: "macOS", comment: "Text for the 'macOS' button") + public static let subscriptionPIRMacOS = NSLocalizedString("subscription.pir.macos", value: "Mac", comment: "Text for the 'macOS' button") // Autocomplete public static let autocompleteHistoryWarningTitle = NSLocalizedString("autocomplete.history.warning.title", value: "Same privacy.\nBetter search suggestions!", comment: "Title for message show in suggestions") diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index f4c3f330bb..e8e419c204 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -1899,7 +1899,7 @@ But if you *do* want a peek under the hood, you can find more information about "settings.subscription.activation.pending.description" = "This is taking longer than usual, please check back later."; /* Subscription activation pending title */ -"settings.subscription.activation.pending.title" = "Your Subscription is Being Activated"; +"settings.subscription.activation.pending.title" = "Your Subscription is being activated"; /* Data Broker protection cell subtitle for privacy pro */ "settings.subscription.DBP.subtitle" = "Remove your info from sites that sell it"; @@ -1908,7 +1908,7 @@ But if you *do* want a peek under the hood, you can find more information about "settings.subscription.DBP.title" = "Personal Information Removal"; /* Privacy pro description subtext */ -"settings.subscription.description" = "More seamless privacy with three new protections, including:"; +"settings.subscription.description" = "More seamless privacy with three new protections:"; /* I have a Subscription button text for privacy pro */ "settings.subscription.existing.subscription" = "I Have a Subscription"; @@ -2147,7 +2147,7 @@ But if you *do* want a peek under the hood, you can find more information about "subscription.manage.devices" = "Manage Devices"; /* Description for Email Management options */ -"subscription.manage.email.description" = "You can use this email to activate your subscription from browser settings in the DuckDuckGo app on your other devices."; +"subscription.manage.email.description" = "Use this email to activate your subscription from browser settings in the DuckDuckGo app on other devices.."; /* Manage Plan header */ "subscription.manage.plan" = "Manage Plan"; @@ -2180,7 +2180,7 @@ But if you *do* want a peek under the hood, you can find more information about "subscription.pir.heroTextMenyEntry" = "I have a subscription"; /* Text for the 'macOS' button */ -"subscription.pir.macos" = "macOS"; +"subscription.pir.macos" = "Mac"; /* Text for the 'Windows' button */ "subscription.pir.windows" = "Windows"; diff --git a/DuckDuckGoTests/MockUserAgent.swift b/DuckDuckGoTests/MockUserAgent.swift index ce8147a4c8..1e0ab0c086 100644 --- a/DuckDuckGoTests/MockUserAgent.swift +++ b/DuckDuckGoTests/MockUserAgent.swift @@ -48,6 +48,10 @@ class MockUserAgentManager: UserAgentManager { return userAgent.agent(forUrl: nil, isDesktop: isDesktop, privacyConfig: privacyConfig) } + func userAgent(isDesktop: Bool, url: URL?) -> String { + return userAgent.agent(forUrl: url, isDesktop: isDesktop) + } + public func update(request: inout URLRequest, isDesktop: Bool) { request.addValue(userAgent.agent(forUrl: nil, isDesktop: isDesktop, privacyConfig: privacyConfig), forHTTPHeaderField: "User-Agent") } diff --git a/DuckDuckGoTests/RemoteMessagingStoreTests.swift b/DuckDuckGoTests/RemoteMessagingStoreTests.swift index 87f5beb01e..191ae48b11 100644 --- a/DuckDuckGoTests/RemoteMessagingStoreTests.swift +++ b/DuckDuckGoTests/RemoteMessagingStoreTests.swift @@ -141,8 +141,11 @@ class RemoteMessagingStoreTests: XCTestCase { favoritesCount: 0, appTheme: "light", isWidgetInstalled: false, - daysSinceNetPEnabled: -1), + daysSinceNetPEnabled: -1, + isPrivacyProEligibleUser: false, + isPrivacyProSubscriber: false), percentileStore: RemoteMessagingPercentileUserDefaultsStore(userDefaults: self.defaults), + surveyActionMapper: MockRemoteMessagingSurveyActionMapper(), dismissedMessageIds: [] ) @@ -159,3 +162,11 @@ class RemoteMessagingStoreTests: XCTestCase { } } } + +private final class MockRemoteMessagingSurveyActionMapper: RemoteMessagingSurveyActionMapping { + + func add(parameters: [RemoteMessagingSurveyActionParameter], to url: URL) -> URL { + return url + } + +}