diff --git a/Configuration/Tests/UnitTestsAppStore.xcconfig b/Configuration/Tests/UnitTestsAppStore.xcconfig index a885a868ed..b31177d987 100644 --- a/Configuration/Tests/UnitTestsAppStore.xcconfig +++ b/Configuration/Tests/UnitTestsAppStore.xcconfig @@ -16,7 +16,7 @@ #include "UnitTests.xcconfig" #include "../AppStore.xcconfig" -FEATURE_FLAGS = FEEDBACK NETWORK_PROTECTION DBP +FEATURE_FLAGS = FEEDBACK NETWORK_PROTECTION DBP SUBSCRIPTION PRODUCT_BUNDLE_IDENTIFIER = com.duckduckgo.mobile.ios.DuckDuckGoTests diff --git a/DuckDuckGo/Menus/MainMenu.swift b/DuckDuckGo/Menus/MainMenu.swift index 835f52a061..2df71c787b 100644 --- a/DuckDuckGo/Menus/MainMenu.swift +++ b/DuckDuckGo/Menus/MainMenu.swift @@ -544,18 +544,20 @@ import SubscriptionUI } private func updateShortcutMenuItems() { - toggleAutofillShortcutMenuItem.title = LocalPinningManager.shared.shortcutTitle(for: .autofill) - toggleBookmarksShortcutMenuItem.title = LocalPinningManager.shared.shortcutTitle(for: .bookmarks) - toggleDownloadsShortcutMenuItem.title = LocalPinningManager.shared.shortcutTitle(for: .downloads) + Task { @MainActor in + toggleAutofillShortcutMenuItem.title = LocalPinningManager.shared.shortcutTitle(for: .autofill) + toggleBookmarksShortcutMenuItem.title = LocalPinningManager.shared.shortcutTitle(for: .bookmarks) + toggleDownloadsShortcutMenuItem.title = LocalPinningManager.shared.shortcutTitle(for: .downloads) #if NETWORK_PROTECTION - if NetworkProtectionKeychainTokenStore().isFeatureActivated { - toggleNetworkProtectionShortcutMenuItem.isHidden = false - toggleNetworkProtectionShortcutMenuItem.title = LocalPinningManager.shared.shortcutTitle(for: .networkProtection) - } else { - toggleNetworkProtectionShortcutMenuItem.isHidden = true - } + if await DefaultNetworkProtectionVisibility().isVPNVisible() { + toggleNetworkProtectionShortcutMenuItem.isHidden = false + toggleNetworkProtectionShortcutMenuItem.title = LocalPinningManager.shared.shortcutTitle(for: .networkProtection) + } else { + toggleNetworkProtectionShortcutMenuItem.isHidden = true + } #endif + } } // MARK: - Debug diff --git a/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift b/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift index 3ae0a5ab01..05868109ac 100644 --- a/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift +++ b/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift @@ -341,7 +341,7 @@ final class MoreOptionsMenu: NSMenu { #endif #if NETWORK_PROTECTION - if networkProtectionFeatureVisibility.isNetworkProtectionVisible() { + if networkProtectionFeatureVisibility.isNetworkProtectionBetaVisible() { let networkProtectionItem: NSMenuItem networkProtectionItem = makeNetworkProtectionItem() diff --git a/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift b/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift index d392da9c79..9f8bb87ab1 100644 --- a/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift +++ b/DuckDuckGo/NavigationBar/View/NavigationBarViewController.swift @@ -320,7 +320,7 @@ final class NavigationBarViewController: NSViewController { private func toggleNetworkProtectionPopover() { let featureVisibility = DefaultNetworkProtectionVisibility() - guard featureVisibility.isNetworkProtectionVisible() else { + guard featureVisibility.isNetworkProtectionBetaVisible() else { featureVisibility.disableForWaitlistUsers() LocalPinningManager.shared.unpin(.networkProtection) return @@ -405,7 +405,7 @@ final class NavigationBarViewController: NSViewController { self.updateHomeButton() #if NETWORK_PROTECTION case .networkProtection: - networkProtectionButtonModel.updateVisibility() + self.networkProtectionButtonModel.updateVisibility() #endif } } else { @@ -945,7 +945,7 @@ extension NavigationBarViewController: NSMenuDelegate { #if NETWORK_PROTECTION let isPopUpWindow = view.window?.isPopUpWindow ?? false - if !isPopUpWindow && networkProtectionFeatureActivation.isFeatureActivated { + if !isPopUpWindow && DefaultNetworkProtectionVisibility().isVPNVisible() { let networkProtectionTitle = LocalPinningManager.shared.shortcutTitle(for: .networkProtection) menu.addItem(withTitle: networkProtectionTitle, action: #selector(toggleNetworkProtectionPanelPinning), keyEquivalent: "N") } @@ -980,7 +980,7 @@ extension NavigationBarViewController: NSMenuDelegate { func showNetworkProtectionStatus() { let featureVisibility = DefaultNetworkProtectionVisibility() - if featureVisibility.isNetworkProtectionVisible() { + if featureVisibility.isNetworkProtectionBetaVisible() { popovers.showNetworkProtectionPopover(positionedBelow: networkProtectionButton, withDelegate: networkProtectionButtonModel) } else { diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarButtonModel.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarButtonModel.swift index b31c8f007f..5ee8f863a0 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarButtonModel.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarButtonModel.swift @@ -178,7 +178,7 @@ final class NetworkProtectionNavBarButtonModel: NSObject, ObservableObject { func updateVisibility() { // The button is visible in the case where NetP has not been activated, but the user has been invited and they haven't accepted T&Cs. let networkProtectionVisibility = DefaultNetworkProtectionVisibility() - if networkProtectionVisibility.isNetworkProtectionVisible() { + if networkProtectionVisibility.isNetworkProtectionBetaVisible() { if NetworkProtectionWaitlist().readyToAcceptTermsAndConditions { DailyPixel.fire(pixel: .networkProtectionWaitlistEntryPointToolbarButtonDisplayed, frequency: .dailyOnly, diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarPopoverManager.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarPopoverManager.swift index 331892d0f5..089a82f3f1 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarPopoverManager.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionNavBarPopoverManager.swift @@ -144,7 +144,7 @@ final class NetworkProtectionNavBarPopoverManager: NetPPopoverManager { } else { let featureVisibility = DefaultNetworkProtectionVisibility() - if featureVisibility.isNetworkProtectionVisible() { + if featureVisibility.isNetworkProtectionBetaVisible() { show(positionedBelow: view, withDelegate: delegate) } else { featureVisibility.disableForWaitlistUsers() diff --git a/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionIPCTunnelController.swift b/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionIPCTunnelController.swift index 9c27855554..1b03bfb3f8 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionIPCTunnelController.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionIPCTunnelController.swift @@ -83,7 +83,7 @@ final class NetworkProtectionIPCTunnelController: TunnelController { // MARK: - Login Items Manager private func enableLoginItems() async throws -> Bool { - guard try await featureVisibility.isFeatureEnabled() else { + guard try await featureVisibility.canStartVPN() else { // We shouldn't enable the menu app is the VPN feature is disabled. return false } diff --git a/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionRemoteMessaging/NetworkProtectionRemoteMessaging.swift b/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionRemoteMessaging/NetworkProtectionRemoteMessaging.swift index 2a4a2d3f36..382a4f1bd8 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionRemoteMessaging/NetworkProtectionRemoteMessaging.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/DeveloperIDTarget/NetworkProtectionRemoteMessaging/NetworkProtectionRemoteMessaging.swift @@ -133,7 +133,7 @@ final class DefaultNetworkProtectionRemoteMessaging: NetworkProtectionRemoteMess } // Next, check if the message requires access to NetP but it's not visible: - if message.requiresNetworkProtectionAccess, !networkProtectionVisibility.isNetworkProtectionVisible() { + if message.requiresNetworkProtectionAccess, !networkProtectionVisibility.isNetworkProtectionBetaVisible() { return false } diff --git a/DuckDuckGo/Preferences/Model/PreferencesSidebarModel.swift b/DuckDuckGo/Preferences/Model/PreferencesSidebarModel.swift index 7078235c82..b5ba825f14 100644 --- a/DuckDuckGo/Preferences/Model/PreferencesSidebarModel.swift +++ b/DuckDuckGo/Preferences/Model/PreferencesSidebarModel.swift @@ -108,26 +108,12 @@ final class PreferencesSidebarModel: ObservableObject { private func setupVPNPaneVisibility() { DefaultNetworkProtectionVisibility().onboardStatusPublisher .receive(on: DispatchQueue.main) - .sink { [weak self] onboardingStatus in + .sink { [weak self] _ in guard let self else { return } - if onboardingStatus != .completed && self.selectedPane == .vpn { - self.selectedPane = .general - } - self.refreshSections() } .store(in: &cancellables) - - UserDefaults.netP.publisher(for: \.networkProtectionEntitlementsExpired) - .receive(on: DispatchQueue.main) - .sink { [weak self] entitlementsExpired in - guard let self else { return } - if !entitlementsExpired && self.selectedPane == .vpn { - self.selectedPane = .general - } - self.refreshSections() - }.store(in: &cancellables) } #endif diff --git a/DuckDuckGo/Preferences/Model/VPNPreferencesModel.swift b/DuckDuckGo/Preferences/Model/VPNPreferencesModel.swift index 8e062d7e27..54ead02220 100644 --- a/DuckDuckGo/Preferences/Model/VPNPreferencesModel.swift +++ b/DuckDuckGo/Preferences/Model/VPNPreferencesModel.swift @@ -61,7 +61,7 @@ final class VPNPreferencesModel: ObservableObject { private var onboardingStatus: OnboardingStatus { didSet { - showUninstallVPN = onboardingStatus != .default + showUninstallVPN = DefaultNetworkProtectionVisibility().isInstalled } } diff --git a/DuckDuckGo/Waitlist/NetworkProtectionFeatureDisabler.swift b/DuckDuckGo/Waitlist/NetworkProtectionFeatureDisabler.swift index c15bb6568e..ba12c9cdd2 100644 --- a/DuckDuckGo/Waitlist/NetworkProtectionFeatureDisabler.swift +++ b/DuckDuckGo/Waitlist/NetworkProtectionFeatureDisabler.swift @@ -62,24 +62,9 @@ final class NetworkProtectionFeatureDisabler: NetworkProtectionFeatureDisabling self.ipcClient = ipcClient } - private var isSystemExtensionInstalled: Bool { -#if NETP_SYSTEM_EXTENSION - userDefaults.networkProtectionOnboardingStatus != .isOnboarding(step: .userNeedsToAllowExtension) -#else - return false -#endif - } - - private var isVPNConfigurationInstalled: Bool { - userDefaults.networkProtectionOnboardingStatus == .completed - } - @MainActor private func canUninstall(includingSystemExtension: Bool) -> Bool { - !isDisabling - && LoginItem.vpnMenu.status.isInstalled - && ((includingSystemExtension && isSystemExtensionInstalled) - || isVPNConfigurationInstalled) + !isDisabling && LoginItem.vpnMenu.status.isInstalled } /// This method disables the VPN and clear all of its state. @@ -93,17 +78,17 @@ final class NetworkProtectionFeatureDisabler: NetworkProtectionFeatureDisabling func disable(keepAuthToken: Bool, uninstallSystemExtension: Bool) async -> Bool { // To disable NetP we need the login item to be running // This should be fine though as we'll disable them further down below + guard canUninstall(includingSystemExtension: uninstallSystemExtension) else { + return true + } + + isDisabling = true defer { unpinNetworkProtection() resetUserDefaults(uninstallSystemExtension: uninstallSystemExtension) } - guard canUninstall(includingSystemExtension: uninstallSystemExtension) else { - return true - } - - isDisabling = true enableLoginItems() // Allow some time for the login items to fully launch diff --git a/DuckDuckGo/Waitlist/NetworkProtectionFeatureVisibility.swift b/DuckDuckGo/Waitlist/NetworkProtectionFeatureVisibility.swift index db7eb7c5a5..28f9299290 100644 --- a/DuckDuckGo/Waitlist/NetworkProtectionFeatureVisibility.swift +++ b/DuckDuckGo/Waitlist/NetworkProtectionFeatureVisibility.swift @@ -33,9 +33,11 @@ import Subscription protocol NetworkProtectionFeatureVisibility { var isEligibleForThankYouMessage: Bool { get } + var isInstalled: Bool { get } - func isFeatureEnabled() async throws -> Bool - func isNetworkProtectionVisible() -> Bool + func canStartVPN() async throws -> Bool + func isVPNVisible() -> Bool + func isNetworkProtectionBetaVisible() -> Bool func shouldUninstallAutomatically() -> Bool func disableForAllUsers() async func disableForWaitlistUsers() @@ -77,19 +79,22 @@ struct DefaultNetworkProtectionVisibility: NetworkProtectionFeatureVisibility { /// 2. If no auth token is found, the feature is visible if the waitlist feature flag is enabled /// /// Once the waitlist beta has ended, we can trigger a remote change that removes the user's auth token and turn off the waitlist flag, hiding the VPN from the user. - func isNetworkProtectionVisible() -> Bool { + func isNetworkProtectionBetaVisible() -> Bool { return isEasterEggUser || waitlistIsOngoing } var isInstalled: Bool { - LoginItem.vpnMenu.status.isInstalled && isOnboarded + LoginItem.vpnMenu.status.isInstalled } - /// Replaces `isNetworkProtectionVisible` to add subscriptions support + /// Whether the user can start the VPN. /// - func isFeatureEnabled() async throws -> Bool { + /// For beta users this means they have an auth token. + /// For subscription users this means they have entitlements. + /// + func canStartVPN() async throws -> Bool { guard subscriptionFeatureAvailability.isFeatureAvailable else { - return isNetworkProtectionVisible() + return isNetworkProtectionBetaVisible() } switch await AccountManager().hasEntitlement(for: .networkProtection) { @@ -100,6 +105,19 @@ struct DefaultNetworkProtectionVisibility: NetworkProtectionFeatureVisibility { } } + /// Whether the user can see the VPN entry points in the UI. + /// + /// For beta users this means they have an auth token. + /// For subscription users this means they are authenticated. + /// + func isVPNVisible() -> Bool { + guard subscriptionFeatureAvailability.isFeatureAvailable else { + return isNetworkProtectionBetaVisible() + } + + return AccountManager().isUserAuthenticated + } + /// We've had to add this method because accessing the singleton in app delegate is crashing the integration tests. /// var subscriptionFeatureAvailability: DefaultSubscriptionFeatureAvailability { diff --git a/DuckDuckGoVPN/NetworkProtectionBouncer.swift b/DuckDuckGoVPN/NetworkProtectionBouncer.swift index 3ab9ee5e6b..f50152e122 100644 --- a/DuckDuckGoVPN/NetworkProtectionBouncer.swift +++ b/DuckDuckGoVPN/NetworkProtectionBouncer.swift @@ -36,23 +36,9 @@ final class NetworkProtectionBouncer { func requireAuthTokenOrKillApp(controller: TunnelController) async { #if SUBSCRIPTION let accountManager = AccountManager(subscriptionAppGroup: Bundle.main.appGroup(bundle: .subs)) - let result = await accountManager.hasEntitlement(for: .networkProtection, cachePolicy: .reloadIgnoringLocalCacheData) - switch result { - case .success(true): - return - case .failure: - guard accountManager.accessToken == nil else { - return - } - case .success(false): - os_log(.error, log: .networkProtection, "🔴 Stopping: DuckDuckGo VPN not authorized. Missing entitlement.") - await controller.stop() - // EXIT_SUCCESS ensures the login item won't relaunch - // Ref: https://developer.apple.com/documentation/servicemanagement/smappservice/register() - // See where it mentions: - // "If the helper crashes or exits with a non-zero status, the system relaunches it" - exit(EXIT_SUCCESS) + guard !accountManager.isUserAuthenticated else { + return } #endif let keychainStore = NetworkProtectionKeychainTokenStore(keychainType: .default, diff --git a/UnitTests/Menus/MoreOptionsMenuTests.swift b/UnitTests/Menus/MoreOptionsMenuTests.swift index 7cf4b36222..05b355614a 100644 --- a/UnitTests/Menus/MoreOptionsMenuTests.swift +++ b/UnitTests/Menus/MoreOptionsMenuTests.swift @@ -18,6 +18,10 @@ import XCTest +#if SUBSCRIPTION +import Subscription +#endif + #if NETWORK_PROTECTION import NetworkProtection #endif @@ -62,7 +66,7 @@ final class MoreOptionsMenuTests: XCTestCase { internalUserDecider = InternalUserDeciderMock() #if NETWORK_PROTECTION - networkProtectionVisibilityMock = NetworkProtectionVisibilityMock(visible: false) + networkProtectionVisibilityMock = NetworkProtectionVisibilityMock(isInstalled: false, visible: false) #endif } @@ -80,7 +84,7 @@ final class MoreOptionsMenuTests: XCTestCase { #if NETWORK_PROTECTION moreOptionMenu = MoreOptionsMenu(tabCollectionViewModel: tabCollectionViewModel, passwordManagerCoordinator: passwordManagerCoordinator, - networkProtectionFeatureVisibility: NetworkProtectionVisibilityMock(visible: true), + networkProtectionFeatureVisibility: NetworkProtectionVisibilityMock(isInstalled: false, visible: true), sharingMenu: NSMenu(), internalUserDecider: internalUserDecider) #else @@ -105,10 +109,18 @@ final class MoreOptionsMenuTests: XCTestCase { XCTAssertEqual(moreOptionMenu.items[12].title, UserText.emailOptionsMenuItem) #if NETWORK_PROTECTION - XCTAssertTrue(moreOptionMenu.items[13].isSeparatorItem) - XCTAssertTrue(moreOptionMenu.items[14].title.hasPrefix(UserText.networkProtection)) - XCTAssertTrue(moreOptionMenu.items[15].isSeparatorItem) - XCTAssertEqual(moreOptionMenu.items[16].title, UserText.settings) + if AccountManager().isUserAuthenticated { + XCTAssertTrue(moreOptionMenu.items[13].isSeparatorItem) + XCTAssertTrue(moreOptionMenu.items[14].title.hasPrefix(UserText.networkProtection)) + XCTAssertTrue(moreOptionMenu.items[15].title.hasPrefix(UserText.identityTheftRestorationOptionsMenuItem)) + XCTAssertTrue(moreOptionMenu.items[16].isSeparatorItem) + XCTAssertEqual(moreOptionMenu.items[17].title, UserText.settings) + } else { + XCTAssertTrue(moreOptionMenu.items[13].isSeparatorItem) + XCTAssertTrue(moreOptionMenu.items[14].title.hasPrefix(UserText.networkProtection)) + XCTAssertTrue(moreOptionMenu.items[15].isSeparatorItem) + XCTAssertEqual(moreOptionMenu.items[16].title, UserText.settings) + } #else XCTAssertTrue(moreOptionMenu.items[13].isSeparatorItem) XCTAssertEqual(moreOptionMenu.items[14].title, UserText.settings) @@ -120,7 +132,7 @@ final class MoreOptionsMenuTests: XCTestCase { #if NETWORK_PROTECTION moreOptionMenu = MoreOptionsMenu(tabCollectionViewModel: tabCollectionViewModel, passwordManagerCoordinator: passwordManagerCoordinator, - networkProtectionFeatureVisibility: NetworkProtectionVisibilityMock(visible: false), + networkProtectionFeatureVisibility: NetworkProtectionVisibilityMock(isInstalled: false, visible: false), sharingMenu: NSMenu(), internalUserDecider: internalUserDecider) #else @@ -143,8 +155,20 @@ final class MoreOptionsMenuTests: XCTestCase { XCTAssertEqual(moreOptionMenu.items[10].title, UserText.passwordManagement) XCTAssertTrue(moreOptionMenu.items[11].isSeparatorItem) XCTAssertEqual(moreOptionMenu.items[12].title, UserText.emailOptionsMenuItem) +#if SUBSCRIPTION + XCTAssertTrue(moreOptionMenu.items[13].isSeparatorItem) + + if AccountManager().isUserAuthenticated { + XCTAssertTrue(moreOptionMenu.items[14].title.hasPrefix(UserText.identityTheftRestorationOptionsMenuItem)) + XCTAssertTrue(moreOptionMenu.items[15].isSeparatorItem) + XCTAssertEqual(moreOptionMenu.items[16].title, UserText.settings) + } else { + XCTAssertEqual(moreOptionMenu.items[14].title, UserText.settings) + } +#else XCTAssertTrue(moreOptionMenu.items[13].isSeparatorItem) XCTAssertEqual(moreOptionMenu.items[14].title, UserText.settings) +#endif } // MARK: Zoom @@ -166,8 +190,7 @@ final class MoreOptionsMenuTests: XCTestCase { @MainActor func testWhenClickingOnPreferenceMenuItemThenTheActionDelegateIsAlerted() { - moreOptionMenu.performActionForItem(at: 14) - + moreOptionMenu.performActionForItem(at: moreOptionMenu.items.count - 1) XCTAssertTrue(capturingActionDelegate.optionsButtonMenuRequestedPreferencesCalled) } @@ -176,21 +199,27 @@ final class MoreOptionsMenuTests: XCTestCase { #if NETWORK_PROTECTION final class NetworkProtectionVisibilityMock: NetworkProtectionFeatureVisibility { + var isInstalled: Bool var visible: Bool - init(visible: Bool) { + init(isInstalled: Bool, visible: Bool) { + self.isInstalled = isInstalled self.visible = visible } + func isVPNVisible() -> Bool { + return visible + } + func shouldUninstallAutomatically() -> Bool { return !visible } - func isNetworkProtectionVisible() -> Bool { + func isNetworkProtectionBetaVisible() -> Bool { return visible } - func isFeatureEnabled() async throws -> Bool { + func canStartVPN() async throws -> Bool { return false } diff --git a/UnitTests/NetworkProtection/NetworkProtectionRemoteMessagingTests.swift b/UnitTests/NetworkProtection/NetworkProtectionRemoteMessagingTests.swift index 33eec679ee..761f184335 100644 --- a/UnitTests/NetworkProtection/NetworkProtectionRemoteMessagingTests.swift +++ b/UnitTests/NetworkProtection/NetworkProtectionRemoteMessagingTests.swift @@ -37,7 +37,7 @@ final class NetworkProtectionRemoteMessagingTests: XCTestCase { let storage = MockNetworkProtectionRemoteMessagingStorage() let waitlistStorage = MockWaitlistStorage() let activationDateStorage = MockWaitlistActivationDateStore() - let visibility = NetworkProtectionVisibilityMock(visible: true) + let visibility = NetworkProtectionVisibilityMock(isInstalled: false, visible: true) let messaging = DefaultNetworkProtectionRemoteMessaging( messageRequest: request, @@ -67,7 +67,7 @@ final class NetworkProtectionRemoteMessagingTests: XCTestCase { let storage = MockNetworkProtectionRemoteMessagingStorage() let waitlistStorage = MockWaitlistStorage() let activationDateStorage = MockWaitlistActivationDateStore() - let visibility = NetworkProtectionVisibilityMock(visible: true) + let visibility = NetworkProtectionVisibilityMock(isInstalled: false, visible: true) request.result = .success([]) waitlistStorage.store(waitlistToken: "token") @@ -103,7 +103,7 @@ final class NetworkProtectionRemoteMessagingTests: XCTestCase { let storage = MockNetworkProtectionRemoteMessagingStorage() let waitlistStorage = MockWaitlistStorage() let activationDateStorage = MockWaitlistActivationDateStore() - let visibility = NetworkProtectionVisibilityMock(visible: true) + let visibility = NetworkProtectionVisibilityMock(isInstalled: false, visible: true) let messages = [mockMessage(id: "123")] @@ -144,7 +144,7 @@ final class NetworkProtectionRemoteMessagingTests: XCTestCase { let storage = MockNetworkProtectionRemoteMessagingStorage() let waitlistStorage = MockWaitlistStorage() let activationDateStorage = MockWaitlistActivationDateStore() - let visibility = NetworkProtectionVisibilityMock(visible: true) + let visibility = NetworkProtectionVisibilityMock(isInstalled: false, visible: true) waitlistStorage.store(waitlistToken: "token") waitlistStorage.store(waitlistTimestamp: 123) @@ -183,7 +183,7 @@ final class NetworkProtectionRemoteMessagingTests: XCTestCase { let storage = MockNetworkProtectionRemoteMessagingStorage() let waitlistStorage = MockWaitlistStorage() let activationDateStorage = MockWaitlistActivationDateStore() - let visibility = NetworkProtectionVisibilityMock(visible: true) + let visibility = NetworkProtectionVisibilityMock(isInstalled: false, visible: true) let dismissedMessage = mockMessage(id: "123") let activeMessage = mockMessage(id: "456") @@ -212,7 +212,7 @@ final class NetworkProtectionRemoteMessagingTests: XCTestCase { let storage = MockNetworkProtectionRemoteMessagingStorage() let waitlistStorage = MockWaitlistStorage() let activationDateStorage = MockWaitlistActivationDateStore() - let visibility = NetworkProtectionVisibilityMock(visible: true) + let visibility = NetworkProtectionVisibilityMock(isInstalled: false, visible: true) let hiddenMessage = mockMessage(id: "123", daysSinceNetworkProtectionEnabled: 10) let activeMessage = mockMessage(id: "456") @@ -238,7 +238,7 @@ final class NetworkProtectionRemoteMessagingTests: XCTestCase { let storage = MockNetworkProtectionRemoteMessagingStorage() let waitlistStorage = MockWaitlistStorage() let activationDateStorage = MockWaitlistActivationDateStore() - let visibility = NetworkProtectionVisibilityMock(visible: false) + let visibility = NetworkProtectionVisibilityMock(isInstalled: false, visible: false) let hiddenMessage = mockMessage(id: "123", requiresNetPAccess: true) try? storage.store(messages: [hiddenMessage]) @@ -262,7 +262,7 @@ final class NetworkProtectionRemoteMessagingTests: XCTestCase { let storage = MockNetworkProtectionRemoteMessagingStorage() let waitlistStorage = MockWaitlistStorage() let activationDateStorage = MockWaitlistActivationDateStore() - let visibility = NetworkProtectionVisibilityMock(visible: true) + let visibility = NetworkProtectionVisibilityMock(isInstalled: false, visible: true) let message = mockMessage(id: "123", requiresNetPUsage: false, requiresNetPAccess: true) try? storage.store(messages: [message])