Skip to content

Commit

Permalink
Ignore form factor specific favorites if they're received in Sync res…
Browse files Browse the repository at this point in the history
…ponse (#529)

Task/Issue URL: https://app.asana.com/0/414235014887631/1205688495536992/f

Description:
Until FFS favorites support is released, deliberately ignore any FFS
favorites folders received in Sync response.
  • Loading branch information
ayoy authored Oct 12, 2023
1 parent 7cd525e commit 89cd93f
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import DDGSync
import Foundation

final class BookmarksResponseHandler {
// Before form-factor-specific favorites is supported, we deliberately ignore FFS folders.
static let ignoredFoldersUUIDs: Set<String> = ["desktop_favorites_root", "mobile_favorites_root"]

let clientTimestamp: Date?
let received: [SyncableBookmarkAdapter]
let context: NSManagedObjectContext
Expand Down Expand Up @@ -84,10 +87,11 @@ final class BookmarksResponseHandler {
self.favoritesUUIDs = favoritesUUIDs

let foldersWithoutParent = Set(parentFoldersToChildren.keys).subtracting(childrenToParents.keys)
.subtracting(Self.ignoredFoldersUUIDs)
topLevelFoldersSyncables = foldersWithoutParent.compactMap { syncablesByUUID[$0] }

bookmarkSyncablesWithoutParent = allUUIDs.subtracting(childrenToParents.keys)
.subtracting(foldersWithoutParent + [BookmarkEntity.Constants.favoritesFolderID])
.subtracting(foldersWithoutParent + [BookmarkEntity.Constants.favoritesFolderID] + Self.ignoredFoldersUUIDs)
.compactMap { syncablesByUUID[$0] }

BookmarkEntity.fetchBookmarks(with: allReceivedIDs, in: context)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//
// FormFactorSpecificFavoritesFoldersIgnoringTests.swift
// DuckDuckGo
//
// Copyright © 2023 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 XCTest
import Bookmarks
import BookmarksTestsUtils
import Common
import DDGSync
import Persistence
@testable import SyncDataProviders

private extension Syncable {
static func desktopFavoritesFolder(favorites: [String]) -> Syncable {
.folder(id: "desktop_favorites_root", children: favorites)
}

static func mobileFavoritesFolder(favorites: [String]) -> Syncable {
.folder(id: "mobile_favorites_root", children: favorites)
}
}

final class FormFactorSpecificFavoritesFoldersIgnoringTests: BookmarksProviderTestsBase {

func testThatDesktopFavoritesFolderIsIgnored() async throws {
let context = bookmarksDatabase.makeContext(concurrencyType: .privateQueueConcurrencyType)

let bookmarkTree = BookmarkTree {
Bookmark(id: "1", isFavorite: true)
Bookmark(id: "2")
}

let received: [Syncable] = [.desktopFavoritesFolder(favorites: ["1", "2"])]

let rootFolder = try await createEntitiesAndHandleSyncResponse(with: bookmarkTree, received: received, in: context)
assertEquivalent(withTimestamps: false, rootFolder, BookmarkTree {
Bookmark(id: "1", isFavorite: true)
Bookmark(id: "2")
})
}

func testThatMobileFavoritesFolderIsIgnored() async throws {
let context = bookmarksDatabase.makeContext(concurrencyType: .privateQueueConcurrencyType)

let bookmarkTree = BookmarkTree {
Bookmark(id: "1", isFavorite: true)
Bookmark(id: "2")
}

let received: [Syncable] = [.mobileFavoritesFolder(favorites: ["1", "2"])]

let rootFolder = try await createEntitiesAndHandleSyncResponse(with: bookmarkTree, received: received, in: context)
assertEquivalent(withTimestamps: false, rootFolder, BookmarkTree {
Bookmark(id: "1", isFavorite: true)
Bookmark(id: "2")
})
}

func testThatDesktopFavoritesFolderDoesNotAffectReceivedFavoritesFolder() async throws {
let context = bookmarksDatabase.makeContext(concurrencyType: .privateQueueConcurrencyType)

let bookmarkTree = BookmarkTree {
Bookmark(id: "1", isFavorite: true)
Bookmark(id: "2")
}

let received: [Syncable] = [
.favoritesFolder(favorites: ["1", "2"]),
.desktopFavoritesFolder(favorites: ["1", "2"])
]

let rootFolder = try await createEntitiesAndHandleSyncResponse(with: bookmarkTree, received: received, in: context)
assertEquivalent(withTimestamps: false, rootFolder, BookmarkTree {
Bookmark(id: "1", isFavorite: true)
Bookmark(id: "2", isFavorite: true)
})
}

func testThatMobileFavoritesFolderDoesNotAffectReceivedFavoritesFolder() async throws {
let context = bookmarksDatabase.makeContext(concurrencyType: .privateQueueConcurrencyType)

let bookmarkTree = BookmarkTree {
Bookmark(id: "1", isFavorite: true)
Bookmark(id: "2")
}

let received: [Syncable] = [
.favoritesFolder(favorites: ["1", "2"]),
.mobileFavoritesFolder(favorites: ["1", "2"])
]

let rootFolder = try await createEntitiesAndHandleSyncResponse(with: bookmarkTree, received: received, in: context)
assertEquivalent(withTimestamps: false, rootFolder, BookmarkTree {
Bookmark(id: "1", isFavorite: true)
Bookmark(id: "2", isFavorite: true)
})
}

// MARK: - Helpers

func createEntitiesAndHandleSyncResponse(
with bookmarkTree: BookmarkTree,
sent: [Syncable] = [],
received: [Syncable],
clientTimestamp: Date = Date(),
serverTimestamp: String = "1234",
in context: NSManagedObjectContext
) async throws -> BookmarkEntity {

context.performAndWait {
BookmarkUtils.prepareFoldersStructure(in: context)
bookmarkTree.createEntities(in: context)
try! context.save()
}

try await provider.handleSyncResponse(sent: sent, received: received, clientTimestamp: Date(), serverTimestamp: "1234", crypter: crypter)

var rootFolder: BookmarkEntity!

context.performAndWait {
context.refreshAllObjects()
rootFolder = BookmarkUtils.fetchRootFolder(context)
}

return rootFolder
}
}

0 comments on commit 89cd93f

Please sign in to comment.