From 2a58f7037b1b76dfae538f03157bb7ab428e4efd Mon Sep 17 00:00:00 2001 From: Dominik Kapusta Date: Wed, 11 Dec 2024 15:27:46 +0100 Subject: [PATCH] Add unit tests for NewTabPageNextStepsCardsProvider --- DuckDuckGo.xcodeproj/project.pbxproj | 13 +- .../NewTabPageNextStepsCardsProvider.swift | 2 +- ...ewTabPageNextStepsCardsProviderTests.swift | 121 ++++++++++++++++++ 3 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 UnitTests/NewTabPage/NewTabPageNextStepsCardsProviderTests.swift diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 5c77de7536..58525998ca 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 70; objects = { /* Begin PBXBuildFile section */ @@ -5000,6 +5000,10 @@ FD23FD2C2886A81D007F6985 /* AutoconsentManagement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoconsentManagement.swift; sourceTree = ""; }; /* End PBXFileReference section */ +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 3792D51A2D09C72200FC15D6 /* NewTabPage */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = NewTabPage; sourceTree = ""; }; +/* End PBXFileSystemSynchronizedRootGroup section */ + /* Begin PBXFrameworksBuildPhase section */ 3706FCA6293F65D500E42796 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; @@ -8035,6 +8039,7 @@ 1D3B1AB7293405F5006F4388 /* PasswordManagers */, B6106BA126A7BE430013B453 /* Permissions */, CD34F0BE2C886462006826BE /* MaliciousSiteProtection */, + 3792D51A2D09C72200FC15D6 /* NewTabPage */, 37D2377E287EFECD00BCE03B /* PinnedTabs */, 4B0511EE262CAEB300F6079C /* Preferences */, 31E163BB293A577200963C10 /* PrivacyReferenceTests */, @@ -9975,6 +9980,9 @@ B6AEB5552BA3042300781A09 /* PBXTargetDependency */, 37079A93294236F20031BB3C /* PBXTargetDependency */, ); + fileSystemSynchronizedGroups = ( + 3792D51A2D09C72200FC15D6 /* NewTabPage */, + ); name = "Unit Tests App Store"; packageProductDependencies = ( 3706FDD6293F661700E42796 /* OHHTTPStubs */, @@ -10462,6 +10470,9 @@ B6E6BA1D2BA2E049008AA7E1 /* PBXTargetDependency */, B6CAC23D2B8F0EC6006CD402 /* PBXTargetDependency */, ); + fileSystemSynchronizedGroups = ( + 3792D51A2D09C72200FC15D6 /* NewTabPage */, + ); name = "Unit Tests"; packageProductDependencies = ( B6DA44162616C13800DD1EC2 /* OHHTTPStubs */, diff --git a/DuckDuckGo/NewTabPage/NewTabPageNextStepsCardsProvider.swift b/DuckDuckGo/NewTabPage/NewTabPageNextStepsCardsProvider.swift index 0fd6e72036..b56558e98e 100644 --- a/DuckDuckGo/NewTabPage/NewTabPageNextStepsCardsProvider.swift +++ b/DuckDuckGo/NewTabPage/NewTabPageNextStepsCardsProvider.swift @@ -53,7 +53,7 @@ final class NewTabPageNextStepsCardsProvider: NewTabPageNextStepsCardsProviding var cardsPublisher: AnyPublisher<[NewTabPageNextStepsCardsClient.CardID], Never> { let features = continueSetUpModel.$featuresMatrix.dropFirst().removeDuplicates() - let cardsDidBecomeOutdated = appearancePreferences.$isContinueSetUpCardsViewOutdated.dropFirst().removeDuplicates() + let cardsDidBecomeOutdated = appearancePreferences.$isContinueSetUpCardsViewOutdated.removeDuplicates() return Publishers.CombineLatest(features, cardsDidBecomeOutdated) .map { features, isOutdated -> [NewTabPageNextStepsCardsClient.CardID] in diff --git a/UnitTests/NewTabPage/NewTabPageNextStepsCardsProviderTests.swift b/UnitTests/NewTabPage/NewTabPageNextStepsCardsProviderTests.swift new file mode 100644 index 0000000000..4b9f30a79a --- /dev/null +++ b/UnitTests/NewTabPage/NewTabPageNextStepsCardsProviderTests.swift @@ -0,0 +1,121 @@ +// +// NewTabPageNextStepsCardsProviderTests.swift +// +// Copyright © 2024 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import BrowserServicesKit +import Combine +import NewTabPage +import XCTest +@testable import DuckDuckGo_Privacy_Browser + +final class NewTabPageNextStepsCardsProviderTests: XCTestCase { + var provider: NewTabPageNextStepsCardsProvider! + + @MainActor + override func setUp() async throws { + let privacyConfigManager = MockPrivacyConfigurationManager() + let config = MockPrivacyConfiguration() + privacyConfigManager.privacyConfig = config + + let continueSetUpModel = HomePage.Models.ContinueSetUpModel( + defaultBrowserProvider: CapturingDefaultBrowserProvider(), + dockCustomizer: DockCustomizerMock(), + dataImportProvider: CapturingDataImportProvider(), + tabOpener: TabCollectionViewModelTabOpener(tabCollectionViewModel: TabCollectionViewModel()), + emailManager: EmailManager(storage: MockEmailStorage()), + duckPlayerPreferences: DuckPlayerPreferencesPersistorMock(), + privacyConfigurationManager: privacyConfigManager + ) + + provider = NewTabPageNextStepsCardsProvider( + continueSetUpModel: continueSetUpModel, + appearancePreferences: AppearancePreferences(persistor: MockAppearancePreferencesPersistor()) + ) + } + + func testWhenCardsViewIsNotOutdatedThenCardsAreReportedByModel() { + provider.appearancePreferences.isContinueSetUpCardsViewOutdated = false + provider.continueSetUpModel.featuresMatrix = [[.defaultBrowser, .dock, .emailProtection]] + + XCTAssertEqual(provider.cards, [.defaultApp, .addAppToDockMac, .emailProtection]) + } + + func testWhenCardsViewIsOutdatedThenCardsAreEmpty() { + provider.appearancePreferences.isContinueSetUpCardsViewOutdated = true + provider.continueSetUpModel.featuresMatrix = [[.defaultBrowser, .dock, .emailProtection]] + + XCTAssertEqual(provider.cards, []) + } + + func testWhenCardsViewIsNotOutdatedThenCardsAreEmitted() { + provider.appearancePreferences.isContinueSetUpCardsViewOutdated = false + provider.continueSetUpModel.featuresMatrix = [[.defaultBrowser]] + + var cardsEvents = [[NewTabPageNextStepsCardsClient.CardID]]() + + let cancellable = provider.cardsPublisher + .sink { cards in + cardsEvents.append(cards) + } + + provider.continueSetUpModel.featuresMatrix = [[.dock]] + provider.continueSetUpModel.featuresMatrix = [[.dock, .duckplayer]] + provider.continueSetUpModel.featuresMatrix = [[.defaultBrowser]] + + cancellable.cancel() + XCTAssertEqual(cardsEvents, [[.addAppToDockMac], [.addAppToDockMac, .duckplayer], [.defaultApp]]) + } + + func testWhenCardsViewIsOutdatedThenEmptyCardsAreEmitted() { + provider.appearancePreferences.isContinueSetUpCardsViewOutdated = true + provider.continueSetUpModel.featuresMatrix = [[.defaultBrowser]] + + var cardsEvents = [[NewTabPageNextStepsCardsClient.CardID]]() + + let cancellable = provider.cardsPublisher + .sink { cards in + cardsEvents.append(cards) + } + + provider.continueSetUpModel.featuresMatrix = [[.dock]] + provider.continueSetUpModel.featuresMatrix = [[.duckplayer]] + provider.continueSetUpModel.featuresMatrix = [[.defaultBrowser]] + + cancellable.cancel() + XCTAssertEqual(cardsEvents, [[], [], []]) + } + + func testWhenCardsViewBecomesOutdatedThenCardsStopBeingEmitted() { + provider.appearancePreferences.isContinueSetUpCardsViewOutdated = false + provider.continueSetUpModel.featuresMatrix = [[.defaultBrowser]] + + var cardsEvents = [[NewTabPageNextStepsCardsClient.CardID]]() + + let cancellable = provider.cardsPublisher + .sink { cards in + cardsEvents.append(cards) + } + + provider.continueSetUpModel.featuresMatrix = [[.dock]] + provider.continueSetUpModel.featuresMatrix = [[.dock, .duckplayer]] + provider.appearancePreferences.isContinueSetUpCardsViewOutdated = true + provider.continueSetUpModel.featuresMatrix = [[.defaultBrowser]] + + cancellable.cancel() + XCTAssertEqual(cardsEvents, [[.addAppToDockMac], [.addAppToDockMac, .duckplayer], [], []]) + } +}