|
441 | 441 | )
|
442 | 442 | #expect(
|
443 | 443 | recordTypes[(remindersTableIndex + 1)...]
|
444 |
| - == recordTypesAfterMigration[(remindersTableIndex + 1)...]) |
| 444 | + == recordTypesAfterMigration[(remindersTableIndex + 1)...] |
| 445 | + ) |
445 | 446 |
|
446 | 447 | assertInlineSnapshot(of: recordTypesAfterMigration[remindersTableIndex], as: .customDump) {
|
447 | 448 | #"""
|
|
514 | 515 | """#
|
515 | 516 | }
|
516 | 517 | }
|
| 518 | + |
| 519 | + // * Stop sync engine |
| 520 | + // * Migrate to add new table |
| 521 | + // * Create new sync engine but forget to add table |
| 522 | + // * Create new sync engine but this time add the table |
| 523 | + // * Confirm that new table records are uploaded to CloudKit |
| 524 | + @available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
| 525 | + @Test func migrationAddTableForgetToAddToSyncEngine() async throws { |
| 526 | + let recordTypes = try await syncEngine.metadatabase.read { db in |
| 527 | + try RecordType.order(by: \.tableName).fetchAll(db) |
| 528 | + } |
| 529 | + syncEngine.stop() |
| 530 | + try syncEngine.tearDownSyncEngine() |
| 531 | + |
| 532 | + try await userDatabase.userWrite { db in |
| 533 | + try #sql( |
| 534 | + """ |
| 535 | + CREATE TABLE "foos" ( |
| 536 | + "id" INTEGER PRIMARY KEY NOT NULL ON CONFLICT REPLACE DEFAULT (uuid()) |
| 537 | + ) |
| 538 | + """ |
| 539 | + ) |
| 540 | + .execute(db) |
| 541 | + try Foo |
| 542 | + .insert { Foo(id: 1) } |
| 543 | + .execute(db) |
| 544 | + } |
| 545 | + |
| 546 | + // Relaunch sync engine but forget to add new table to sync engine. |
| 547 | + do { |
| 548 | + let relaunchedSyncEngine = try await SyncEngine( |
| 549 | + container: syncEngine.container, |
| 550 | + userDatabase: syncEngine.userDatabase, |
| 551 | + tables: syncEngine.tables, |
| 552 | + privateTables: syncEngine.privateTables |
| 553 | + ) |
| 554 | + let recordTypesAfterMigration = try await syncEngine.metadatabase.read { db in |
| 555 | + try RecordType.order(by: \.tableName).fetchAll(db) |
| 556 | + } |
| 557 | + expectNoDifference(recordTypesAfterMigration, recordTypes) |
| 558 | + relaunchedSyncEngine.stop() |
| 559 | + try relaunchedSyncEngine.tearDownSyncEngine() |
| 560 | + assertInlineSnapshot(of: container, as: .customDump) { |
| 561 | + """ |
| 562 | + MockCloudContainer( |
| 563 | + privateCloudDatabase: MockCloudDatabase( |
| 564 | + databaseScope: .private, |
| 565 | + storage: [] |
| 566 | + ), |
| 567 | + sharedCloudDatabase: MockCloudDatabase( |
| 568 | + databaseScope: .shared, |
| 569 | + storage: [] |
| 570 | + ) |
| 571 | + ) |
| 572 | + """ |
| 573 | + } |
| 574 | + } |
| 575 | + |
| 576 | + // Relaunch sync engine and remember this time to add new table to sync engine. |
| 577 | + do { |
| 578 | + let relaunchedSyncEngine = try await SyncEngine( |
| 579 | + container: syncEngine.container, |
| 580 | + userDatabase: syncEngine.userDatabase, |
| 581 | + tables: syncEngine.tables + [SynchronizedTable(for: Foo.self)], |
| 582 | + privateTables: syncEngine.privateTables |
| 583 | + ) |
| 584 | + try await relaunchedSyncEngine.processPendingRecordZoneChanges(scope: .private) |
| 585 | + assertInlineSnapshot(of: container, as: .customDump) { |
| 586 | + """ |
| 587 | + MockCloudContainer( |
| 588 | + privateCloudDatabase: MockCloudDatabase( |
| 589 | + databaseScope: .private, |
| 590 | + storage: [ |
| 591 | + [0]: CKRecord( |
| 592 | + recordID: CKRecord.ID(1:foos/zone/__defaultOwner__), |
| 593 | + recordType: "foos", |
| 594 | + parent: nil, |
| 595 | + share: nil, |
| 596 | + id: 1 |
| 597 | + ) |
| 598 | + ] |
| 599 | + ), |
| 600 | + sharedCloudDatabase: MockCloudDatabase( |
| 601 | + databaseScope: .shared, |
| 602 | + storage: [] |
| 603 | + ) |
| 604 | + ) |
| 605 | + """ |
| 606 | + } |
| 607 | + } |
| 608 | + } |
517 | 609 | }
|
518 | 610 | }
|
| 611 | + |
| 612 | + @Table |
| 613 | + private struct Foo { |
| 614 | + let id: Int |
| 615 | + } |
519 | 616 | #endif
|
0 commit comments