From 0a821ab37602612fc030aa84d44d3d969e7f5fd9 Mon Sep 17 00:00:00 2001 From: pubkey <8926560+pubkey@users.noreply.github.com> Date: Tue, 28 Jan 2025 13:33:09 +0100 Subject: [PATCH] ADD test for #6786 --- test/unit/replication-graphql.test.ts | 134 +++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git a/test/unit/replication-graphql.test.ts b/test/unit/replication-graphql.test.ts index fe162b117ad..00692dbb30f 100644 --- a/test/unit/replication-graphql.test.ts +++ b/test/unit/replication-graphql.test.ts @@ -24,7 +24,8 @@ import { ensureNotFalsy, RxReplicationWriteToMasterRow, ReplicationPullHandlerResult, - RxCollection + RxCollection, + addRxPlugin } from '../../plugins/core/index.mjs'; import { @@ -67,10 +68,15 @@ import { import { ReplicationPushHandlerResult, RxDocumentData } from '../../plugins/core/index.mjs'; import { HumanWithTimestampDocumentType } from '../../src/plugins/test-utils/schema-objects.ts'; import { normalizeString } from '../../plugins/utils/index.mjs'; +import { RxDBMigrationSchemaPlugin } from '../../plugins/migration-schema/index.mjs'; +import { RxDBUpdatePlugin } from '../../plugins/update/index.mjs'; declare type WithDeleted = T & { deleted: boolean; }; describe('replication-graphql.test.ts', () => { + addRxPlugin(RxDBMigrationSchemaPlugin); + addRxPlugin(RxDBUpdatePlugin); + if (!config.storage.hasReplication) { return; } @@ -2544,6 +2550,132 @@ describe('replication-graphql.test.ts', () => { }); }); describeParallel('issues', () => { + it('#6786 should not leak _attachments when using a sqlite storage', async () => { + const server = await SpawnServer.spawn(); + + const pushQueryBuilderWithAssert = (rows: RxReplicationWriteToMasterRow[]) => { + if (!rows || rows.length === 0) { + throw new Error('test pushQueryBuilder(): called with no docs'); + } + const query = ` + mutation CreateHumans($writeRows: [HumanWriteRow!]) { + writeHumans(writeRows: $writeRows) { + id + name + age + updatedAt + deleted + } + } + `; + + // It should fail when using a sqlite storage + const firstRow = rows[0]; + if (firstRow.assumedMasterState) { + console.log('in the _attachments assert:'); + console.dir(firstRow); + assert.strictEqual(firstRow.assumedMasterState._attachments, undefined); + } + + const variables = { + writeRows: rows + }; + return Promise.resolve({ + query, + operationName: 'CreateHumans', + variables + }); + }; + + const dbName = randomToken(10); + + // TODO : change the storage type for a sqlite. It should leak _attachments when applying the new migration + // I can't get a sqlite storage because I don't have access to the premium package + const storage = config.storage.getStorage(); + + const db = await createRxDatabase({ + name: dbName, + storage, + multiInstance: false, + eventReduce: true, + }); + const schema: RxJsonSchema = clone(schemas.humanWithTimestampAllIndex); + const collections = await db.addCollections({ + humans: { + schema, + }, + }); + + const collection = collections.humans; + + // add one doc to the client database + const testData = getTestData(1).pop(); + delete (testData as any).deleted; + await collection.insert(testData); + + await db.close(); + const db2 = await createRxDatabase({ + name: dbName, + storage, + multiInstance: false, + eventReduce: true, + }); + + const schemaV2 = clone(schema); + schemaV2.version = 1; + const newCollection = await db2.addCollections({ + humans: { + schema: schemaV2, + autoMigrate: false, + migrationStrategies: { + 1: (doc) => doc + } + }, + }); + + // const server = await SpawnServer.spawn(); + assert.strictEqual(server.getDocuments().length, 0); + + // start live replication + const replicationState = replicateGraphQL({ + replicationIdentifier: randomToken(10), + collection: newCollection.humans, + url: server.url, + push: { + batchSize, + queryBuilder: pushQueryBuilderWithAssert, + }, + pull: { + batchSize, + queryBuilder: pullQueryBuilder, + }, + live: true, + deletedField: 'deleted' + }); + + ensureReplicationHasNoErrors(replicationState); + await replicationState.awaitInitialReplication(); + + // make sure the migration should be executed + assert.strictEqual(await newCollection.humans.migrationNeeded(), true); + await newCollection.humans.startMigration(); + + // Should sync in the replication ({assumedMasterState, newDocumentState}) + await newCollection.humans.findOne({ selector: { id: testData?.id } }).update({ + $set: { + age: 12 + } + }); + await replicationState.awaitInSync(); + + const graphQlData = server.getDocuments(); + console.dir(graphQlData); + assert.strictEqual(graphQlData.length, 1, 'graphQlData.length must be 1'); + assert.strictEqual(graphQlData._attachments, undefined); + + await db2.close(); + await server.close(); + }); it('push not working on slow db', async () => { if (isBun) { // TODO for somehow bun times out here