Паритет вложений и поиска на iOS (desktop/server/android), новые autotests и аудит
This commit is contained in:
85
RosettaTests/MigrationHarnessTests.swift
Normal file
85
RosettaTests/MigrationHarnessTests.swift
Normal file
@@ -0,0 +1,85 @@
|
||||
import XCTest
|
||||
@testable import Rosetta
|
||||
|
||||
@MainActor
|
||||
final class MigrationHarnessTests: XCTestCase {
|
||||
private var ctx: DBTestContext!
|
||||
|
||||
override func setUpWithError() throws {
|
||||
ctx = DBTestContext()
|
||||
}
|
||||
|
||||
override func tearDownWithError() throws {
|
||||
ctx.teardown()
|
||||
ctx = nil
|
||||
}
|
||||
|
||||
func testLegacySyncOnlyMigrationReconcilesWithoutSQLiteUpsertSyntaxFailure() async throws {
|
||||
try await ctx.bootstrap()
|
||||
|
||||
DatabaseManager.shared.close()
|
||||
let sqlite = try ctx.openSQLite()
|
||||
let rerunMigrations = DatabaseManager.migrationIdentifiers.dropFirst(3)
|
||||
let deleteList = rerunMigrations.map { "'\($0)'" }.joined(separator: ",")
|
||||
try sqlite.execute("DELETE FROM grdb_migrations WHERE identifier IN (\(deleteList))")
|
||||
try sqlite.execute("DROP TABLE IF EXISTS accounts_sync_times")
|
||||
try sqlite.execute("DELETE FROM sync_cursors")
|
||||
try sqlite.execute("INSERT INTO sync_cursors(account, timestamp) VALUES ('\(ctx.account)', 1234567890123)")
|
||||
|
||||
try DatabaseManager.shared.bootstrap(accountPublicKey: ctx.account)
|
||||
let cursor = DatabaseManager.shared.loadSyncCursor(account: ctx.account)
|
||||
XCTAssertEqual(cursor, 1_234_567_890_123)
|
||||
}
|
||||
|
||||
func testPartialReconcileBackfillsNullIds() async throws {
|
||||
try await ctx.bootstrap()
|
||||
DatabaseManager.shared.saveSyncCursor(account: ctx.account, timestamp: 9_001)
|
||||
|
||||
DatabaseManager.shared.close()
|
||||
let sqlite = try ctx.openSQLite()
|
||||
try sqlite.execute("UPDATE accounts_sync_times SET id = NULL WHERE account = '\(ctx.account)'")
|
||||
try sqlite.execute("DELETE FROM grdb_migrations WHERE identifier = '\(DatabaseManager.migrationV7SyncCursorReconcile)'")
|
||||
|
||||
try DatabaseManager.shared.bootstrap(accountPublicKey: ctx.account)
|
||||
|
||||
let check = try ctx.openSQLite()
|
||||
let rows = try check.query(
|
||||
"SELECT id, last_sync FROM accounts_sync_times WHERE account = ? LIMIT 1",
|
||||
[.text(ctx.account)]
|
||||
)
|
||||
XCTAssertEqual(rows.count, 1)
|
||||
XCTAssertNotEqual(rows.first?["id"], "")
|
||||
XCTAssertNotEqual(rows.first?["id"], "0")
|
||||
XCTAssertEqual(rows.first?["last_sync"], "9001")
|
||||
}
|
||||
|
||||
func testMonotonicSyncCursorNeverDecreases() async throws {
|
||||
try await ctx.bootstrap()
|
||||
|
||||
DatabaseManager.shared.saveSyncCursor(account: ctx.account, timestamp: 1_700_000_005_000)
|
||||
DatabaseManager.shared.saveSyncCursor(account: ctx.account, timestamp: 1_700_000_004_999)
|
||||
DatabaseManager.shared.saveSyncCursor(account: ctx.account, timestamp: 1_700_000_006_500)
|
||||
|
||||
XCTAssertEqual(DatabaseManager.shared.loadSyncCursor(account: ctx.account), 1_700_000_006_500)
|
||||
}
|
||||
|
||||
func testCompatibilityMirrorWritesAccountsSyncTimesAndSyncCursors() async throws {
|
||||
try await ctx.bootstrap()
|
||||
DatabaseManager.shared.saveSyncCursor(account: ctx.account, timestamp: 77_777)
|
||||
|
||||
let sqlite = try ctx.openSQLite()
|
||||
let accountsRows = try sqlite.query(
|
||||
"SELECT last_sync, id FROM accounts_sync_times WHERE account = ? LIMIT 1",
|
||||
[.text(ctx.account)]
|
||||
)
|
||||
let legacyRows = try sqlite.query(
|
||||
"SELECT timestamp FROM sync_cursors WHERE account = ? LIMIT 1",
|
||||
[.text(ctx.account)]
|
||||
)
|
||||
|
||||
XCTAssertEqual(accountsRows.first?["last_sync"], "77777")
|
||||
XCTAssertNotEqual(accountsRows.first?["id"], "")
|
||||
XCTAssertNotEqual(accountsRows.first?["id"], "0")
|
||||
XCTAssertEqual(legacyRows.first?["timestamp"], "77777")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user