// Copyright (c) 2020 650 Industries, Inc. All rights reserved. import ExpoModulesTestCore @testable import EXUpdates import EXManifests class UpdatesDatabaseIntegrityCheckMockingAssetExists : UpdatesDatabaseIntegrityCheck { public override func assetExists(_ asset: UpdateAsset, inDirectory directory: URL) -> Bool { return asset.key == "asset1" } } class UpdatesDatabaseIntegrityCheckSpec : ExpoSpec { override func spec() { var testDatabaseDir: URL! var db: UpdatesDatabase! beforeEach { let applicationSupportDir = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).last testDatabaseDir = applicationSupportDir!.appendingPathComponent("UpdatesDatabaseTests") try? FileManager.default.removeItem(atPath: testDatabaseDir.path) if !FileManager.default.fileExists(atPath: testDatabaseDir.path) { try! FileManager.default.createDirectory(atPath: testDatabaseDir.path, withIntermediateDirectories: true) } db = UpdatesDatabase() db.databaseQueue.sync { try! db.openDatabase(inDirectory: testDatabaseDir) } } afterEach { db.databaseQueue.sync { db.closeDatabase() } try! FileManager.default.removeItem(atPath: testDatabaseDir.path) } describe("filter embedded updates") { it("works") { // We can't run any updates with the status EMBEDDED if they aren't the update that's // currently embedded in the installed app; the integrity check should remove any such updates // from the database entirely. let scopeKey = "testScopeKey" let runtimeVersion = "1.0" let config = UpdatesConfig.config(fromDictionary: [ UpdatesConfig.EXUpdatesConfigScopeKeyKey: scopeKey, UpdatesConfig.EXUpdatesConfigRuntimeVersionKey: runtimeVersion ]) let update1 = Update( manifest: ManifestFactory.manifest(forManifestJSON: [:]), config: config, database: db, updateId: UUID(), scopeKey: scopeKey, commitTime: Date(timeIntervalSince1970: 1608667851), runtimeVersion: runtimeVersion, keep: true, status: .StatusEmbedded, isDevelopmentMode: false, assetsFromManifest: [] ) let update2 = Update( manifest: ManifestFactory.manifest(forManifestJSON: [:]), config: config, database: db, updateId: UUID(), scopeKey: scopeKey, commitTime: Date(timeIntervalSince1970: 1608667852), runtimeVersion: runtimeVersion, keep: true, status: .StatusEmbedded, isDevelopmentMode: false, assetsFromManifest: [] ) db.databaseQueue.sync { try! db.addUpdate(update1) try! db.addUpdate(update2) expect(try! db.allUpdates(withConfig: config).count) == 2 try! UpdatesDatabaseIntegrityCheck().run(withDatabase: db, directory: testDatabaseDir, config: config, embeddedUpdate: update2) let allUpdates = try! db.allUpdates(withConfig: config) expect(allUpdates.count) == 1 expect(update2.updateId) == allUpdates.first?.updateId } } } describe("missing assets") { it("works") { let asset1 = UpdateAsset(key: "asset1", type: "png") asset1.downloadTime = Date() asset1.contentHash = "hash1" let asset2 = UpdateAsset(key: "asset2", type: "png") asset2.downloadTime = Date() asset2.contentHash = "hash2" let scopeKey = "testScopeKey" let runtimeVersion = "1.0" let config = UpdatesConfig.config(fromDictionary: [ UpdatesConfig.EXUpdatesConfigScopeKeyKey: scopeKey, UpdatesConfig.EXUpdatesConfigRuntimeVersionKey: runtimeVersion ]) let update1 = Update( manifest: ManifestFactory.manifest(forManifestJSON: [:]), config: config, database: db, updateId: UUID(), scopeKey: scopeKey, commitTime: Date(timeIntervalSince1970: 1608667851), runtimeVersion: runtimeVersion, keep: true, status: .StatusEmbedded, isDevelopmentMode: false, assetsFromManifest: [] ) let update2 = Update( manifest: ManifestFactory.manifest(forManifestJSON: [:]), config: config, database: db, updateId: UUID(), scopeKey: scopeKey, commitTime: Date(timeIntervalSince1970: 1608667852), runtimeVersion: runtimeVersion, keep: true, status: .StatusEmbedded, isDevelopmentMode: false, assetsFromManifest: [] ) db.databaseQueue.sync { try! db.addUpdate(update1) try! db.addUpdate(update2) try! db.addNewAssets([asset1], toUpdateWithId: update1.updateId) try! db.addNewAssets([asset2], toUpdateWithId: update2.updateId) expect(try! db.allUpdates(withConfig: config).count) == 2 expect(try! db.allAssets().count) == 2 try! UpdatesDatabaseIntegrityCheckMockingAssetExists().run( withDatabase: db, directory: testDatabaseDir, config: config, embeddedUpdate: nil ) let allUpdates = try! db.allUpdates(withConfig: config) let allAssets = try! db.allAssets() // this is broken? // expect(allUpdates.count) == 1 // expect(allAssets.count) == 2 // // let sortedUpdates = allUpdates.sorted { l, r in // return l.commitTime < r.commitTime // } // expect(sortedUpdates[0].status) == UpdateStatus.StatusReady // expect(sortedUpdates[1].status) == UpdateStatus.StatusPending } } } } }