diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index cff2085141..3a617e57b3 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -14675,8 +14675,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { - kind = exactVersion; - version = 201.0.0; + branch = "sabrina/onboarding-import-state"; + kind = branch; }; }; 9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 51a522e596..189e309997 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/BrowserServicesKit", "state" : { - "revision" : "e5946eee6af859690cc1cc5e51daef3c8368981b", - "version" : "201.0.0" + "branch" : "sabrina/onboarding-import-state", + "revision" : "05ea8316abb7cf3ba312b749b09ea2a437aa188a" } }, { @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/content-scope-scripts", "state" : { - "revision" : "b74549bd869fdecc16fad851f2f608b1724764df", - "version" : "6.25.0" + "branch" : "pr-releases/pr-1180", + "revision" : "551d15fcadecd1e8cddd0dca625358e8bf1fb3fa" } }, { @@ -50,8 +50,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/duckduckgo-autofill.git", "state" : { - "revision" : "945ac09a0189dc6736db617867fde193ea984b20", - "version" : "15.0.0" + "revision" : "c992041d16ec10d790e6204dce9abf9966d1363c", + "version" : "15.1.0" } }, { diff --git a/DuckDuckGo/HomePage/Model/DataImportStatusProviding.swift b/DuckDuckGo/HomePage/Model/DataImportStatusProviding.swift index 17efd1a64d..79dcfc6c51 100644 --- a/DuckDuckGo/HomePage/Model/DataImportStatusProviding.swift +++ b/DuckDuckGo/HomePage/Model/DataImportStatusProviding.swift @@ -23,7 +23,7 @@ import PixelKit protocol DataImportStatusProviding { var didImport: Bool { get } - func showImportWindow(completion: (() -> Void)?) + func showImportWindow(customTitle: String?, completion: (() -> Void)?) } final class BookmarksAndPasswordsImportStatusProvider: DataImportStatusProviding { @@ -50,8 +50,8 @@ final class BookmarksAndPasswordsImportStatusProvider: DataImportStatusProviding } @MainActor - func showImportWindow(completion: (() -> Void)?) { - DataImportView().show(completion: completion) + func showImportWindow(customTitle: String?, completion: (() -> Void)?) { + DataImportView(title: customTitle ?? UserText.importDataTitle).show(completion: completion) } // It only cover the case in which the user has imported bookmar AFTER already having some bookmarks diff --git a/DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift b/DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift index a4b90a6a4c..9ae76d5bc7 100644 --- a/DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift +++ b/DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift @@ -145,7 +145,7 @@ extension HomePage.Models { } private func performImportBookmarksAndPasswordsAction() { - dataImportProvider.showImportWindow(completion: { self.refreshFeaturesMatrix() }) + dataImportProvider.showImportWindow(customTitle: nil, completion: { self.refreshFeaturesMatrix() }) } @MainActor diff --git a/DuckDuckGo/Onboarding/OnboardingActionsManager.swift b/DuckDuckGo/Onboarding/OnboardingActionsManager.swift index 1ba94165b9..f8ddb0b380 100644 --- a/DuckDuckGo/Onboarding/OnboardingActionsManager.swift +++ b/DuckDuckGo/Onboarding/OnboardingActionsManager.swift @@ -48,7 +48,7 @@ protocol OnboardingActionsManaging { func addToDock() /// At user imput shows the import data flow - func importData() + func importData() async -> Bool /// At user imput shows the system prompt to change default browser func setAsDefault() @@ -83,6 +83,7 @@ final class OnboardingActionsManager: OnboardingActionsManaging { private let defaultBrowserProvider: DefaultBrowserProvider private let appearancePreferences: AppearancePreferences private let startupPreferences: StartupPreferences + private let dataImportProvider: DataImportStatusProviding private var cancellables = Set() @UserDefaultsWrapper(key: .onboardingFinished, defaultValue: false) @@ -109,12 +110,18 @@ final class OnboardingActionsManager: OnboardingActionsManaging { return OnboardingConfiguration(stepDefinitions: stepDefinitions, exclude: [], order: order, env: env, locale: preferredLocale, platform: platform) }() - init(navigationDelegate: OnboardingNavigating, dockCustomization: DockCustomization, defaultBrowserProvider: DefaultBrowserProvider, appearancePreferences: AppearancePreferences, startupPreferences: StartupPreferences) { + init(navigationDelegate: OnboardingNavigating, + dockCustomization: DockCustomization, + defaultBrowserProvider: DefaultBrowserProvider, + appearancePreferences: AppearancePreferences, + startupPreferences: StartupPreferences, + dataImportProvider: DataImportStatusProviding = BookmarksAndPasswordsImportStatusProvider()) { self.navigation = navigationDelegate self.dockCustomization = dockCustomization self.defaultBrowserProvider = defaultBrowserProvider self.appearancePreferences = appearancePreferences self.startupPreferences = startupPreferences + self.dataImportProvider = dataImportProvider } func onboardingStarted() { @@ -148,8 +155,16 @@ final class OnboardingActionsManager: OnboardingActionsManaging { } @MainActor - func importData() { - navigation.showImportDataView() + func importData() async -> Bool { + return await withCheckedContinuation { continuation in + dataImportProvider.showImportWindow(customTitle: UserText.importDataTitleOnboarding, completion: { [weak self] in + guard let self else { + continuation.resume(returning: false) + return + } + continuation.resume(returning: self.dataImportProvider.didImport) + }) + } } func setAsDefault() { diff --git a/DuckDuckGo/Onboarding/OnboardingConfiguration.swift b/DuckDuckGo/Onboarding/OnboardingConfiguration.swift index 9477fe183c..d9f03fd5d9 100644 --- a/DuckDuckGo/Onboarding/OnboardingConfiguration.swift +++ b/DuckDuckGo/Onboarding/OnboardingConfiguration.swift @@ -40,3 +40,7 @@ struct SystemSettings: Codable, Equatable { struct OnboardingPlatform: Codable, Equatable { var name: String } + +struct OnboardingImportResponse: Codable, Equatable { + var enabled: Bool +} diff --git a/DuckDuckGo/Onboarding/OnboardingUserScript.swift b/DuckDuckGo/Onboarding/OnboardingUserScript.swift index a5120ce22a..adc92457bf 100644 --- a/DuckDuckGo/Onboarding/OnboardingUserScript.swift +++ b/DuckDuckGo/Onboarding/OnboardingUserScript.swift @@ -109,8 +109,8 @@ extension OnboardingUserScript { @MainActor private func requestImport(params: Any, original: WKScriptMessage) async throws -> Encodable? { - onboardingActionsManager.importData() - return Result() + let isDataImported = await onboardingActionsManager.importData() + return OnboardingImportResponse(enabled: isDataImported) } private func requestSetAsDefault(params: Any, original: WKScriptMessage) async throws -> Encodable? { diff --git a/UnitTests/HomePage/Mocks/CapturingDataImportProvider.swift b/UnitTests/HomePage/Mocks/CapturingDataImportProvider.swift index b09c71c6a3..8f03f1727b 100644 --- a/UnitTests/HomePage/Mocks/CapturingDataImportProvider.swift +++ b/UnitTests/HomePage/Mocks/CapturingDataImportProvider.swift @@ -20,10 +20,11 @@ import Foundation @testable import DuckDuckGo_Privacy_Browser class CapturingDataImportProvider: DataImportStatusProviding { + var showImportWindowCalled = false var didImport = false - func showImportWindow(completion: (() -> Void)?) { + func showImportWindow(customTitle: String?, completion: (() -> Void)?) { showImportWindowCalled = true completion?() } diff --git a/UnitTests/Onboarding/Mocks/CapturingOnboardingActionsManager.swift b/UnitTests/Onboarding/Mocks/CapturingOnboardingActionsManager.swift index afe4a93bb6..ac94a161c6 100644 --- a/UnitTests/Onboarding/Mocks/CapturingOnboardingActionsManager.swift +++ b/UnitTests/Onboarding/Mocks/CapturingOnboardingActionsManager.swift @@ -62,8 +62,9 @@ class CapturingOnboardingActionsManager: OnboardingActionsManaging { addToDockCalled = true } - func importData() { + func importData() async -> Bool { importDataCalled = true + return true } func setAsDefault() { diff --git a/UnitTests/Onboarding/OnboardingManagerTests.swift b/UnitTests/Onboarding/OnboardingManagerTests.swift index 0d5bdad199..660259c345 100644 --- a/UnitTests/Onboarding/OnboardingManagerTests.swift +++ b/UnitTests/Onboarding/OnboardingManagerTests.swift @@ -30,6 +30,7 @@ class OnboardingManagerTests: XCTestCase { var startupPreferences: StartupPreferences! var appearancePersistor: MockAppearancePreferencesPersistor! var startupPersistor: StartupPreferencesUserDefaultsPersistor! + var importProvider: CapturingDataImportProvider! @MainActor override func setUp() { super.setUp() @@ -40,7 +41,8 @@ class OnboardingManagerTests: XCTestCase { appearancePreferences = AppearancePreferences(persistor: appearancePersistor) startupPersistor = StartupPreferencesUserDefaultsPersistor() startupPreferences = StartupPreferences(appearancePreferences: appearancePreferences, persistor: startupPersistor) - manager = OnboardingActionsManager(navigationDelegate: navigationDelegate, dockCustomization: dockCustomization, defaultBrowserProvider: defaultBrowserProvider, appearancePreferences: appearancePreferences, startupPreferences: startupPreferences) + importProvider = CapturingDataImportProvider() + manager = OnboardingActionsManager(navigationDelegate: navigationDelegate, dockCustomization: dockCustomization, defaultBrowserProvider: defaultBrowserProvider, appearancePreferences: appearancePreferences, startupPreferences: startupPreferences, dataImportProvider: importProvider) } override func tearDown() { @@ -151,12 +153,16 @@ class OnboardingManagerTests: XCTestCase { } @MainActor - func testOnImportData_DataImportViewShown() { + func testOnImportData_DataImportViewShown() async { + // Given + importProvider.didImport = true + // When - manager.importData() + let didImport = await manager.importData() // Then - XCTAssertTrue(navigationDelegate.showImportDataViewCalled) + XCTAssertTrue(importProvider.showImportWindowCalled) + XCTAssertTrue(didImport) } func testOnAddToDock_IsAddedToDock() {