From 975870899c98c9583cad7fd10963c08f96c3bc68 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Fri, 25 Oct 2024 19:36:44 +0600 Subject: [PATCH] fix flaky bookmark store tests (#3431) Task/Issue URL: https://app.asana.com/0/1202406491309510/1208594009101931/f --- DuckDuckGo.xcodeproj/project.pbxproj | 6 + .../Services/BookmarkStoreMock.swift | 6 +- .../Services/LocalBookmarkStore.swift | 3 +- DuckDuckGo/Menus/MainMenuActions.swift | 2 +- DuckDuckGo/YoutubePlayer/DuckPlayer.swift | 2 +- IntegrationTests/Tab/AddressBarTests.swift | 15 ++- ...utofillCredentialsImportManagerTests.swift | 2 - .../Model/LocalBookmarkManagerTests.swift | 111 ++++++++++-------- .../Common/Extensions/Logger+UnitTests.swift | 26 ++++ .../TrackerMessageProviderTests.swift | 6 +- .../AdClickAttributionTabExtensionTests.swift | 78 +++++++++--- 11 files changed, 170 insertions(+), 87 deletions(-) create mode 100644 UnitTests/Common/Extensions/Logger+UnitTests.swift diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 4edbe2b8bc..82447c8abe 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -1854,6 +1854,8 @@ 848648A22C76F4B20082282D /* BookmarksBarMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848648A02C76F4B20082282D /* BookmarksBarMenuViewController.swift */; }; 84B49F0D2CB10F0900FF08BB /* OHHTTPStubs in Frameworks */ = {isa = PBXBuildFile; productRef = 84B49F0C2CB10F0900FF08BB /* OHHTTPStubs */; }; 84B49F0F2CB10F0900FF08BB /* OHHTTPStubsSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 84B49F0E2CB10F0900FF08BB /* OHHTTPStubsSwift */; }; + 84B479082CCA7A3E00F40329 /* Logger+UnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B479072CCA7A3900F40329 /* Logger+UnitTests.swift */; }; + 84B479092CCA7A3E00F40329 /* Logger+UnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B479072CCA7A3900F40329 /* Logger+UnitTests.swift */; }; 84DC715A2C1C1E9000033B8C /* UserDefaultsWrapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DC71582C1C1E8A00033B8C /* UserDefaultsWrapperTests.swift */; }; 84DC715B2C1C1E9000033B8C /* UserDefaultsWrapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DC71582C1C1E8A00033B8C /* UserDefaultsWrapperTests.swift */; }; 84DDB90A2C92B66E008C997B /* WKVisitedLinkStoreWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DDB9092C92B667008C997B /* WKVisitedLinkStoreWrapper.swift */; }; @@ -3957,6 +3959,7 @@ 844D7DA32C9443E500BE61D4 /* NSPrintInfoExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPrintInfoExtension.swift; sourceTree = ""; }; 84537A022C998C24008723BC /* FireWindowSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FireWindowSession.swift; sourceTree = ""; }; 848648A02C76F4B20082282D /* BookmarksBarMenuViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksBarMenuViewController.swift; sourceTree = ""; }; + 84B479072CCA7A3900F40329 /* Logger+UnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Logger+UnitTests.swift"; sourceTree = ""; }; 84DC71582C1C1E8A00033B8C /* UserDefaultsWrapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsWrapperTests.swift; sourceTree = ""; }; 84DDB9092C92B667008C997B /* WKVisitedLinkStoreWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKVisitedLinkStoreWrapper.swift; sourceTree = ""; }; 84F1C8CE2C7705B500716446 /* BookmarksBarMenuPopover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksBarMenuPopover.swift; sourceTree = ""; }; @@ -8565,6 +8568,7 @@ AAEC74B92642E66600C2EFBC /* Extensions */ = { isa = PBXGroup; children = ( + 84B479072CCA7A3900F40329 /* Logger+UnitTests.swift */, 4B4F72EB266B2ED300814C60 /* CollectionExtension.swift */, 1DFAB51F2A89830D00A0F7F6 /* SetExtensionTests.swift */, B65349A9265CF45000DCC645 /* DispatchQueueExtensionsTests.swift */, @@ -11749,6 +11753,7 @@ 317295D32AF058D3002C3206 /* MockWaitlistTermsAndConditionsActionHandler.swift in Sources */, 9F0FFFB52BCCAE37007C87DD /* BookmarkAllTabsDialogCoordinatorViewModelTests.swift in Sources */, 3706FE34293F661700E42796 /* PermissionStoreTests.swift in Sources */, + 84B479092CCA7A3E00F40329 /* Logger+UnitTests.swift in Sources */, 3706FE35293F661700E42796 /* ThirdPartyBrowserTests.swift in Sources */, 1DFAB5232A8983E100A0F7F6 /* SetExtensionTests.swift in Sources */, 56A054002C1AEFA1007D8FAB /* OnboardingManagerTests.swift in Sources */, @@ -13156,6 +13161,7 @@ buildActionMask = 2147483647; files = ( 1DB9617A29F1D06D00CF5568 /* InternalUserDeciderMock.swift in Sources */, + 84B479082CCA7A3E00F40329 /* Logger+UnitTests.swift in Sources */, 9833913327AAAEEE00DAF119 /* EmbeddedTrackerDataTests.swift in Sources */, 3776583127F8325B009A6B35 /* AutofillPreferencesTests.swift in Sources */, 373B2F852C387B830013A94B /* ActiveRemoteMessageModelTests.swift in Sources */, diff --git a/DuckDuckGo/Bookmarks/Services/BookmarkStoreMock.swift b/DuckDuckGo/Bookmarks/Services/BookmarkStoreMock.swift index 9ce9a877af..1017bc1756 100644 --- a/DuckDuckGo/Bookmarks/Services/BookmarkStoreMock.swift +++ b/DuckDuckGo/Bookmarks/Services/BookmarkStoreMock.swift @@ -21,7 +21,7 @@ import Bookmarks import Foundation -final class BookmarkStoreMock: BookmarkStore { +final class BookmarkStoreMock: BookmarkStore, CustomDebugStringConvertible { private let store: LocalBookmarkStore? @@ -266,6 +266,10 @@ final class BookmarkStoreMock: BookmarkStore { parent() } } + + var debugDescription: String { + return "<\(type(of: self)) \(Unmanaged.passUnretained(self).toOpaque()): \(store.map { "\($0)" } ?? "")>" + } } #endif diff --git a/DuckDuckGo/Bookmarks/Services/LocalBookmarkStore.swift b/DuckDuckGo/Bookmarks/Services/LocalBookmarkStore.swift index 07af3ab838..f5f35befcb 100644 --- a/DuckDuckGo/Bookmarks/Services/LocalBookmarkStore.swift +++ b/DuckDuckGo/Bookmarks/Services/LocalBookmarkStore.swift @@ -354,7 +354,7 @@ final class LocalBookmarkStore: BookmarkStore { let fetchResults = (try? context.fetch(fetchRequest)) ?? [] if fetchResults.count != identifiers.count { - assertionFailure("\(#file): Fetched bookmark entities didn't match the number of provided UUIDs") + assertionFailure("\(self): Fetched bookmark entities \(fetchResults) didn't match the number of provided UUIDs \(identifiers)") } for object in fetchResults { @@ -1107,7 +1107,6 @@ final class LocalBookmarkStore: BookmarkStore { } private func parent(for entity: BaseBookmarkEntity, in context: NSManagedObjectContext) throws -> BookmarkEntity { - let parentEntity: BookmarkEntity if let parentId = entity.parentFolderUUID, parentId != PseudoFolder.bookmarks.id, parentId != "bookmarks_root", let parentFetchRequestResult = try? context.fetch(BaseBookmarkEntity.singleEntity(with: parentId)).first { return parentFetchRequestResult diff --git a/DuckDuckGo/Menus/MainMenuActions.swift b/DuckDuckGo/Menus/MainMenuActions.swift index 79f8e6d638..197e3ae0dd 100644 --- a/DuckDuckGo/Menus/MainMenuActions.swift +++ b/DuckDuckGo/Menus/MainMenuActions.swift @@ -818,7 +818,7 @@ extension MainViewController { eventMapping: EventMapping { _, _, _, _ in }, installDate: nil) autofillPixelReporter.resetStoreDefaults() - var loginImportState = AutofillLoginImportState() + let loginImportState = AutofillLoginImportState() loginImportState.hasImportedLogins = false loginImportState.isCredentialsImportPromptPermanantlyDismissed = false } diff --git a/DuckDuckGo/YoutubePlayer/DuckPlayer.swift b/DuckDuckGo/YoutubePlayer/DuckPlayer.swift index 1bd8d77466..e739522169 100644 --- a/DuckDuckGo/YoutubePlayer/DuckPlayer.swift +++ b/DuckDuckGo/YoutubePlayer/DuckPlayer.swift @@ -311,7 +311,7 @@ final class DuckPlayer { let userValues = encodeUserValues() /// If the user clicked on "Watch on Youtube" the next vide should open directly on youtube instead of displaying the overlay - var allowFirstVideo = shouldOpenNextVideoOnYoutube + let allowFirstVideo = shouldOpenNextVideoOnYoutube /// Reset the flag for subsequent videos shouldOpenNextVideoOnYoutube = false diff --git a/IntegrationTests/Tab/AddressBarTests.swift b/IntegrationTests/Tab/AddressBarTests.swift index 03fa9beba7..57bd63b4a0 100644 --- a/IntegrationTests/Tab/AddressBarTests.swift +++ b/IntegrationTests/Tab/AddressBarTests.swift @@ -371,7 +371,10 @@ class AddressBarTests: XCTestCase { } for (idx, tab) in viewModel.tabs.enumerated() { viewModel.select(tab: tab) - try await Task.sleep(interval: 0.01) + for _ in 0..<10 { + guard addressBarValue != "tab-\(idx)" else { continue } + try await Task.sleep(interval: 0.01) + } XCTAssertEqual(addressBarValue, "tab-\(idx)") if tab.content == .newtab { XCTAssertTrue(isAddressBarFirstResponder, "\(idx)") @@ -872,7 +875,7 @@ class AddressBarTests: XCTestCase { // GIVEN let expectedImage = NSImage(named: "Shield")! let evaluator = MockCertificateEvaluator() - let tab = Tab(content: .url(.duckDuckGo, credential: nil, source: .userEntered("")), certificateTrustEvaluator: evaluator) + let tab = Tab(content: .url(.duckDuckGo, credential: nil, source: .userEntered("")), webViewConfiguration: webViewConfiguration, certificateTrustEvaluator: evaluator) let viewModel = TabCollectionViewModel(tabCollection: TabCollection(tabs: [tab])) let tabLoadedPromise = tab.webViewDidFinishNavigationPublisher.timeout(5).first().promise() @@ -891,7 +894,7 @@ class AddressBarTests: XCTestCase { let expectedImage = NSImage(named: "Shield")! let evaluator = MockCertificateEvaluator() evaluator.isValidCertificate = true - let tab = Tab(content: .url(.duckDuckGo, credential: nil, source: .userEntered("")), certificateTrustEvaluator: evaluator) + let tab = Tab(content: .url(.duckDuckGo, credential: nil, source: .userEntered("")), webViewConfiguration: webViewConfiguration, certificateTrustEvaluator: evaluator) let viewModel = TabCollectionViewModel(tabCollection: TabCollection(tabs: [tab])) let tabLoadedPromise = tab.webViewDidFinishNavigationPublisher.timeout(5).first().promise() @@ -910,7 +913,7 @@ class AddressBarTests: XCTestCase { let expectedImage = NSImage(named: "ShieldDot")! let evaluator = MockCertificateEvaluator() evaluator.isValidCertificate = false - let tab = Tab(content: .url(.duckDuckGo, credential: nil, source: .userEntered("")), certificateTrustEvaluator: evaluator) + let tab = Tab(content: .url(.duckDuckGo, credential: nil, source: .userEntered("")), webViewConfiguration: webViewConfiguration, certificateTrustEvaluator: evaluator) let viewModel = TabCollectionViewModel(tabCollection: TabCollection(tabs: [tab])) let tabLoadedPromise = tab.webViewDidFinishNavigationPublisher.timeout(5).first().promise() @@ -926,7 +929,7 @@ class AddressBarTests: XCTestCase { @MainActor func test_ZoomLevelNonDefault_ThenZoomButtonIsVisible() async throws { // GIVEN - let tab = Tab(content: .url(.duckDuckGo, credential: nil, source: .userEntered(""))) + let tab = Tab(content: .url(.duckDuckGo, credential: nil, source: .userEntered("")), webViewConfiguration: webViewConfiguration) let viewModel = TabCollectionViewModel(tabCollection: TabCollection(tabs: [tab])) viewModel.selectedTabViewModel?.zoomWasSet(to: .percent150) let tabLoadedPromise = tab.webViewDidFinishNavigationPublisher.timeout(5).first().promise() @@ -943,7 +946,7 @@ class AddressBarTests: XCTestCase { @MainActor func test_ZoomLevelDefault_ThenZoomButtonIsNotVisible() async throws { // GIVEN - let tab = Tab(content: .url(.duckDuckGo, credential: nil, source: .userEntered(""))) + let tab = Tab(content: .url(.duckDuckGo, credential: nil, source: .userEntered("")), webViewConfiguration: webViewConfiguration) tab.webView.zoomLevel = AccessibilityPreferences.shared.defaultPageZoom let viewModel = TabCollectionViewModel(tabCollection: TabCollection(tabs: [tab])) viewModel.selectedTabViewModel?.zoomWasSet(to: .percent100) diff --git a/UnitTests/Autofill/Tests/AutofillCredentialsImportManagerTests.swift b/UnitTests/Autofill/Tests/AutofillCredentialsImportManagerTests.swift index dcf99f8801..5aba4734d2 100644 --- a/UnitTests/Autofill/Tests/AutofillCredentialsImportManagerTests.swift +++ b/UnitTests/Autofill/Tests/AutofillCredentialsImportManagerTests.swift @@ -104,14 +104,12 @@ final class AutofillCredentialsImportManagerTests: XCTestCase { } func testOnAutofillUserScriptShouldDisplayOverlay_SerializedInputContextWithCredentialsImportFalse_returnsTrue() { - let serializedInputContext = "{\"inputType\":\"credentials.username\",\"credentialsImport\":false}" let result = manager.autofillUserScriptShouldDisplayOverlay("", for: "fill.dev") XCTAssertTrue(result) } func testOnAutofillUserScriptShouldDisplayOverlay_SerializedInputContextWithCredentialsImportTrue_PromptHasNOTBeenPermanantlyDismissed_returnsTrue() { - let serializedInputContext = "{\"inputType\":\"credentials.username\",\"credentialsImport\":false}" importState.isCredentialsImportPromptPermanantlyDismissed = false let result = manager.autofillUserScriptShouldDisplayOverlay("", for: "fill.dev") diff --git a/UnitTests/Bookmarks/Model/LocalBookmarkManagerTests.swift b/UnitTests/Bookmarks/Model/LocalBookmarkManagerTests.swift index 31038e14ec..46c8b78504 100644 --- a/UnitTests/Bookmarks/Model/LocalBookmarkManagerTests.swift +++ b/UnitTests/Bookmarks/Model/LocalBookmarkManagerTests.swift @@ -19,6 +19,7 @@ import Bookmarks import Combine import Foundation +import os.log import XCTest @testable import DuckDuckGo_Privacy_Browser @@ -26,6 +27,7 @@ import XCTest final class LocalBookmarkManagerTests: XCTestCase { var container: NSPersistentContainer! + var context: NSManagedObjectContext! enum BookmarkManagerError: Error { case somethingReallyBad @@ -34,15 +36,28 @@ final class LocalBookmarkManagerTests: XCTestCase { override func setUp() { container = CoreData.bookmarkContainer() let context = container.newBackgroundContext() + self.context = context + Logger.tests.debug("LocalBookmarkManagerTests.\(self.name).setUp with \(context.description, privacy: .public)") + context.performAndWait { BookmarkUtils.prepareFoldersStructure(in: context) } - LocalBookmarkManager.context = context } + override func tearDown() { + // flush pending operations + Logger.tests.debug("LocalBookmarkManagerTests.\(self.name).tearDown: flush") + context.performAndWait { } + context = nil + container = nil + Logger.tests.debug("LocalBookmarkManagerTests.\(self.name).tearDown end") + } + + // MARK: - Tests + @MainActor func testWhenBookmarksAreNotLoadedYet_ThenManagerIgnoresBookmarkingRequests() { - let (bookmarkManager, _) = LocalBookmarkManager.manager(loadBookmarks: false) {} + let (bookmarkManager, _) = manager(loadBookmarks: false) {} XCTAssertNil(bookmarkManager.makeBookmark(for: URL.duckDuckGo, title: "Test", isFavorite: false)) XCTAssertNil(bookmarkManager.updateUrl(of: Bookmark.aBookmark, to: URL.duckDuckGoAutocomplete)) @@ -50,7 +65,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenBookmarksAreLoaded_ThenTheManagerHoldsAllLoadedBookmarks() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.manager { + let (bookmarkManager, bookmarkStoreMock) = manager { Bookmark.aBookmark } @@ -74,7 +89,7 @@ final class LocalBookmarkManagerTests: XCTestCase { } func testWhenBookmarkIsCreated_ThenManagerSavesItToStore() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager let bookmark = bookmarkManager.makeBookmark(for: URL.duckDuckGo, title: "Title", isFavorite: false)! XCTAssert(bookmarkManager.isUrlBookmarked(url: bookmark.urlObject!)) @@ -82,7 +97,7 @@ final class LocalBookmarkManagerTests: XCTestCase { } func testWhenBookmarkIsCreatedAndStoringFails_ThenManagerRemovesItFromList() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager bookmarkStoreMock.saveEntitiesError = BookmarkManagerError.somethingReallyBad let bookmark = bookmarkManager.makeBookmark(for: URL.duckDuckGo, title: "Title", isFavorite: false)! @@ -92,7 +107,7 @@ final class LocalBookmarkManagerTests: XCTestCase { } func testWhenUrlIsAlreadyBookmarked_ThenManagerReturnsNil() { - let (bookmarkManager, _) = LocalBookmarkManager.aManager + let (bookmarkManager, _) = aManager _ = bookmarkManager.makeBookmark(for: URL.duckDuckGo, title: "Title", isFavorite: false)! XCTAssertNil(bookmarkManager.makeBookmark(for: URL.duckDuckGo, title: "Title", isFavorite: false)) @@ -100,7 +115,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenBookmarkIsRemoved_ThenManagerRemovesItFromStore() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager let bookmark = bookmarkManager.makeBookmark(for: URL.duckDuckGo, title: "Title", isFavorite: false)! bookmarkManager.remove(bookmark: bookmark, undoManager: nil) @@ -112,7 +127,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenFolderIsRemoved_ThenManagerRemovesItFromStore() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager var folder: BookmarkFolder! let e = expectation(description: "Folder created") bookmarkManager.makeFolder(named: "Folder", parent: nil) { result in @@ -134,7 +149,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenBookmarkAndFolderAreRemoved_ThenManagerRemovesThemFromStore() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager let bookmark = bookmarkManager.makeBookmark(for: URL.duckDuckGo, title: "Title", isFavorite: false)! var folder: BookmarkFolder! let e = expectation(description: "Folder created") @@ -152,7 +167,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenRemovalFails_ThenManagerPutsBookmarkBackToList() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager let bookmark = bookmarkManager.makeBookmark(for: URL.duckDuckGo, title: "Title", isFavorite: false)! bookmarkStoreMock.removeError = BookmarkManagerError.somethingReallyBad @@ -165,7 +180,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenBookmarkRemovalIsUndone_ThenRestoreBookmarkIsCalled() async throws { - let (bookmarkManager, bookmarkStoreMock) = await LocalBookmarkManager.manager(with: { + let (bookmarkManager, bookmarkStoreMock) = await manager(with: { bookmark(.duckDuckGo) bookmark(.duckDuckGoEmail) folder("Folder") @@ -205,7 +220,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenFolderRemovalIsUndone_ThenRestoreFolderIsCalled() async throws { - let (bookmarkManager, bookmarkStoreMock) = await LocalBookmarkManager.manager(with: { + let (bookmarkManager, bookmarkStoreMock) = await manager(with: { bookmark(.duckDuckGo) folder(id: "1", "Folder") { bookmark(.duckDuckGoEmailLogin) @@ -276,7 +291,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenBookmarkAndFolderRemovalIsUndone_ThenRestoreEntitiesIsCalled() async throws { - let (bookmarkManager, bookmarkStoreMock) = await LocalBookmarkManager.manager(with: { + let (bookmarkManager, bookmarkStoreMock) = await manager(with: { bookmark(.duckDuckGo) bookmark(.aboutDuckDuckGo) folder(id: "1", "Folder") { @@ -407,7 +422,7 @@ final class LocalBookmarkManagerTests: XCTestCase { Bookmark(.duckDuckGo.appending("7")), Bookmark(.duckDuckGo.appending("8")), ] - let (bookmarkManager, _) = await LocalBookmarkManager.manager(with: { bookmarks }) + let (bookmarkManager, _) = await manager(with: { bookmarks }) let undoManager = UndoManager() let removedEntities = [ @@ -465,7 +480,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenBookmarkNoLongerExist_ThenManagerIgnoresAttemptToRemoval() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager bookmarkManager.remove(bookmark: Bookmark.aBookmark, undoManager: nil) @@ -474,7 +489,7 @@ final class LocalBookmarkManagerTests: XCTestCase { } func testWhenBookmarkNoLongerExist_ThenManagerIgnoresAttemptToUpdate() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager bookmarkManager.update(bookmark: Bookmark.aBookmark) let updateUrlResult = bookmarkManager.updateUrl(of: Bookmark.aBookmark, to: URL.duckDuckGoAutocomplete) @@ -485,7 +500,7 @@ final class LocalBookmarkManagerTests: XCTestCase { } func testWhenBookmarkIsUpdated_ThenManagerUpdatesItInStore() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager let bookmark = bookmarkManager.makeBookmark(for: URL.duckDuckGo, title: "Title", isFavorite: false)! bookmark.isFavorite = !bookmark.isFavorite @@ -496,7 +511,7 @@ final class LocalBookmarkManagerTests: XCTestCase { } func testWhenBookmarkUrlIsUpdated_ThenManagerUpdatesItAlsoInStore() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager let bookmark = bookmarkManager.makeBookmark(for: URL.duckDuckGo, title: "Title", isFavorite: false)! let newURL = URL.duckDuckGoAutocomplete @@ -514,7 +529,7 @@ final class LocalBookmarkManagerTests: XCTestCase { func testWhenBookmarkFolderIsUpdatedAndMoved_ThenManagerUpdatesItAlsoInStore() throws { let parent = BookmarkFolder(id: "1", title: "Parent") let folder = BookmarkFolder(id: "2", title: "Child") - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.manager { + let (bookmarkManager, bookmarkStoreMock) = manager { parent folder } @@ -540,7 +555,7 @@ final class LocalBookmarkManagerTests: XCTestCase { func testWhenGetBookmarkFolderIsCalledThenAskBookmarkStoreToRetrieveFolder() throws { // GIVEN - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager XCTAssertFalse(bookmarkStoreMock.bookmarkFolderWithIdCalled) XCTAssertNil(bookmarkStoreMock.capturedFolderId) @@ -555,7 +570,7 @@ final class LocalBookmarkManagerTests: XCTestCase { func testWhenGetBookmarkFolderIsCalledAndFolderExistsInStoreThenBookmarkStoreReturnsFolder() throws { // GIVEN let folder = BookmarkFolder(id: #function, title: "Test") - let (bookmarkManager, _) = LocalBookmarkManager.manager { folder } + let (bookmarkManager, _) = manager { folder } // WHEN let result = bookmarkManager.getBookmarkFolder(withId: #function) @@ -566,7 +581,7 @@ final class LocalBookmarkManagerTests: XCTestCase { func testWhenGetBookmarkFolderIsCalledAndFolderDoesNotExistInStoreThenBookmarkStoreReturnsNil() throws { // GIVEN - let (bookmarkManager, _) = LocalBookmarkManager.aManager + let (bookmarkManager, _) = aManager // WHEN let result = bookmarkManager.getBookmarkFolder(withId: #function) @@ -580,7 +595,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenMakeBookmarksForWebsitesInfoIsCalledThenBookmarkStoreIsAskedToCreateMultipleBookmarks() { // GIVEN - let (sut, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (sut, bookmarkStoreMock) = aManager let newFolderName = #function let websitesInfo = [ WebsiteInfo(url: URL.duckDuckGo, title: "Website 1"), @@ -607,7 +622,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenMakeBookmarksForWebsiteInfoIsCalledThenReloadAllBookmarks() { // GIVEN - let (sut, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (sut, bookmarkStoreMock) = aManager bookmarkStoreMock.loadAllCalled = false // Reset after load all bookmarks the first time XCTAssertFalse(bookmarkStoreMock.loadAllCalled) let websitesInfo = [WebsiteInfo(url: URL.duckDuckGo, title: "Website 1")].compactMap { $0 } @@ -631,7 +646,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenQueryIsEmptyThenSearchResultsAreEmpty() { - let (sut, _) = LocalBookmarkManager.manager(with: topLevelBookmarks) + let (sut, _) = manager(with: topLevelBookmarks) let results = sut.search(by: "") XCTAssertTrue(results.isEmpty) @@ -639,7 +654,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenQueryIsBlankThenSearchResultsAreEmpty() { - let (sut, _) = LocalBookmarkManager.manager(with: topLevelBookmarks) + let (sut, _) = manager(with: topLevelBookmarks) let results = sut.search(by: " ") @@ -648,7 +663,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenASearchIsDoneThenCorrectResultsAreReturnedAndIntheRightOrder() { - let (sut, _) = LocalBookmarkManager.manager(with: topLevelBookmarks) + let (sut, _) = manager(with: topLevelBookmarks) let results = sut.search(by: "folder") XCTAssertEqual(results.count, 3) @@ -659,7 +674,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenASearchIsDoneThenFoldersAndBookmarksAreReturned() { - let (sut, _) = LocalBookmarkManager.manager(with: topLevelBookmarks) + let (sut, _) = manager(with: topLevelBookmarks) let results = sut.search(by: "favorite") XCTAssertEqual(results.count, 2) @@ -671,7 +686,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenASearchIsDoneThenItMatchesWithLowercaseResults() { - let (sut, _) = LocalBookmarkManager.manager { + let (sut, _) = manager { Bookmark(id: "1", url: "www.favorite.com", title: "Favorite bookmark", isFavorite: true) Bookmark(id: "2", url: "www.favoritetwo.com", title: "favorite bookmark", isFavorite: true) } @@ -685,7 +700,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testSearchIgnoresAccents() { - let (sut, _) = LocalBookmarkManager.manager { + let (sut, _) = manager { Bookmark(id: "1", url: "www.coffee.com", title: "Mi café favorito", isFavorite: true) Bookmark(id: "1", url: "www.coffee.com", title: "Mi cafe favorito", isFavorite: true) } @@ -699,7 +714,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenASearchIsDoneWithoutAccenttsThenItMatchesBookmarksWithoutAccent() { - let (sut, _) = LocalBookmarkManager.manager { + let (sut, _) = manager { Bookmark(id: "1", url: "www.coffee.com", title: "Mi café favorito", isFavorite: true) } @@ -710,7 +725,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testWhenBookmarkHasASymbolThenItsIgnoredWhenSearching() { - let (sut, _) = LocalBookmarkManager.manager { + let (sut, _) = manager { Bookmark(id: "1", url: "www.test.com", title: "Site • Login", isFavorite: true) } @@ -721,7 +736,7 @@ final class LocalBookmarkManagerTests: XCTestCase { @MainActor func testSearchQueryHasASymbolThenItsIgnoredWhenSearching() { - let (sut, _) = LocalBookmarkManager.manager { + let (sut, _) = manager { Bookmark(id: "1", url: "www.test.com", title: "Site Login", isFavorite: true) } @@ -746,7 +761,7 @@ final class LocalBookmarkManagerTests: XCTestCase { let originalURL = URL(string: "http://example.com")! let variantURL = URL(string: "https://example.com/")! let bookmark = Bookmark(id: UUID().uuidString, url: variantURL.absoluteString, title: "Title", isFavorite: false, parentFolderUUID: "bookmarks_root") - let (bookmarkManager, bookmarkStoreMock) = await LocalBookmarkManager.manager(with: { + let (bookmarkManager, bookmarkStoreMock) = await manager(with: { bookmark }) bookmarkManager.loadBookmarks() @@ -758,9 +773,8 @@ final class LocalBookmarkManagerTests: XCTestCase { } func testWhenNoVariantUrlIsBookmarked_ThenGetBookmarkForVariantReturnsNil() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager let originalURL = URL(string: "http://example.com")! - let variantURL = URL(string: "https://example.com/")! bookmarkStoreMock.bookmarks = [] bookmarkManager.loadBookmarks() @@ -774,7 +788,7 @@ final class LocalBookmarkManagerTests: XCTestCase { let originalURL = URL(string: "http://example.com")! let variantURL = URL(string: "https://example.com/")! let bookmark = Bookmark(id: UUID().uuidString, url: variantURL.absoluteString, title: "Title", isFavorite: false, parentFolderUUID: "bookmarks_root") - let (bookmarkManager, bookmarkStoreMock) = await LocalBookmarkManager.manager(with: { + let (bookmarkManager, _) = await manager(with: { bookmark }) bookmarkManager.loadBookmarks() @@ -785,7 +799,7 @@ final class LocalBookmarkManagerTests: XCTestCase { } func testWhenNoVariantUrlIsBookmarked_ThenIsAnyUrlVariantBookmarkedReturnsFalse() { - let (bookmarkManager, bookmarkStoreMock) = LocalBookmarkManager.aManager + let (bookmarkManager, bookmarkStoreMock) = aManager let originalURL = URL(string: "http://example.com")! bookmarkStoreMock.bookmarks = [] @@ -798,23 +812,22 @@ final class LocalBookmarkManagerTests: XCTestCase { } -fileprivate extension LocalBookmarkManager { - - static var context: NSManagedObjectContext! +fileprivate extension LocalBookmarkManagerTests { - static var aManager: (LocalBookmarkManager, BookmarkStoreMock) { + var aManager: (LocalBookmarkManager, BookmarkStoreMock) { manager(with: {}) } - private static func makeManager(@BookmarksBuilder with bookmarks: () -> [BookmarksBuilderItem]) -> (LocalBookmarkManager, BookmarkStoreMock) { - let bookmarkStoreMock = BookmarkStoreMock(contextProvider: { Self.context }, bookmarks: bookmarks().build()) + private func makeManager(@BookmarksBuilder with bookmarks: () -> [BookmarksBuilderItem]) -> (LocalBookmarkManager, BookmarkStoreMock) { + let bookmarkStoreMock = BookmarkStoreMock(contextProvider: context.map { context in { context } }, bookmarks: bookmarks().build()) let faviconManagerMock = MainActor.assumeIsolated { FaviconManagerMock() } let bookmarkManager = LocalBookmarkManager(bookmarkStore: bookmarkStoreMock, faviconManagement: faviconManagerMock) + Logger.tests.debug("LocalBookmarkManagerTests.\(self.name).makeManager \(String(describing: bookmarkManager)) with \(bookmarkStoreMock.debugDescription, privacy: .public)") return (bookmarkManager, bookmarkStoreMock) } - static func manager(loadBookmarks: Bool = true, @BookmarksBuilder with bookmarks: () -> [BookmarksBuilderItem]) -> (LocalBookmarkManager, BookmarkStoreMock) { + func manager(loadBookmarks: Bool = true, @BookmarksBuilder with bookmarks: () -> [BookmarksBuilderItem]) -> (LocalBookmarkManager, BookmarkStoreMock) { let (bookmarkManager, bookmarkStoreMock) = makeManager(with: bookmarks) if loadBookmarks { bookmarkManager.loadBookmarks() @@ -826,7 +839,7 @@ fileprivate extension LocalBookmarkManager { } @MainActor - static func manager(loadBookmarks: Bool = true, @BookmarksBuilder with bookmarks: () -> [BookmarksBuilderItem]) async -> (LocalBookmarkManager, BookmarkStoreMock) { + func manager(loadBookmarks: Bool = true, @BookmarksBuilder with bookmarks: () -> [BookmarksBuilderItem]) async -> (LocalBookmarkManager, BookmarkStoreMock) { let (bookmarkManager, bookmarkStoreMock) = makeManager(with: bookmarks) if loadBookmarks { bookmarkManager.loadBookmarks() @@ -881,15 +894,11 @@ fileprivate extension BaseBookmarkEntity { } } - func matchesFolder(withTitle title: String, parent: String? = nil) -> Bool { + func matchesFolder(withTitle title: String, parent: String?) -> Bool { guard self.isFolder else { return false } return self.title == title && self.parentFolderUUID ?? "bookmarks_root" == parent ?? "bookmarks_root" } - func matchesFolder(withTitle title: String, parent: BookmarkFolder? = nil) -> Bool { - matchesFolder(withTitle: title, parent: parent?.id) - } - func matches(_ folder: BookmarkFolder) -> Bool { matchesFolder(withTitle: folder.title, parent: folder.parentFolderUUID) } diff --git a/UnitTests/Common/Extensions/Logger+UnitTests.swift b/UnitTests/Common/Extensions/Logger+UnitTests.swift new file mode 100644 index 0000000000..ce55cef7f4 --- /dev/null +++ b/UnitTests/Common/Extensions/Logger+UnitTests.swift @@ -0,0 +1,26 @@ +// +// Logger+UnitTests.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 Foundation +import os.log + +public extension Logger { + fileprivate static let subsystem = "com.duckduckgo.macos.browser.DuckDuckGoTests" + + static var tests = { Logger(subsystem: subsystem, category: "🧪") }() +} diff --git a/UnitTests/Onboarding/ContextualOnboarding/TrackerMessageProviderTests.swift b/UnitTests/Onboarding/ContextualOnboarding/TrackerMessageProviderTests.swift index 9ce0676897..2e7d9f311e 100644 --- a/UnitTests/Onboarding/ContextualOnboarding/TrackerMessageProviderTests.swift +++ b/UnitTests/Onboarding/ContextualOnboarding/TrackerMessageProviderTests.swift @@ -114,9 +114,8 @@ final class TrackerMessageProviderTests: XCTestCase { func testTrackerType_When1Tracker_ReturnsExpectedMessage() { let expectedMessage: String = "Tracker1 was trying to track you here. I blocked them!\n\n☝️ Tap the shield for more info." - let serverTrust = MockSecurityTrust() let protectionStatus = ProtectionStatus(unprotectedTemporary: false, enabledFeatures: [], allowlisted: false, denylisted: false) - var privacyInfo = PrivacyInfo(url: URL(string: "https://site-with-tracker.com")!, + let privacyInfo = PrivacyInfo(url: URL(string: "https://site-with-tracker.com")!, parentEntity: nil, protectionStatus: protectionStatus) let detectedTracker = DetectedRequest(url: "https://site-with-tracker.com", eTLDplus1: "https://site-with-tracker.com", knownTracker: nil, entity: trackerEntity1, state: .blocked, pageUrl: "https://site-with-tracker.com") @@ -131,9 +130,8 @@ final class TrackerMessageProviderTests: XCTestCase { func testTrackerType_When2Trackers_ReturnsExpectedMessage() throws { let expectedMessage: String = "were trying to track you here. I blocked them!" - let serverTrust = MockSecurityTrust() let protectionStatus = ProtectionStatus(unprotectedTemporary: false, enabledFeatures: [], allowlisted: false, denylisted: false) - var privacyInfo = PrivacyInfo(url: URL(string: "https://site-with-tracker.com")!, + let privacyInfo = PrivacyInfo(url: URL(string: "https://site-with-tracker.com")!, parentEntity: nil, protectionStatus: protectionStatus) let detectedTracker = DetectedRequest(url: "https://site-with-tracker.com", eTLDplus1: "https://site-with-tracker.com", knownTracker: nil, entity: trackerEntity1, state: .blocked, pageUrl: "https://site-with-tracker.com") diff --git a/UnitTests/TabExtensionsTests/AdClickAttributionTabExtensionTests.swift b/UnitTests/TabExtensionsTests/AdClickAttributionTabExtensionTests.swift index 9c53a02c6c..8b15ebdc5a 100644 --- a/UnitTests/TabExtensionsTests/AdClickAttributionTabExtensionTests.swift +++ b/UnitTests/TabExtensionsTests/AdClickAttributionTabExtensionTests.swift @@ -19,10 +19,11 @@ import BrowserServicesKit import Combine import ContentBlocking +import Navigation +import os.log import TrackerRadarKit import WebKit import XCTest -import Navigation @testable import DuckDuckGo_Privacy_Browser @@ -103,8 +104,9 @@ class AdClickAttributionTabExtensionTests: XCTestCase { }} schemeHandler = TestSchemeHandler() - schemeHandler.middleware = [{ [data] _ in - .ok(.html(data.html.utf8String()!)) + schemeHandler.middleware = [{ [data] in + Logger.tests.debug("schemeHandler.middleware \($0.url?.absoluteString ?? "", privacy: .public)") + return .ok(.html(data.html.utf8String()!)) }] WKWebView.customHandlerSchemes = [.http, .https] @@ -116,6 +118,7 @@ class AdClickAttributionTabExtensionTests: XCTestCase { func makeContentBlockerRulesUserScript() { contentBlockerRulesScript = MockContentBlockerRulesUserScript() + Logger.tests.debug("➡️ contentBlockerRulesScriptSubj.send(MockContentBlockerRulesUserScript)") contentBlockerRulesScriptSubj.send(contentBlockerRulesScript) } @@ -252,30 +255,36 @@ class AdClickAttributionTabExtensionTests: XCTestCase { let onDetectionDidStart = expectation(description: "detection.onDidStart") detection.onDidStart = { [urls] url in + Logger.tests.log("detection.onDidStart \(url?.absoluteString ?? "", privacy: .public)") XCTAssertEqual(url, urls.url2) onDetectionDidStart.fulfill() } let on2XXResponse = expectation(description: "on2XXResponse") detection.on2XXResponse = { [urls] url in + Logger.tests.log("detection.on2XXResponse \(url?.absoluteString ?? "", privacy: .public)") XCTAssertEqual(url, urls.url2) on2XXResponse.fulfill() } let onNavigation = expectation(description: "onNavigation") logic.onNavigation = { + Logger.tests.log("logic.onNavigation") onNavigation.fulfill() } let onDetectionDidFinish = expectation(description: "detection.onDidFinish") let onLogicDidFinish = expectation(description: "logic.onDidFinish") - detection.onDidFinish = { _ in + detection.onDidFinish = { + Logger.tests.log("detection.onDidFinish \($0?.absoluteString ?? "", privacy: .public)") onDetectionDidFinish.fulfill() } logic.onDidFinish = { [now, urls] host, date in + Logger.tests.log("logic.onDidFinish \(host ?? "", privacy: .public) \("\(date)", privacy: .public)") XCTAssertEqual(host, urls.url2.host!) XCTAssertEqual(date, now) onLogicDidFinish.fulfill() } + Logger.tests.debug("➡️ setContent \(self.urls.url2.absoluteString, privacy: .public)") tab.setContent(.url(urls.url2, source: .link)) waitForExpectations(timeout: 5) } @@ -293,44 +302,52 @@ class AdClickAttributionTabExtensionTests: XCTestCase { schemeHandler.middleware = [{ [data] request in guard request.url!.path == "/" else { return nil} + Logger.tests.debug("schemeHandler.middleware #1 \(request.url?.absoluteString ?? "", privacy: .public)") return .ok(.html(data.metaRedirect.utf8String()!)) - }, { [data] _ in + }, { [data] request in + Logger.tests.debug("schemeHandler.middleware #2 \(request.url?.absoluteString ?? "", privacy: .public)") return .ok(.html(data.html.utf8String()!)) }] var onDetectionDidStart = expectation(description: "detection.onDidStart") let onDetectionDidStart2 = expectation(description: "detection.onDidStart 2") - detection.onDidStart = { _ in + detection.onDidStart = { url in + Logger.tests.log("detection.onDidStart \(url?.absoluteString ?? "", privacy: .public)") onDetectionDidStart.fulfill() onDetectionDidStart = onDetectionDidStart2 } var on2XXResponse = expectation(description: "on2XXResponse") let on2XXResponse2 = expectation(description: "on2XXResponse 2") - detection.on2XXResponse = { _ in + detection.on2XXResponse = { url in + Logger.tests.log("detection.on2XXResponse \(url?.absoluteString ?? "", privacy: .public)") on2XXResponse.fulfill() on2XXResponse = on2XXResponse2 } var onNavigation = expectation(description: "onNavigation") let onNavigation2 = expectation(description: "onNavigation 2") logic.onNavigation = { + Logger.tests.log("logic.onNavigation") onNavigation.fulfill() onNavigation = onNavigation2 } let onDetectionDidFinish = expectation(description: "detection.onDidFinish") let onLogicDidFinish = expectation(description: "logic.onDidFinish") - detection.onDidFinish = { _ in + detection.onDidFinish = { + Logger.tests.log("detection.onDidFinish \($0?.absoluteString ?? "", privacy: .public)") onDetectionDidFinish.fulfill() } detection.onDidFail = { XCTFail("Not expected") } logic.onDidFinish = { [now, urls] host, date in + Logger.tests.log("logic.onDidFinish \(host ?? "", privacy: .public) \("\(date)", privacy: .public)") XCTAssertEqual(host, urls.url2.host!) XCTAssertEqual(date, now) onLogicDidFinish.fulfill() } + Logger.tests.debug("➡️ setContent \(self.urls.url1.absoluteString, privacy: .public)") tab.setContent(.url(urls.url1, source: .link)) waitForExpectations(timeout: 5) } @@ -349,50 +366,60 @@ class AdClickAttributionTabExtensionTests: XCTestCase { // For first load, redirect from url1 to url2 schemeHandler.middleware = [{ request in guard request.url!.path == "/" else { return nil} + Logger.tests.debug("schemeHandler.middleware #1 \(request.url?.absoluteString ?? "", privacy: .public)") return .redirect(to: self.urls.url2) - }, { [data] _ in + }, { [data] request in + Logger.tests.debug("schemeHandler.middleware #1 \(request.url?.absoluteString ?? "", privacy: .public)") return .ok(.html(data.html.utf8String()!)) }] // After redirect, issue developer redirect, that cancels url2 loading and navigates to url3 decidePolicy = { navAction in if navAction.request.url == self.urls.url2 { + Logger.tests.debug("decidePolicy \(navAction.url.absoluteString, privacy: .public) -> redirect to \(self.urls.url3.absoluteString, privacy: .public)") return .redirect(navAction.mainFrameTarget!, { navigator in navigator.load(.init(url: self.urls.url3)) }) } else { + Logger.tests.debug("decidePolicy \(navAction.url.absoluteString, privacy: .public) -> .next") return .next } } let onDetectionDidStart = expectation(description: "detection.onDidStart") onDetectionDidStart.assertForOverFulfill = false - detection.onDidStart = { _ in + detection.onDidStart = { url in + Logger.tests.log("detection.onDidStart \(url?.absoluteString ?? "", privacy: .public)") onDetectionDidStart.fulfill() } let on2XXResponse = expectation(description: "on2XXResponse") - detection.on2XXResponse = { _ in + detection.on2XXResponse = { url in + Logger.tests.log("detection.on2XXResponse \(url?.absoluteString ?? "", privacy: .public)") on2XXResponse.fulfill() } let onNavigation = expectation(description: "onNavigation") logic.onNavigation = { + Logger.tests.log("logic.onNavigation") onNavigation.fulfill() } let onDetectionDidFinish = expectation(description: "detection.onDidFinish") let onLogicDidFinish = expectation(description: "logic.onDidFinish") - detection.onDidFinish = { _ in + detection.onDidFinish = { + Logger.tests.log("detection.onDidFinish \($0?.absoluteString ?? "", privacy: .public)") onDetectionDidFinish.fulfill() } detection.onDidFail = { XCTFail("Not expected") } logic.onDidFinish = { [now, urls] host, date in + Logger.tests.log("logic.onDidFinish \(host ?? "", privacy: .public) \("\(date)", privacy: .public)") XCTAssertEqual(host, urls.url3.host!) XCTAssertEqual(date, now) onLogicDidFinish.fulfill() } + Logger.tests.debug("➡️ setContent \(self.urls.url1.absoluteString, privacy: .public)") tab.setContent(.url(urls.url1, source: .link)) waitForExpectations(timeout: 5) } @@ -403,7 +430,8 @@ class AdClickAttributionTabExtensionTests: XCTestCase { privacyConfiguration.isFeatureKeyEnabled = { _, _ in return false } - schemeHandler.middleware = [{ _ in + schemeHandler.middleware = [{ request in + Logger.tests.debug("schemeHandler.middleware #err \(request.url?.absoluteString ?? "", privacy: .public)") return .failure(NSError(domain: NSURLErrorDomain, code: NSURLErrorCannotFindHost)) }] let tab = Tab(content: .none, webViewConfiguration: webViewConfiguration, privacyFeatures: privacyFeaturesMock, extensionsBuilder: extensionsBuilder, shouldLoadInBackground: true) @@ -413,16 +441,19 @@ class AdClickAttributionTabExtensionTests: XCTestCase { let onDetectionDidStart = expectation(description: "detection.onDidStart") detection.onDidStart = { [urls] url in + Logger.tests.log("detection.onDidStart \(url?.absoluteString ?? "", privacy: .public)") XCTAssertEqual(url, urls.url2) onDetectionDidStart.fulfill() } let onDetectionDidFail = expectation(description: "detection.onDidFail") detection.onDidFail = { + Logger.tests.log("detection.onDidFail") onDetectionDidFail.fulfill() } // skipping server.start + Logger.tests.debug("➡️ setContent \(self.urls.url2.absoluteString, privacy: .public)") tab.setContent(.url(urls.url2, source: .link)) waitForExpectations(timeout: 5) } @@ -438,44 +469,53 @@ class AdClickAttributionTabExtensionTests: XCTestCase { self.makeContentBlockerRulesUserScript() } - detection.onDidStart = { _ in } - detection.on2XXResponse = { _ in } - logic.onNavigation = { } - detection.onDidFinish = { _ in } + detection.onDidStart = { Logger.tests.log("detection.onDidStart \($0?.absoluteString ?? "", privacy: .public)") } + detection.on2XXResponse = { Logger.tests.log("detection.on2XXResponse \($0?.absoluteString ?? "", privacy: .public)") } + logic.onNavigation = { Logger.tests.log("logic.onNavigation") } + detection.onDidFinish = { Logger.tests.log("detection.onDidFinish \($0?.absoluteString ?? "", privacy: .public)") } var onDidFinish = expectation(description: "onDidFinish 1") - logic.onDidFinish = { _, _ in + logic.onDidFinish = { host, time in + Logger.tests.log("logic.onDidFinish \(host ?? "", privacy: .public) \("\(time)", privacy: .public)") onDidFinish.fulfill() } tab.setContent(.url(urls.url1, source: .link)) waitForExpectations(timeout: 5) + Logger.tests.debug("➡️ setContent \(self.urls.url1.absoluteString, privacy: .public)") + onDidFinish = expectation(description: "onDidFinish 2") tab.setContent(.url(urls.url2, source: .link)) waitForExpectations(timeout: 5) + Logger.tests.debug("➡️ setContent \(self.urls.url2.absoluteString, privacy: .public)") detection.on2XXResponse = nil /*assert*/ let onBackForward = expectation(description: "detection.onBackForward") logic.onBackForward = { [urls] url in XCTAssertEqual(url, urls.url1) + Logger.tests.log("logic.onBackForward \(url?.absoluteString ?? "", privacy: .public)") onBackForward.fulfill() } let onDetectionDidStart = expectation(description: "detection.onDidStart") detection.onDidStart = { [urls] url in XCTAssertEqual(url, urls.url1) + Logger.tests.log("detection.onDidStart \(url?.absoluteString ?? "", privacy: .public)") onDetectionDidStart.fulfill() } let onDetectionDidFinish = expectation(description: "detection.onDidFinish") let onLogicDidFinish = expectation(description: "logic.onDidFinish") - detection.onDidFinish = { _ in + detection.onDidFinish = { + Logger.tests.log("detection.onDidFinish \($0?.absoluteString ?? "", privacy: .public)") onDetectionDidFinish.fulfill() } logic.onDidFinish = { [now, urls] host, date in + Logger.tests.log("logic.onDidFinish \(host ?? "", privacy: .public) \("\(date)", privacy: .public)") XCTAssertEqual(host, urls.url1.host!) XCTAssertEqual(date, now) onLogicDidFinish.fulfill() } + Logger.tests.debug("➡️ goBack()") tab.goBack() waitForExpectations(timeout: 5) }