From 13dd008a1184cc1a548e6807f57e5818a4239dbe Mon Sep 17 00:00:00 2001 From: Bartek Waresiak Date: Mon, 27 Nov 2023 14:52:27 +0100 Subject: [PATCH 1/9] Add proper migration tests --- Package.swift | 15 + ...BookmarkFormFactorFavoritesMigration.swift | 29 +- .../BookmarksTestDBBuilder.swift | 321 ++++++++++++++++++ .../BookmarkMigrationTests.swift | 166 +++++++++ Tests/BookmarksTests/BookmarkUtilsTests.swift | 51 --- .../Resources/Bookmarks_V1.sqlite | Bin 0 -> 32768 bytes .../Resources/Bookmarks_V1.sqlite-shm | Bin 0 -> 32768 bytes .../Resources/Bookmarks_V1.sqlite-wal | Bin 0 -> 16512 bytes .../Resources/Bookmarks_V3.sqlite | Bin 0 -> 49152 bytes .../Resources/Bookmarks_V3.sqlite-shm | Bin 0 -> 32768 bytes .../Resources/Bookmarks_V3.sqlite-wal | 0 11 files changed, 523 insertions(+), 59 deletions(-) create mode 100644 Sources/BookmarksTestDBBuilder/BookmarksTestDBBuilder.swift create mode 100644 Tests/BookmarksTests/BookmarkMigrationTests.swift create mode 100644 Tests/BookmarksTests/Resources/Bookmarks_V1.sqlite create mode 100644 Tests/BookmarksTests/Resources/Bookmarks_V1.sqlite-shm create mode 100644 Tests/BookmarksTests/Resources/Bookmarks_V1.sqlite-wal create mode 100644 Tests/BookmarksTests/Resources/Bookmarks_V3.sqlite create mode 100644 Tests/BookmarksTests/Resources/Bookmarks_V3.sqlite-shm create mode 100644 Tests/BookmarksTests/Resources/Bookmarks_V3.sqlite-wal diff --git a/Package.swift b/Package.swift index 8f561e30c..bd3d9a54d 100644 --- a/Package.swift +++ b/Package.swift @@ -82,6 +82,13 @@ let package = Package( .process("BookmarksModel.xcdatamodeld") ] ), + .executableTarget(name: "BookmarksTestDBBuilder", + dependencies: [ + "Bookmarks", + "Persistence" + ], + path: "Sources/BookmarksTestDBBuilder" + ), .target( name: "BookmarksTestsUtils", dependencies: [ @@ -234,6 +241,14 @@ let package = Package( dependencies: [ "Bookmarks", "BookmarksTestsUtils" + ], + resources: [ + .copy("Resources/Bookmarks_V1.sqlite"), + .copy("Resources/Bookmarks_V1.sqlite-shm"), + .copy("Resources/Bookmarks_V1.sqlite-wal"), + .copy("Resources/Bookmarks_V3.sqlite"), + .copy("Resources/Bookmarks_V3.sqlite-shm"), + .copy("Resources/Bookmarks_V3.sqlite-wal") ]), .testTarget( name: "BrowserServicesKitTests", diff --git a/Sources/Bookmarks/Migrations/BookmarkFormFactorFavoritesMigration.swift b/Sources/Bookmarks/Migrations/BookmarkFormFactorFavoritesMigration.swift index 49fce7802..a1c563907 100644 --- a/Sources/Bookmarks/Migrations/BookmarkFormFactorFavoritesMigration.swift +++ b/Sources/Bookmarks/Migrations/BookmarkFormFactorFavoritesMigration.swift @@ -25,21 +25,33 @@ public class BookmarkFormFactorFavoritesMigration { case couldNotLoadDatabase } + public static func modelURL(forVersion version: Int) -> URL? { + let bundle = Bookmarks.bundle + var momUrl: URL? + if version == 1 { + momUrl = bundle.url(forResource: "BookmarksModel.momd/BookmarksModel", withExtension: "mom") + } else { + momUrl = bundle.url(forResource: "BookmarksModel.momd/BookmarksModel \(version)", withExtension: "mom") + } + return momUrl + } + public static func getFavoritesOrderFromPreV4Model(dbContainerLocation: URL, dbFileURL: URL, errorEvents: EventMapping? = nil) -> [String]? { var oldFavoritesOrder: [String]? - let metadata = try? NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, - at: dbFileURL) - if let metadata, let version = metadata["NSStoreModelVersionHashesVersion"] as? Int, version < 4 { + guard let metadata = try? NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, + at: dbFileURL), + let latestModel = CoreDataDatabase.loadModel(from: bundle, named: "BookmarksModel") else { return nil } + + if latestModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: metadata) == false{ // Before migrating to latest scheme version, read order of favorites from DB - let v3BookmarksModel = NSManagedObjectModel.mergedModel(from: [Bookmarks.bundle], forStoreMetadata: metadata)! - - let oldDB = CoreDataDatabase(name: "Bookmarks", + let oldBookmarksModel = NSManagedObjectModel.mergedModel(from: [Bookmarks.bundle], forStoreMetadata: metadata)! + let oldDB = CoreDataDatabase(name: dbFileURL.deletingPathExtension().lastPathComponent, containerLocation: dbContainerLocation, - model: v3BookmarksModel) + model: oldBookmarksModel) oldDB.loadStore { context, error in guard let context = context else { errorEvents?.fire(.couldNotLoadDatabase, error: error) @@ -47,7 +59,8 @@ public class BookmarkFormFactorFavoritesMigration { } let favs = BookmarkUtils.fetchLegacyFavoritesFolder(context) - oldFavoritesOrder = favs?.favoritesArray.compactMap { $0.uuid } + let orderedFavorites = favs?.favorites?.array as? [BookmarkEntity] ?? [] + oldFavoritesOrder = orderedFavorites.compactMap { $0.uuid } } } return oldFavoritesOrder diff --git a/Sources/BookmarksTestDBBuilder/BookmarksTestDBBuilder.swift b/Sources/BookmarksTestDBBuilder/BookmarksTestDBBuilder.swift new file mode 100644 index 000000000..5c7857a1a --- /dev/null +++ b/Sources/BookmarksTestDBBuilder/BookmarksTestDBBuilder.swift @@ -0,0 +1,321 @@ +// +// BookmarksTestDBBuilder.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 Cocoa +import Foundation +import CoreData +import Persistence +import Bookmarks +//import BookmarksTestsUtils + +@main +struct BookmarksTestDBBuilder { + + static func main() { + generateDatabase(modelVersion: 3) + } + + private static func generateDatabase(modelVersion: Int) { + let bundle = Bookmarks.bundle + var momUrl: URL? + if modelVersion == 1 { + momUrl = bundle.url(forResource: "BookmarksModel.momd/BookmarksModel", withExtension: "mom") + } else { + momUrl = bundle.url(forResource: "BookmarksModel.momd/BookmarksModel \(modelVersion)", withExtension: "mom") + } + + guard let dir = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first else { + fatalError("Could not find directory") + } + + let model = NSManagedObjectModel(contentsOf: momUrl!) + let stack = CoreDataDatabase(name: "Bookmarks_V\(modelVersion)", + containerLocation: dir, + model: model!) + stack.loadStore() + + let context = stack.makeContext(concurrencyType: .privateQueueConcurrencyType) + context.performAndWait { + buildTestTree(in: context) + } + } + + private static func buildTestTree(in context: NSManagedObjectContext) { + /* When modifying, please add requirements to list below + - Test roof folders (root, favorites) migration and order. + - Test regular folder migration and order. + - Test Form Factor favorites. + */ + let bookmarkTree = BookmarkTree { + Bookmark(id: "1") + Bookmark(id: "2", favoritedOn: [.unified, .mobile]) + Folder(id: "3") { + Folder(id: "31") {} + Bookmark(id: "32", favoritedOn: [.unified, .desktop]) + Bookmark(id: "33", favoritedOn: [.unified, .desktop, .mobile]) + } + Bookmark(id: "4", favoritedOn: [.unified, .desktop, .mobile]) + Bookmark(id: "5", favoritedOn: [.unified, .desktop]) + } + + bookmarkTree.createEntities(in: context) + + // Apply order to make sure order of generation (or PK) does not influence order of results + let unifiedRoot = BookmarkUtils.fetchFavoritesFolder(withUUID: FavoritesFolderID.unified.rawValue, + in: context)! + reorderFavorites(to: ["5", "4", "33", "32", "2"], favoritesRoot: unifiedRoot) + + if let desktopRoot = BookmarkUtils.fetchFavoritesFolder(withUUID: FavoritesFolderID.desktop.rawValue, + in: context) { + reorderFavorites(to: ["32", "4", "33", "5"], favoritesRoot: desktopRoot) + } + + if let mobileRoot = BookmarkUtils.fetchFavoritesFolder(withUUID: FavoritesFolderID.mobile.rawValue, + in: context) { + reorderFavorites(to: ["4", "2", "33"], favoritesRoot: mobileRoot) + } + + try! context.save() + } + + static func reorderFavorites(to ids: [String], favoritesRoot: BookmarkEntity) { + let favs = favoritesRoot.favoritesArray + for fav in favs { + fav.removeFromFavorites(favoritesRoot: favoritesRoot) + } + + for id in ids { + let fav = favs.first(where: { $0.uuid == id}) + fav?.addToFavorites(favoritesRoot: favoritesRoot) + } + } +} + +public enum BookmarkTreeNode { + case bookmark(id: String, name: String?, url: String?, favoritedOn: [FavoritesFolderID], modifiedAt: Date?, isDeleted: Bool, isOrphaned: Bool) + case folder(id: String, name: String?, children: [BookmarkTreeNode], modifiedAt: Date?, isDeleted: Bool, isOrphaned: Bool) + + public var id: String { + switch self { + case .bookmark(let id, _, _, _, _, _, _): + return id + case .folder(let id, _, _, _, _, _): + return id + } + } + + public var name: String? { + switch self { + case .bookmark(_, let name, _, _, _, _, _): + return name + case .folder(_, let name, _, _, _, _): + return name + } + } + + public var modifiedAt: Date? { + switch self { + case .bookmark(_, _, _, _, let modifiedAt, _, _): + return modifiedAt + case .folder(_, _, _, let modifiedAt, _, _): + return modifiedAt + } + } + + public var isDeleted: Bool { + switch self { + case .bookmark(_, _, _, _, _, let isDeleted, _): + return isDeleted + case .folder(_, _, _, _, let isDeleted, _): + return isDeleted + } + } + + public var isOrphaned: Bool { + switch self { + case .bookmark(_, _, _, _, _, _, let isOrphaned): + return isOrphaned + case .folder(_, _, _, _, _, let isOrphaned): + return isOrphaned + } + } +} + +public protocol BookmarkTreeNodeConvertible { + func asBookmarkTreeNode() -> BookmarkTreeNode +} + +public struct Bookmark: BookmarkTreeNodeConvertible { + var id: String + var name: String? + var url: String? + var favoritedOn: [FavoritesFolderID] + var modifiedAt: Date? + var isDeleted: Bool + var isOrphaned: Bool + + public init(_ name: String? = nil, id: String? = nil, url: String? = nil, favoritedOn: [FavoritesFolderID] = [], modifiedAt: Date? = nil, isDeleted: Bool = false, isOrphaned: Bool = false) { + self.id = id ?? UUID().uuidString + self.name = name ?? id + self.url = (url ?? name) ?? id + self.favoritedOn = favoritedOn + self.modifiedAt = modifiedAt + self.isDeleted = isDeleted + self.isOrphaned = isOrphaned + } + + public func asBookmarkTreeNode() -> BookmarkTreeNode { + .bookmark(id: id, name: name, url: url, favoritedOn: favoritedOn, modifiedAt: modifiedAt, isDeleted: isDeleted, isOrphaned: isOrphaned) + } +} + +public struct Folder: BookmarkTreeNodeConvertible { + var id: String + var name: String? + var modifiedAt: Date? + var isDeleted: Bool + var isOrphaned: Bool + var children: [BookmarkTreeNode] + + public init(_ name: String? = nil, id: String? = nil, modifiedAt: Date? = nil, isDeleted: Bool = false, isOrphaned: Bool = false, @BookmarkTreeBuilder children: () -> [BookmarkTreeNode] = { [] }) { + self.id = id ?? UUID().uuidString + self.name = name ?? id + self.modifiedAt = modifiedAt + self.isDeleted = isDeleted + self.isOrphaned = isOrphaned + self.children = children() + } + + public func asBookmarkTreeNode() -> BookmarkTreeNode { + .folder(id: id, name: name, children: children, modifiedAt: modifiedAt, isDeleted: isDeleted, isOrphaned: isOrphaned) + } +} + +@resultBuilder +public struct BookmarkTreeBuilder { + + public static func buildBlock(_ components: BookmarkTreeNodeConvertible...) -> [BookmarkTreeNode] { + components.compactMap { $0.asBookmarkTreeNode() } + } +} + +public struct BookmarkTree { + + public init(modifiedAt: Date? = nil, @BookmarkTreeBuilder builder: () -> [BookmarkTreeNode]) { + self.modifiedAt = modifiedAt + self.bookmarkTreeNodes = builder() + } + + @discardableResult + public func createEntities(in context: NSManagedObjectContext) -> (BookmarkEntity, [BookmarkEntity]) { + let (rootFolder, orphans) = createEntitiesForCheckingModifiedAt(in: context) + return (rootFolder, orphans) + } + + // swiftlint:disable large_tuple + @discardableResult + public func createEntitiesForCheckingModifiedAt(in context: NSManagedObjectContext) -> (BookmarkEntity, [BookmarkEntity]) { + BookmarkUtils.prepareLegacyFoldersStructure(in: context) + + let rootFolder = BookmarkUtils.fetchRootFolder(context)! + rootFolder.modifiedAt = modifiedAt + let favoritesFolders = BookmarkUtils.fetchFavoritesFolders(withUUIDs: Set(FavoritesFolderID.allCases.map(\.rawValue)), in: context) + var orphans = [BookmarkEntity]() + for bookmarkTreeNode in bookmarkTreeNodes { + let entity = BookmarkEntity.makeWithModifiedAtConstraints(with: bookmarkTreeNode, rootFolder: rootFolder, favoritesFolders: favoritesFolders, in: context) + if bookmarkTreeNode.isOrphaned { + orphans.append(entity) + } + } + return (rootFolder, orphans) + } + // swiftlint:enable large_tuple + + let modifiedAt: Date? + let bookmarkTreeNodes: [BookmarkTreeNode] +} + +public extension BookmarkEntity { + @discardableResult + static func make(with treeNode: BookmarkTreeNode, rootFolder: BookmarkEntity, favoritesFolders: [BookmarkEntity], in context: NSManagedObjectContext) -> BookmarkEntity { + makeWithModifiedAtConstraints(with: treeNode, rootFolder: rootFolder, favoritesFolders: favoritesFolders, in: context) + } + + @discardableResult + static func makeWithModifiedAtConstraints(with treeNode: BookmarkTreeNode, rootFolder: BookmarkEntity, favoritesFolders: [BookmarkEntity], in context: NSManagedObjectContext) -> BookmarkEntity { + var entity: BookmarkEntity! + + var queues: [[BookmarkTreeNode]] = [[treeNode]] + var parents: [BookmarkEntity] = [rootFolder] + + while !queues.isEmpty { + var queue = queues.removeFirst() + let parent = parents.removeFirst() + + while !queue.isEmpty { + let node = queue.removeFirst() + + switch node { + case .bookmark(let id, let name, let url, let favoritedOn, let modifiedAt, let isDeleted, let isOrphaned): + let bookmarkEntity = BookmarkEntity(context: context) + if entity == nil { + entity = bookmarkEntity + } + bookmarkEntity.uuid = id + bookmarkEntity.isFolder = false + bookmarkEntity.title = name + bookmarkEntity.url = url + bookmarkEntity.modifiedAt = modifiedAt + + for platform in favoritedOn { + if let favoritesFolder = favoritesFolders.first(where: { $0.uuid == platform.rawValue }) { + bookmarkEntity.addToFavorites(favoritesRoot: favoritesFolder) + } + } + + if isDeleted { + bookmarkEntity.markPendingDeletion() + } + if !isOrphaned { + bookmarkEntity.parent = parent + } + case .folder(let id, let name, let children, let modifiedAt, let isDeleted, let isOrphaned): + let bookmarkEntity = BookmarkEntity(context: context) + if entity == nil { + entity = bookmarkEntity + } + bookmarkEntity.uuid = id + bookmarkEntity.isFolder = true + bookmarkEntity.title = name + bookmarkEntity.modifiedAt = modifiedAt + if isDeleted { + bookmarkEntity.markPendingDeletion() + } + if !isOrphaned { + bookmarkEntity.parent = parent + } + parents.append(bookmarkEntity) + queues.append(children) + } + } + } + + return entity + } +} diff --git a/Tests/BookmarksTests/BookmarkMigrationTests.swift b/Tests/BookmarksTests/BookmarkMigrationTests.swift new file mode 100644 index 000000000..d818a2c01 --- /dev/null +++ b/Tests/BookmarksTests/BookmarkMigrationTests.swift @@ -0,0 +1,166 @@ +// +// BookmarkMigrationTests.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 BookmarksTestsUtils +import XCTest +import Persistence +@testable import Bookmarks +import Foundation + +class BookmarkMigrationTests: XCTestCase { + + var location: URL! + var resourceURLDir: URL! + + override func setUp() { + super.setUp() + + location = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) + + guard let location = Bundle(for: BookmarkMigrationTests.self).resourceURL else { + XCTFail() + return + } + resourceURLDir = location.appending(path: "BrowserServicesKit_BookmarksTests.bundle/Contents/Resources/") + } + + override func tearDown() { + super.tearDown() + + try? FileManager.default.removeItem(at: location) + } + + func copyDatabase(name: String, formDirectory: URL, toDirectory: URL) throws { + + let fileManager = FileManager.default + try fileManager.createDirectory(at: toDirectory, withIntermediateDirectories: false) + for ext in ["sqlite", "sqlite-shm", "sqlite-wal"] { + + try fileManager.copyItem(at: formDirectory.appendingPathComponent("\(name).\(ext)", conformingTo: .database), + to: toDirectory.appendingPathComponent("\(name).\(ext)")) + } + } + + func loadDatabase(name: String) -> CoreDataDatabase? { + let bundle = Bookmarks.bundle + guard let model = CoreDataDatabase.loadModel(from: bundle, named: "BookmarksModel") else { + return nil + } + let bookmarksDatabase = CoreDataDatabase(name: name, containerLocation: location, model: model) + bookmarksDatabase.loadStore() + return bookmarksDatabase + } + + func testWhenMigratingFromV1ThenRootFoldersContentsArePreservedInOrder() throws { + + try copyDatabase(name: "Bookmarks_V1", formDirectory: resourceURLDir, toDirectory: location) + print(location) + let legacyFavoritesInOrder = BookmarkFormFactorFavoritesMigration.getFavoritesOrderFromPreV4Model(dbContainerLocation: location, + dbFileURL: location.appendingPathComponent("Bookmarks_V1.sqlite", conformingTo: .database)) + + // Now perform migration and test it + guard let migratedStack = loadDatabase(name: "Bookmarks_V1") else { + XCTFail("Could not initialize legacy stack") + return + } + + let latestContext = migratedStack.makeContext(concurrencyType: .privateQueueConcurrencyType) + latestContext.performAndWait({ + BookmarkFormFactorFavoritesMigration.migrateToFormFactorSpecificFavorites(byCopyingExistingTo: FavoritesFolderID.mobile, + preservingOrderOf: legacyFavoritesInOrder, + in: latestContext) + + let mobileFavoritesArray = BookmarkUtils.fetchFavoritesFolder(withUUID: FavoritesFolderID.mobile.rawValue, in: latestContext)?.favoritesArray.compactMap(\.uuid) + XCTAssertEqual(legacyFavoritesInOrder, mobileFavoritesArray) + }) + + // Test whole structure + let bookmarkTree = BookmarkTree { + Bookmark(id: "1") + Bookmark(id: "2", favoritedOn: [.unified, .mobile]) + Folder(id: "3") { + Folder(id: "31") {} + Bookmark(id: "32", favoritedOn: [.unified, .desktop]) + Bookmark(id: "33", favoritedOn: [.unified, .desktop, .mobile]) + } + Bookmark(id: "4", favoritedOn: [.unified, .desktop, .mobile]) + Bookmark(id: "5", favoritedOn: [.unified, .desktop]) + } + + try? migratedStack.tearDown(deleteStores: true) + } + + func atestThatMigrationToFormFactorSpecificFavoritesAddsFavoritesToNativeFolder() async throws { + + guard let bookmarksDatabase = loadDatabase(name: "Any") else { + XCTFail("Failed to load model") + return + } + + let context = bookmarksDatabase.makeContext(concurrencyType: .privateQueueConcurrencyType) + + context.performAndWait { + BookmarkUtils.insertRootFolder(uuid: BookmarkEntity.Constants.rootFolderID, into: context) + BookmarkUtils.insertRootFolder(uuid: FavoritesFolderID.unified.rawValue, into: context) + try! context.save() + } + + let bookmarkTree = BookmarkTree { + Bookmark(id: "1") + Bookmark(id: "2", favoritedOn: [.unified]) + Folder(id: "10") { + Bookmark(id: "12", favoritedOn: [.unified]) + } + Bookmark(id: "3", favoritedOn: [.unified]) + Bookmark(id: "4", favoritedOn: [.unified]) + } + + context.performAndWait { + bookmarkTree.createEntities(in: context) + + try! context.save() + let favoritesArray = BookmarkUtils.fetchFavoritesFolder(withUUID: FavoritesFolderID.unified.rawValue, in: context)?.favoritesArray.compactMap(\.uuid) + + BookmarkFormFactorFavoritesMigration.migrateToFormFactorSpecificFavorites(byCopyingExistingTo: FavoritesFolderID.mobile, + preservingOrderOf: nil, + in: context) + + try! context.save() + + let mobileFavoritesArray = BookmarkUtils.fetchFavoritesFolder(withUUID: FavoritesFolderID.mobile.rawValue, in: context)?.favoritesArray.compactMap(\.uuid) + XCTAssertEqual(favoritesArray, mobileFavoritesArray) + + let rootFolder = BookmarkUtils.fetchRootFolder(context)! + assertEquivalent(withTimestamps: false, rootFolder, BookmarkTree { + Bookmark(id: "1") + Bookmark(id: "2", favoritedOn: [.mobile, .unified]) + Folder(id: "10") { + Bookmark(id: "12", favoritedOn: [.mobile, .unified]) + } + Bookmark(id: "3", favoritedOn: [.mobile, .unified]) + Bookmark(id: "4", favoritedOn: [.mobile, .unified]) + }) + } + + try? bookmarksDatabase.tearDown(deleteStores: true) + } + + + +} diff --git a/Tests/BookmarksTests/BookmarkUtilsTests.swift b/Tests/BookmarksTests/BookmarkUtilsTests.swift index 8588e4c44..3cd9637cf 100644 --- a/Tests/BookmarksTests/BookmarkUtilsTests.swift +++ b/Tests/BookmarksTests/BookmarkUtilsTests.swift @@ -48,57 +48,6 @@ final class BookmarkUtilsTests: XCTestCase { try? FileManager.default.removeItem(at: location) } - func testThatMigrationToFormFactorSpecificFavoritesAddsFavoritesToNativeFolder() async throws { - - let context = bookmarksDatabase.makeContext(concurrencyType: .privateQueueConcurrencyType) - - context.performAndWait { - BookmarkUtils.insertRootFolder(uuid: BookmarkEntity.Constants.rootFolderID, into: context) - BookmarkUtils.insertRootFolder(uuid: FavoritesFolderID.unified.rawValue, into: context) - try! context.save() - } - - let bookmarkTree = BookmarkTree { - Bookmark(id: "1") - Bookmark(id: "2", favoritedOn: [.unified]) - Folder(id: "10") { - Bookmark(id: "12", favoritedOn: [.unified]) - } - Bookmark(id: "3", favoritedOn: [.unified]) - Bookmark(id: "4", favoritedOn: [.unified]) - } - - context.performAndWait { - bookmarkTree.createEntities(in: context) - - try! context.save() - let favoritesArray = BookmarkUtils.fetchFavoritesFolder(withUUID: FavoritesFolderID.unified.rawValue, in: context)?.favoritesArray.compactMap(\.uuid) - - BookmarkFormFactorFavoritesMigration - .migrateToFormFactorSpecificFavorites( - byCopyingExistingTo: .mobile, - preservingOrderOf: nil, - in: context - ) - - try! context.save() - - let mobileFavoritesArray = BookmarkUtils.fetchFavoritesFolder(withUUID: FavoritesFolderID.mobile.rawValue, in: context)?.favoritesArray.compactMap(\.uuid) - XCTAssertEqual(favoritesArray, mobileFavoritesArray) - - let rootFolder = BookmarkUtils.fetchRootFolder(context)! - assertEquivalent(withTimestamps: false, rootFolder, BookmarkTree { - Bookmark(id: "1") - Bookmark(id: "2", favoritedOn: [.mobile, .unified]) - Folder(id: "10") { - Bookmark(id: "12", favoritedOn: [.mobile, .unified]) - } - Bookmark(id: "3", favoritedOn: [.mobile, .unified]) - Bookmark(id: "4", favoritedOn: [.mobile, .unified]) - }) - } - } - func testCopyFavoritesWhenDisablingSyncInDisplayNativeMode() async throws { let context = bookmarksDatabase.makeContext(concurrencyType: .privateQueueConcurrencyType) diff --git a/Tests/BookmarksTests/Resources/Bookmarks_V1.sqlite b/Tests/BookmarksTests/Resources/Bookmarks_V1.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..dbfdd21758093e61fa28c7a87008c716a1b5151a GIT binary patch literal 32768 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 hRspOg^O?gisTx%+45{|P39j>!N3 literal 0 HcmV?d00001 diff --git a/Tests/BookmarksTests/Resources/Bookmarks_V1.sqlite-shm b/Tests/BookmarksTests/Resources/Bookmarks_V1.sqlite-shm new file mode 100644 index 0000000000000000000000000000000000000000..0dd5f7f2059986ad8328c1fee37ff82f23e5635e GIT binary patch literal 32768 zcmeI)y$J$A5C+io7eNpc;d&4QZNS7bjKm5IjYW&F46zO~3ox|>;hYsYObzwk2g44- zu)!-}irXaRG@}|R4cqbdqDF)5=5f5v4!h;F?62Kx z%A63Wr$F3!6aoYY5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ N009C72oU%&fhU=}C3ye< literal 0 HcmV?d00001 diff --git a/Tests/BookmarksTests/Resources/Bookmarks_V1.sqlite-wal b/Tests/BookmarksTests/Resources/Bookmarks_V1.sqlite-wal new file mode 100644 index 0000000000000000000000000000000000000000..aff9e2d4dabfcf628c4ae150a2ce4b6ad5dfee0a GIT binary patch literal 16512 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 literal 0 HcmV?d00001 diff --git a/Tests/BookmarksTests/Resources/Bookmarks_V3.sqlite-shm b/Tests/BookmarksTests/Resources/Bookmarks_V3.sqlite-shm new file mode 100644 index 0000000000000000000000000000000000000000..fe9ac2845eca6fe6da8a63cd096d9cf9e24ece10 GIT binary patch literal 32768 zcmeIuAr62r3 Date: Mon, 27 Nov 2023 15:28:06 +0100 Subject: [PATCH 2/9] Add tests for V2, fix tests for V3 --- Package.swift | 3 +++ .../BookmarkMigrationTests.swift | 19 ++++++++++++++---- .../Resources/Bookmarks_V2.sqlite | Bin 0 -> 49152 bytes .../Resources/Bookmarks_V2.sqlite-shm | Bin 0 -> 32768 bytes .../Resources/Bookmarks_V2.sqlite-wal | Bin 0 -> 32992 bytes .../Resources/Bookmarks_V3.sqlite | Bin 49152 -> 49152 bytes .../Resources/Bookmarks_V3.sqlite-shm | Bin 32768 -> 32768 bytes .../Resources/Bookmarks_V3.sqlite-wal | Bin 0 -> 32992 bytes 8 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 Tests/BookmarksTests/Resources/Bookmarks_V2.sqlite create mode 100644 Tests/BookmarksTests/Resources/Bookmarks_V2.sqlite-shm create mode 100644 Tests/BookmarksTests/Resources/Bookmarks_V2.sqlite-wal diff --git a/Package.swift b/Package.swift index bd3d9a54d..a148a6747 100644 --- a/Package.swift +++ b/Package.swift @@ -246,6 +246,9 @@ let package = Package( .copy("Resources/Bookmarks_V1.sqlite"), .copy("Resources/Bookmarks_V1.sqlite-shm"), .copy("Resources/Bookmarks_V1.sqlite-wal"), + .copy("Resources/Bookmarks_V2.sqlite"), + .copy("Resources/Bookmarks_V2.sqlite-shm"), + .copy("Resources/Bookmarks_V2.sqlite-wal"), .copy("Resources/Bookmarks_V3.sqlite"), .copy("Resources/Bookmarks_V3.sqlite-shm"), .copy("Resources/Bookmarks_V3.sqlite-wal") diff --git a/Tests/BookmarksTests/BookmarkMigrationTests.swift b/Tests/BookmarksTests/BookmarkMigrationTests.swift index d818a2c01..015236f00 100644 --- a/Tests/BookmarksTests/BookmarkMigrationTests.swift +++ b/Tests/BookmarksTests/BookmarkMigrationTests.swift @@ -68,14 +68,25 @@ class BookmarkMigrationTests: XCTestCase { } func testWhenMigratingFromV1ThenRootFoldersContentsArePreservedInOrder() throws { + try commonMigrationTestForDatabase(name: "Bookmarks_V1") + } + + func testWhenMigratingFromV2ThenRootFoldersContentsArePreservedInOrder() throws { + try commonMigrationTestForDatabase(name: "Bookmarks_V2") + } + + func testWhenMigratingFromV3ThenRootFoldersContentsArePreservedInOrder() throws { + try commonMigrationTestForDatabase(name: "Bookmarks_V3") + } + + func commonMigrationTestForDatabase(name: String) throws { - try copyDatabase(name: "Bookmarks_V1", formDirectory: resourceURLDir, toDirectory: location) - print(location) + try copyDatabase(name: name, formDirectory: resourceURLDir, toDirectory: location) let legacyFavoritesInOrder = BookmarkFormFactorFavoritesMigration.getFavoritesOrderFromPreV4Model(dbContainerLocation: location, - dbFileURL: location.appendingPathComponent("Bookmarks_V1.sqlite", conformingTo: .database)) + dbFileURL: location.appendingPathComponent("\(name).sqlite", conformingTo: .database)) // Now perform migration and test it - guard let migratedStack = loadDatabase(name: "Bookmarks_V1") else { + guard let migratedStack = loadDatabase(name: name) else { XCTFail("Could not initialize legacy stack") return } diff --git a/Tests/BookmarksTests/Resources/Bookmarks_V2.sqlite b/Tests/BookmarksTests/Resources/Bookmarks_V2.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..3c2b9e75ce3cbc14abc0e9b5354753b3f6d1b24c GIT binary patch literal 49152 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 literal 0 HcmV?d00001 diff --git a/Tests/BookmarksTests/Resources/Bookmarks_V2.sqlite-wal b/Tests/BookmarksTests/Resources/Bookmarks_V2.sqlite-wal new file mode 100644 index 0000000000000000000000000000000000000000..17e45ca3174d458a3059877a3c5e6cf77d46ee03 GIT binary patch literal 32992 zcmeI*&r6g+9LMpQ=h|is`?kX!DghCYFqdV-*^WA-(dF^RF zK7)JDM=z*7pHfQIDcdFo^NVfMmtKr-z486%)%JNa6gQ7VW&F{$+Qj8A3yU>oP|H_k zerX6GfB*srAb;0Kr_#ROUnq2)ZtLzkc&6A{?6sMIYo}Jp1@6`y zp8nA9?zFi;ymn5>KDk*tCr9L=_|hR$vRy9PdKv-FG*C`bC4H648UhF)fB*srAb;uweK$v+kE5XP>r2>fN-i-i{CpOEV@15S?-C@#>ugUU)of zbAgzhMI{%w{&HaV)1J01rCeY{$%Oor&oU#kGH$Yg=ki`g)^FCF2>}EUKmY**5I_I{ z1Q0*~0R+|{uu5!D+C^YfgXLWWrIaAtMzEX<*lb`a7dY_v-L+j)w_CYiU=8Y&Abuvx5 literal 0 HcmV?d00001 diff --git a/Tests/BookmarksTests/Resources/Bookmarks_V3.sqlite b/Tests/BookmarksTests/Resources/Bookmarks_V3.sqlite index 8d7a88d90b626203ac534867f2da7f26b7bb40cf..494c6d24054f0cd685b90c33fba9d3b73fd1f303 100644 GIT binary patch delta 50 zcmZo@U~Xt&-XOP5*}~P$+0eyQ*VWY7RoBGHz(m){+1Odv(%IO}#oXA$)YQUpv*Wt` Ff&gci4h;YR delta 50 zcmZo@U~Xt&-XOP5*}%lo)WyI=*UibqRM*7Z+)3BT$jn^V$kfQi)WFTq6v*4`xNg57 E09vIDlmGw# diff --git a/Tests/BookmarksTests/Resources/Bookmarks_V3.sqlite-shm b/Tests/BookmarksTests/Resources/Bookmarks_V3.sqlite-shm index fe9ac2845eca6fe6da8a63cd096d9cf9e24ece10..0d1100a08f09b153cda173e17ee086595c0278ff 100644 GIT binary patch delta 219 zcmZo@U}|V!s+V}A%K!pQK+MR%Aix2nd4Txvshnle7IwY1vEOe+Y+4Yo$4K2ezr;+K zRP{ikzyM_KeF|90%|>`(|d}EVe(FJS>z59SWm@-PtAk3l$wa6n2TgqKr~Rb72!9D1r_J zLe|YgAb}uW`a=+S=}-~HM)W^Y%RoDnBt=9f4!l&)N4r>*alU zGp;=99uv#QlR{Jq-q!7!9@%l}Y{P}IJq<(6lUwwunEt5<&o^%US}#rg}K1s z;ak0jzBQcYTp$+j7t~8b@rigpEhC~G)D^!*&$vA{2tWV=5P$##AOHafKmY;|fWSWz zsJ7$6^E@Ri5s4;5!c}6!jqZ-;$u-k{%1_mJT&d39uks4BKt-IK{=mdfJq zbAM|^?cUQ{rEewx1) z#eQ#7saFjIcB{_#X451#yM(#G?d{Di_rJfX=fEIF1woIgKrd*7Uea6oK(Fa8edhMq zAOHafKmY;|fB*y_009U<00IywCjnau%XXw?IUesyE?h1gE~2JJ+0ybHvl}rbPyZbr zMVJfh9U5G+dtl$8~Jld>}2d|N*_u=IfldQE_?@?BF^ z`iKL^RHdTkC953W&`SqbOhB3x~y>Wa~e@p&&kPBQ9`so5!=n363`2c4F z*J)x-Qe#jMfB*y_009U<00Izz00bZaf!QYD*g`K4D24{+K$_Au<)7vPo*wqk|5G^7 wUbud8eO+Ua3*bJ2+4d)a{z3o(5P$##AOHafKmY;|fWUt(!1o6H)qMm%0Q?E{TmS$7 literal 0 HcmV?d00001 From 0032a2f582c00de9b610c8f6c91942a4f4c1bf74 Mon Sep 17 00:00:00 2001 From: Dominik Kapusta Date: Mon, 27 Nov 2023 15:30:50 +0100 Subject: [PATCH 3/9] Refactor BookmarkFormFactorFavoritesMigration --- ...BookmarkFormFactorFavoritesMigration.swift | 54 ++++++++----------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/Sources/Bookmarks/Migrations/BookmarkFormFactorFavoritesMigration.swift b/Sources/Bookmarks/Migrations/BookmarkFormFactorFavoritesMigration.swift index a1c563907..4f73e8b38 100644 --- a/Sources/Bookmarks/Migrations/BookmarkFormFactorFavoritesMigration.swift +++ b/Sources/Bookmarks/Migrations/BookmarkFormFactorFavoritesMigration.swift @@ -25,43 +25,35 @@ public class BookmarkFormFactorFavoritesMigration { case couldNotLoadDatabase } - public static func modelURL(forVersion version: Int) -> URL? { - let bundle = Bookmarks.bundle - var momUrl: URL? - if version == 1 { - momUrl = bundle.url(forResource: "BookmarksModel.momd/BookmarksModel", withExtension: "mom") - } else { - momUrl = bundle.url(forResource: "BookmarksModel.momd/BookmarksModel \(version)", withExtension: "mom") - } - return momUrl - } - public static func getFavoritesOrderFromPreV4Model(dbContainerLocation: URL, dbFileURL: URL, errorEvents: EventMapping? = nil) -> [String]? { - var oldFavoritesOrder: [String]? - guard let metadata = try? NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, - at: dbFileURL), - let latestModel = CoreDataDatabase.loadModel(from: bundle, named: "BookmarksModel") else { return nil } - - if latestModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: metadata) == false{ - // Before migrating to latest scheme version, read order of favorites from DB - - let oldBookmarksModel = NSManagedObjectModel.mergedModel(from: [Bookmarks.bundle], forStoreMetadata: metadata)! - let oldDB = CoreDataDatabase(name: dbFileURL.deletingPathExtension().lastPathComponent, - containerLocation: dbContainerLocation, - model: oldBookmarksModel) - oldDB.loadStore { context, error in - guard let context = context else { - errorEvents?.fire(.couldNotLoadDatabase, error: error) - return - } + guard let metadata = try? NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: dbFileURL), + let latestModel = CoreDataDatabase.loadModel(from: bundle, named: "BookmarksModel"), + !latestModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: metadata) + else { + return nil + } - let favs = BookmarkUtils.fetchLegacyFavoritesFolder(context) - let orderedFavorites = favs?.favorites?.array as? [BookmarkEntity] ?? [] - oldFavoritesOrder = orderedFavorites.compactMap { $0.uuid } + // Before migrating to latest scheme version, read order of favorites from DB + + let oldBookmarksModel = NSManagedObjectModel.mergedModel(from: [Bookmarks.bundle], forStoreMetadata: metadata)! + let oldDB = CoreDataDatabase(name: dbFileURL.deletingPathExtension().lastPathComponent, + containerLocation: dbContainerLocation, + model: oldBookmarksModel) + + var oldFavoritesOrder: [String]? + + oldDB.loadStore { context, error in + guard let context = context else { + errorEvents?.fire(.couldNotLoadDatabase, error: error) + return } + + let favs = BookmarkUtils.fetchLegacyFavoritesFolder(context) + let orderedFavorites = favs?.favorites?.array as? [BookmarkEntity] ?? [] + oldFavoritesOrder = orderedFavorites.compactMap { $0.uuid } } return oldFavoritesOrder } From 23c5b7d468c177c27c3bc2aac7f6f97a8ff7f72b Mon Sep 17 00:00:00 2001 From: Bartek Waresiak Date: Mon, 27 Nov 2023 15:37:16 +0100 Subject: [PATCH 4/9] Expand tests to assert whole structure --- .../BookmarksTests/BookmarkMigrationTests.swift | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Tests/BookmarksTests/BookmarkMigrationTests.swift b/Tests/BookmarksTests/BookmarkMigrationTests.swift index 015236f00..928dcd9fb 100644 --- a/Tests/BookmarksTests/BookmarkMigrationTests.swift +++ b/Tests/BookmarksTests/BookmarkMigrationTests.swift @@ -107,11 +107,16 @@ class BookmarkMigrationTests: XCTestCase { Bookmark(id: "2", favoritedOn: [.unified, .mobile]) Folder(id: "3") { Folder(id: "31") {} - Bookmark(id: "32", favoritedOn: [.unified, .desktop]) - Bookmark(id: "33", favoritedOn: [.unified, .desktop, .mobile]) + Bookmark(id: "32", favoritedOn: [.unified, .mobile]) + Bookmark(id: "33", favoritedOn: [.unified, .mobile]) } - Bookmark(id: "4", favoritedOn: [.unified, .desktop, .mobile]) - Bookmark(id: "5", favoritedOn: [.unified, .desktop]) + Bookmark(id: "4", favoritedOn: [.unified, .mobile]) + Bookmark(id: "5", favoritedOn: [.unified, .mobile]) + } + + latestContext.performAndWait { + let rootFolder = BookmarkUtils.fetchRootFolder(latestContext)! + assertEquivalent(withTimestamps: false, rootFolder, bookmarkTree) } try? migratedStack.tearDown(deleteStores: true) @@ -171,7 +176,4 @@ class BookmarkMigrationTests: XCTestCase { try? bookmarksDatabase.tearDown(deleteStores: true) } - - - } From 550e309a17c60f5f0f7981f4b5d2773afeca2033 Mon Sep 17 00:00:00 2001 From: Dominik Kapusta Date: Mon, 27 Nov 2023 15:39:19 +0100 Subject: [PATCH 5/9] Fix Swiftlint violations --- .../BookmarksTestDBBuilder.swift | 15 ++++++++++----- Tests/BookmarksTests/BookmarkMigrationTests.swift | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Sources/BookmarksTestDBBuilder/BookmarksTestDBBuilder.swift b/Sources/BookmarksTestDBBuilder/BookmarksTestDBBuilder.swift index 5c7857a1a..f452fb3e5 100644 --- a/Sources/BookmarksTestDBBuilder/BookmarksTestDBBuilder.swift +++ b/Sources/BookmarksTestDBBuilder/BookmarksTestDBBuilder.swift @@ -22,7 +22,10 @@ import Foundation import CoreData import Persistence import Bookmarks -//import BookmarksTestsUtils + +// swiftlint:disable force_try +// swiftlint:disable line_length +// swiftlint:disable function_body_length @main struct BookmarksTestDBBuilder { @@ -228,7 +231,6 @@ public struct BookmarkTree { return (rootFolder, orphans) } - // swiftlint:disable large_tuple @discardableResult public func createEntitiesForCheckingModifiedAt(in context: NSManagedObjectContext) -> (BookmarkEntity, [BookmarkEntity]) { BookmarkUtils.prepareLegacyFoldersStructure(in: context) @@ -245,7 +247,6 @@ public struct BookmarkTree { } return (rootFolder, orphans) } - // swiftlint:enable large_tuple let modifiedAt: Date? let bookmarkTreeNodes: [BookmarkTreeNode] @@ -257,8 +258,8 @@ public extension BookmarkEntity { makeWithModifiedAtConstraints(with: treeNode, rootFolder: rootFolder, favoritesFolders: favoritesFolders, in: context) } - @discardableResult - static func makeWithModifiedAtConstraints(with treeNode: BookmarkTreeNode, rootFolder: BookmarkEntity, favoritesFolders: [BookmarkEntity], in context: NSManagedObjectContext) -> BookmarkEntity { + // swiftlint:disable:next cyclomatic_complexity + @discardableResult static func makeWithModifiedAtConstraints(with treeNode: BookmarkTreeNode, rootFolder: BookmarkEntity, favoritesFolders: [BookmarkEntity], in context: NSManagedObjectContext) -> BookmarkEntity { var entity: BookmarkEntity! var queues: [[BookmarkTreeNode]] = [[treeNode]] @@ -319,3 +320,7 @@ public extension BookmarkEntity { return entity } } + +// swiftlint:enable force_try +// swiftlint:enable line_length +// swiftlint:enable function_body_length diff --git a/Tests/BookmarksTests/BookmarkMigrationTests.swift b/Tests/BookmarksTests/BookmarkMigrationTests.swift index 928dcd9fb..e110198ff 100644 --- a/Tests/BookmarksTests/BookmarkMigrationTests.swift +++ b/Tests/BookmarksTests/BookmarkMigrationTests.swift @@ -34,7 +34,7 @@ class BookmarkMigrationTests: XCTestCase { location = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) guard let location = Bundle(for: BookmarkMigrationTests.self).resourceURL else { - XCTFail() + XCTFail("Failed to find bundle URL") return } resourceURLDir = location.appending(path: "BrowserServicesKit_BookmarksTests.bundle/Contents/Resources/") From dd7989b9f5601ba08945fa9545d030497f4f4afb Mon Sep 17 00:00:00 2001 From: Bartek Waresiak Date: Mon, 27 Nov 2023 16:16:26 +0100 Subject: [PATCH 6/9] Fix locations when running form command line --- Tests/BookmarksTests/BookmarkMigrationTests.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Tests/BookmarksTests/BookmarkMigrationTests.swift b/Tests/BookmarksTests/BookmarkMigrationTests.swift index e110198ff..dff861d78 100644 --- a/Tests/BookmarksTests/BookmarkMigrationTests.swift +++ b/Tests/BookmarksTests/BookmarkMigrationTests.swift @@ -37,7 +37,14 @@ class BookmarkMigrationTests: XCTestCase { XCTFail("Failed to find bundle URL") return } - resourceURLDir = location.appending(path: "BrowserServicesKit_BookmarksTests.bundle/Contents/Resources/") + + let resourcesLocation = location.appending(path: "BrowserServicesKit_BookmarksTests.bundle/Contents/Resources/") + if FileManager.default.fileExists(atPath: resourcesLocation.path) == false { + resourceURLDir = Bundle.module.resourceURL + } else { + resourceURLDir = resourcesLocation + } + } override func tearDown() { From 6e421d3f6c25718e6c9bf419c04124addcee158b Mon Sep 17 00:00:00 2001 From: Bartek Waresiak Date: Mon, 27 Nov 2023 16:49:09 +0100 Subject: [PATCH 7/9] For now disable these tests on CI --- Tests/BookmarksTests/BookmarkMigrationTests.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Tests/BookmarksTests/BookmarkMigrationTests.swift b/Tests/BookmarksTests/BookmarkMigrationTests.swift index dff861d78..47d2f5ce4 100644 --- a/Tests/BookmarksTests/BookmarkMigrationTests.swift +++ b/Tests/BookmarksTests/BookmarkMigrationTests.swift @@ -75,14 +75,17 @@ class BookmarkMigrationTests: XCTestCase { } func testWhenMigratingFromV1ThenRootFoldersContentsArePreservedInOrder() throws { + XCTSkip("Won't run on CI or from command line as momd is not compiled. Tested through Xcode") try commonMigrationTestForDatabase(name: "Bookmarks_V1") } func testWhenMigratingFromV2ThenRootFoldersContentsArePreservedInOrder() throws { + XCTSkip("Won't run on CI or from command line as momd is not compiled. Tested through Xcode") try commonMigrationTestForDatabase(name: "Bookmarks_V2") } func testWhenMigratingFromV3ThenRootFoldersContentsArePreservedInOrder() throws { + XCTSkip("Won't run on CI or from command line as momd is not compiled. Tested through Xcode") try commonMigrationTestForDatabase(name: "Bookmarks_V3") } From 73e09e494a62dbb02ef79fc7895067c8bc1782bc Mon Sep 17 00:00:00 2001 From: Bartek Waresiak Date: Mon, 27 Nov 2023 16:58:23 +0100 Subject: [PATCH 8/9] Disable these for real now --- Tests/BookmarksTests/BookmarkMigrationTests.swift | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Tests/BookmarksTests/BookmarkMigrationTests.swift b/Tests/BookmarksTests/BookmarkMigrationTests.swift index 47d2f5ce4..fe46226d6 100644 --- a/Tests/BookmarksTests/BookmarkMigrationTests.swift +++ b/Tests/BookmarksTests/BookmarkMigrationTests.swift @@ -76,17 +76,20 @@ class BookmarkMigrationTests: XCTestCase { func testWhenMigratingFromV1ThenRootFoldersContentsArePreservedInOrder() throws { XCTSkip("Won't run on CI or from command line as momd is not compiled. Tested through Xcode") - try commonMigrationTestForDatabase(name: "Bookmarks_V1") + return +// try commonMigrationTestForDatabase(name: "Bookmarks_V1") } func testWhenMigratingFromV2ThenRootFoldersContentsArePreservedInOrder() throws { XCTSkip("Won't run on CI or from command line as momd is not compiled. Tested through Xcode") - try commonMigrationTestForDatabase(name: "Bookmarks_V2") + return +// try commonMigrationTestForDatabase(name: "Bookmarks_V2") } func testWhenMigratingFromV3ThenRootFoldersContentsArePreservedInOrder() throws { XCTSkip("Won't run on CI or from command line as momd is not compiled. Tested through Xcode") - try commonMigrationTestForDatabase(name: "Bookmarks_V3") + return +// try commonMigrationTestForDatabase(name: "Bookmarks_V3") } func commonMigrationTestForDatabase(name: String) throws { From cd59c2dcb79c7148c88d4842bcdf212528c5051d Mon Sep 17 00:00:00 2001 From: Bartek Waresiak Date: Mon, 27 Nov 2023 17:15:24 +0100 Subject: [PATCH 9/9] Update API to not use iOS 16 API --- .../BookmarkMigrationTests.swift | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Tests/BookmarksTests/BookmarkMigrationTests.swift b/Tests/BookmarksTests/BookmarkMigrationTests.swift index fe46226d6..a610105b0 100644 --- a/Tests/BookmarksTests/BookmarkMigrationTests.swift +++ b/Tests/BookmarksTests/BookmarkMigrationTests.swift @@ -38,7 +38,7 @@ class BookmarkMigrationTests: XCTestCase { return } - let resourcesLocation = location.appending(path: "BrowserServicesKit_BookmarksTests.bundle/Contents/Resources/") + let resourcesLocation = location.appendingPathComponent( "BrowserServicesKit_BookmarksTests.bundle/Contents/Resources/") if FileManager.default.fileExists(atPath: resourcesLocation.path) == false { resourceURLDir = Bundle.module.resourceURL } else { @@ -59,7 +59,7 @@ class BookmarkMigrationTests: XCTestCase { try fileManager.createDirectory(at: toDirectory, withIntermediateDirectories: false) for ext in ["sqlite", "sqlite-shm", "sqlite-wal"] { - try fileManager.copyItem(at: formDirectory.appendingPathComponent("\(name).\(ext)", conformingTo: .database), + try fileManager.copyItem(at: formDirectory.appendingPathComponent("\(name).\(ext)"), to: toDirectory.appendingPathComponent("\(name).\(ext)")) } } @@ -75,21 +75,18 @@ class BookmarkMigrationTests: XCTestCase { } func testWhenMigratingFromV1ThenRootFoldersContentsArePreservedInOrder() throws { - XCTSkip("Won't run on CI or from command line as momd is not compiled. Tested through Xcode") - return -// try commonMigrationTestForDatabase(name: "Bookmarks_V1") + throw XCTSkip("Won't run on CI or from command line as momd is not compiled. Tested through Xcode") + try commonMigrationTestForDatabase(name: "Bookmarks_V1") } func testWhenMigratingFromV2ThenRootFoldersContentsArePreservedInOrder() throws { - XCTSkip("Won't run on CI or from command line as momd is not compiled. Tested through Xcode") - return -// try commonMigrationTestForDatabase(name: "Bookmarks_V2") + throw XCTSkip("Won't run on CI or from command line as momd is not compiled. Tested through Xcode") + try commonMigrationTestForDatabase(name: "Bookmarks_V2") } func testWhenMigratingFromV3ThenRootFoldersContentsArePreservedInOrder() throws { - XCTSkip("Won't run on CI or from command line as momd is not compiled. Tested through Xcode") - return -// try commonMigrationTestForDatabase(name: "Bookmarks_V3") + throw XCTSkip("Won't run on CI or from command line as momd is not compiled. Tested through Xcode") + try commonMigrationTestForDatabase(name: "Bookmarks_V3") } func commonMigrationTestForDatabase(name: String) throws {