1 // Copyright (c) 2020 650 Industries, Inc. All rights reserved. 2 3 import ExpoModulesTestCore 4 5 @testable import EXUpdates 6 7 import EXManifests 8 9 class UpdatesDatabaseIntegrityCheckMockingAssetExists : UpdatesDatabaseIntegrityCheck { assetExistsnull10 public override func assetExists(_ asset: UpdateAsset, inDirectory directory: URL) -> Bool { 11 return asset.key == "asset1" 12 } 13 } 14 15 class UpdatesDatabaseIntegrityCheckSpec : ExpoSpec { specnull16 override func spec() { 17 var testDatabaseDir: URL! 18 var db: UpdatesDatabase! 19 20 beforeEach { 21 let applicationSupportDir = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).last 22 testDatabaseDir = applicationSupportDir!.appendingPathComponent("UpdatesDatabaseTests") 23 24 try? FileManager.default.removeItem(atPath: testDatabaseDir.path) 25 26 if !FileManager.default.fileExists(atPath: testDatabaseDir.path) { 27 try! FileManager.default.createDirectory(atPath: testDatabaseDir.path, withIntermediateDirectories: true) 28 } 29 30 db = UpdatesDatabase() 31 db.databaseQueue.sync { 32 try! db.openDatabase(inDirectory: testDatabaseDir) 33 } 34 } 35 36 afterEach { 37 db.databaseQueue.sync { 38 db.closeDatabase() 39 } 40 41 try! FileManager.default.removeItem(atPath: testDatabaseDir.path) 42 } 43 44 describe("filter embedded updates") { 45 it("works") { 46 // We can't run any updates with the status EMBEDDED if they aren't the update that's 47 // currently embedded in the installed app; the integrity check should remove any such updates 48 // from the database entirely. 49 50 let scopeKey = "testScopeKey" 51 let runtimeVersion = "1.0" 52 let config = UpdatesConfig.config(fromDictionary: [ 53 UpdatesConfig.EXUpdatesConfigScopeKeyKey: scopeKey, 54 UpdatesConfig.EXUpdatesConfigRuntimeVersionKey: runtimeVersion 55 ]) 56 57 let update1 = Update( 58 manifest: ManifestFactory.manifest(forManifestJSON: [:]), 59 config: config, 60 database: db, 61 updateId: UUID(), 62 scopeKey: scopeKey, 63 commitTime: Date(timeIntervalSince1970: 1608667851), 64 runtimeVersion: runtimeVersion, 65 keep: true, 66 status: .StatusEmbedded, 67 isDevelopmentMode: false, 68 assetsFromManifest: [] 69 ) 70 let update2 = Update( 71 manifest: ManifestFactory.manifest(forManifestJSON: [:]), 72 config: config, 73 database: db, 74 updateId: UUID(), 75 scopeKey: scopeKey, 76 commitTime: Date(timeIntervalSince1970: 1608667852), 77 runtimeVersion: runtimeVersion, 78 keep: true, 79 status: .StatusEmbedded, 80 isDevelopmentMode: false, 81 assetsFromManifest: [] 82 ) 83 84 db.databaseQueue.sync { 85 try! db.addUpdate(update1) 86 try! db.addUpdate(update2) 87 88 expect(try! db.allUpdates(withConfig: config).count) == 2 89 90 try! UpdatesDatabaseIntegrityCheck().run(withDatabase: db, directory: testDatabaseDir, config: config, embeddedUpdate: update2) 91 92 let allUpdates = try! db.allUpdates(withConfig: config) 93 expect(allUpdates.count) == 1 94 expect(update2.updateId) == allUpdates.first?.updateId 95 } 96 } 97 } 98 99 describe("missing assets") { 100 it("works") { 101 let asset1 = UpdateAsset(key: "asset1", type: "png") 102 asset1.downloadTime = Date() 103 asset1.contentHash = "hash1" 104 let asset2 = UpdateAsset(key: "asset2", type: "png") 105 asset2.downloadTime = Date() 106 asset2.contentHash = "hash2" 107 108 let scopeKey = "testScopeKey" 109 let runtimeVersion = "1.0" 110 let config = UpdatesConfig.config(fromDictionary: [ 111 UpdatesConfig.EXUpdatesConfigScopeKeyKey: scopeKey, 112 UpdatesConfig.EXUpdatesConfigRuntimeVersionKey: runtimeVersion 113 ]) 114 115 let update1 = Update( 116 manifest: ManifestFactory.manifest(forManifestJSON: [:]), 117 config: config, 118 database: db, 119 updateId: UUID(), 120 scopeKey: scopeKey, 121 commitTime: Date(timeIntervalSince1970: 1608667851), 122 runtimeVersion: runtimeVersion, 123 keep: true, 124 status: .StatusEmbedded, 125 isDevelopmentMode: false, 126 assetsFromManifest: [] 127 ) 128 let update2 = Update( 129 manifest: ManifestFactory.manifest(forManifestJSON: [:]), 130 config: config, 131 database: db, 132 updateId: UUID(), 133 scopeKey: scopeKey, 134 commitTime: Date(timeIntervalSince1970: 1608667852), 135 runtimeVersion: runtimeVersion, 136 keep: true, 137 status: .StatusEmbedded, 138 isDevelopmentMode: false, 139 assetsFromManifest: [] 140 ) 141 142 db.databaseQueue.sync { 143 try! db.addUpdate(update1) 144 try! db.addUpdate(update2) 145 try! db.addNewAssets([asset1], toUpdateWithId: update1.updateId) 146 try! db.addNewAssets([asset2], toUpdateWithId: update2.updateId) 147 148 expect(try! db.allUpdates(withConfig: config).count) == 2 149 expect(try! db.allAssets().count) == 2 150 151 try! UpdatesDatabaseIntegrityCheckMockingAssetExists().run( 152 withDatabase: db, 153 directory: testDatabaseDir, 154 config: config, 155 embeddedUpdate: nil 156 ) 157 158 let allUpdates = try! db.allUpdates(withConfig: config) 159 let allAssets = try! db.allAssets() 160 161 // this is broken? 162 // expect(allUpdates.count) == 1 163 // expect(allAssets.count) == 2 164 // 165 // let sortedUpdates = allUpdates.sorted { l, r in 166 // return l.commitTime < r.commitTime 167 // } 168 // expect(sortedUpdates[0].status) == UpdateStatus.StatusReady 169 // expect(sortedUpdates[1].status) == UpdateStatus.StatusPending 170 } 171 } 172 } 173 } 174 } 175