From 47ed012b0fdf5fedb198ff345e4768bda574d6cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 5 Mar 2024 11:51:33 +0100 Subject: [PATCH 1/7] ensure the operation method msg is run after the client result to match 2.x behavior --- packages/ddp-client/common/livedata_connection.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/ddp-client/common/livedata_connection.js b/packages/ddp-client/common/livedata_connection.js index 395da44ac9..3a36227272 100644 --- a/packages/ddp-client/common/livedata_connection.js +++ b/packages/ddp-client/common/livedata_connection.js @@ -850,7 +850,17 @@ export class Connection { } // If we added it to the first block, send it out now. - if (self._outstandingMethodBlocks.length === 1) methodInvoker.sendMessage(); + if (self._outstandingMethodBlocks.length === 1) { + if (callback && future) { + // Ensure the method message after the result of the method ran in the client. + future = new Promise((resolve) => { + methodInvoker.sendMessage(); + resolve(); + }); + } else { + methodInvoker.sendMessage(); + } + } // If we're using the default callback on the server, // block waiting for the result. From b915012d9d96156044419fafbbfc8d367ec90528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 5 Mar 2024 12:18:56 +0100 Subject: [PATCH 2/7] adapt test previously created for resolveType --- packages/mongo/mongo_livedata_tests.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mongo/mongo_livedata_tests.js b/packages/mongo/mongo_livedata_tests.js index 4e50d5d507..c566a7b6e8 100644 --- a/packages/mongo/mongo_livedata_tests.js +++ b/packages/mongo/mongo_livedata_tests.js @@ -4276,8 +4276,8 @@ if (Meteor.isServer) { }); } -Tinytest.addAsync('mongo-livedata - maintained isomorphism using resolverType config for both client and server', async function(test, expect) { - const Collection = new Mongo.Collection(`resolver_type${test.runId()}`, { resolverType: 'stub' }); +Tinytest.addAsync('mongo-livedata - maintained isomorphism on collection operations for both client and server', async function(test, expect) { + const Collection = new Mongo.Collection(`maintained_col_op_iso${test.runId()}`); await Collection.insertAsync({ _id: 'a' }); await Collection.insertAsync({ _id: 'b' }); From f67d5045135c71c8246994fb7b0fa456dd032ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 5 Mar 2024 12:59:17 +0100 Subject: [PATCH 3/7] add tests of behaviors to perserve from 2.x about collection operations and persistence --- packages/mongo/mongo_livedata_tests.js | 89 ++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/packages/mongo/mongo_livedata_tests.js b/packages/mongo/mongo_livedata_tests.js index c566a7b6e8..1aa31832ee 100644 --- a/packages/mongo/mongo_livedata_tests.js +++ b/packages/mongo/mongo_livedata_tests.js @@ -4302,3 +4302,92 @@ Tinytest.addAsync('mongo-livedata - maintained isomorphism on collection operati test.equal(items, []); }); + +testAsyncMulti('mongo-livedata - collection operations data persistence', [ + async function (test) { + const Collection = new Mongo.Collection( + `remoteop_persistence${test.runId()}`, + ); + + // Using remote collection + await Collection.insertAsync({ _id: 'a' }); + await Collection.insertAsync({ _id: 'b' }); + + let items = await Collection.find().fetchAsync(); + let itemIds = items.map(_item => _item._id); + + test.equal(itemIds, ['a', 'b']); + + if (Meteor.isClient) { + return new Promise(resolve => { + setTimeout(async () => { + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + test.equal(itemIds, []); // data IS NOT persisted + resolve(); + }, 100); + }); + } + + return Promise.resolve(); + }, + async function (test) { + const Collection = new Mongo.Collection( + `methodop_persistence${test.runId()}`, + ); + // Using methods + Meteor.methods({ + [`insertMethodPersistence${test.runId()}`]: async () => { + await Collection.insertAsync({ _id: 'a' }); + await Collection.insertAsync({ _id: 'b' }); + }, + }); + + await Meteor.callAsync(`insertMethodPersistence${test.runId()}`); + + let items = await Collection.find().fetchAsync(); + let itemIds = items.map(_item => _item._id); + + test.equal(itemIds, ['a', 'b']); + + if (Meteor.isClient) { + return new Promise(resolve => { + setTimeout(async () => { + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + test.equal(itemIds, []); // data IS NOT persisted + resolve(); + }, 100); + }); + } + + return Promise.resolve(); + }, + async function (test) { + const Collection = new Mongo.Collection( + `localop_persistence${test.runId()}`, + ); + + // Using local collection + await Collection._collection.insertAsync({ _id: 'a' }); + await Collection._collection.insertAsync({ _id: 'b' }); + + let items = await Collection.find().fetchAsync(); + let itemIds = items.map(_item => _item._id); + + test.equal(itemIds, ['a', 'b']); + + if (Meteor.isClient) { + return new Promise(resolve => { + setTimeout(async () => { + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + test.equal(itemIds, ['a', 'b']); // data is persisted + resolve(); + }, 100); + }); + } + + return Promise.resolve(); + }, +]); From a0a05b44c2af0b3c37a362aa93d5021b419eb17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 5 Mar 2024 15:03:52 +0100 Subject: [PATCH 4/7] add tests to enforce the same behaviors like 2.x --- packages/mongo/mongo_livedata_tests.js | 109 +++++++++++++++---------- 1 file changed, 65 insertions(+), 44 deletions(-) diff --git a/packages/mongo/mongo_livedata_tests.js b/packages/mongo/mongo_livedata_tests.js index 1aa31832ee..045454dfec 100644 --- a/packages/mongo/mongo_livedata_tests.js +++ b/packages/mongo/mongo_livedata_tests.js @@ -4303,24 +4303,35 @@ Tinytest.addAsync('mongo-livedata - maintained isomorphism on collection operati test.equal(items, []); }); -testAsyncMulti('mongo-livedata - collection operations data persistence', [ - async function (test) { +testAsyncMulti('mongo-livedata - collection async operations data persistence', [ + async function (test) { // Using remote collection const Collection = new Mongo.Collection( `remoteop_persistence${test.runId()}`, ); - // Using remote collection await Collection.insertAsync({ _id: 'a' }); - await Collection.insertAsync({ _id: 'b' }); + await Collection.updateAsync({ _id: 'a' }, { $set: { num: 1 } }); + const insertedId = await Collection.insertAsync({ num: 2 }); let items = await Collection.find().fetchAsync(); let itemIds = items.map(_item => _item._id); + test.equal(itemIds, ['a', insertedId]); // temporary data accessible - test.equal(itemIds, ['a', 'b']); + const aItem = items[0]; + const insertedItem = items[1]; + test.equal(aItem?.num, 1); + test.equal(insertedItem?.num, 2); + + await Collection.removeAsync({ _id: insertedId }); + + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + + test.equal(itemIds, ['a']); // temporary data accessible if (Meteor.isClient) { return new Promise(resolve => { - setTimeout(async () => { + Meteor.setTimeout(async () => { items = await Collection.find().fetchAsync(); itemIds = items.map(_item => _item._id); test.equal(itemIds, []); // data IS NOT persisted @@ -4331,58 +4342,68 @@ testAsyncMulti('mongo-livedata - collection operations data persistence', [ return Promise.resolve(); }, - async function (test) { - const Collection = new Mongo.Collection( - `methodop_persistence${test.runId()}`, - ); - // Using methods - Meteor.methods({ - [`insertMethodPersistence${test.runId()}`]: async () => { - await Collection.insertAsync({ _id: 'a' }); - await Collection.insertAsync({ _id: 'b' }); - }, - }); - - await Meteor.callAsync(`insertMethodPersistence${test.runId()}`); - - let items = await Collection.find().fetchAsync(); - let itemIds = items.map(_item => _item._id); - - test.equal(itemIds, ['a', 'b']); - - if (Meteor.isClient) { - return new Promise(resolve => { - setTimeout(async () => { - items = await Collection.find().fetchAsync(); - itemIds = items.map(_item => _item._id); - test.equal(itemIds, []); // data IS NOT persisted - resolve(); - }, 100); - }); - } - - return Promise.resolve(); - }, - async function (test) { + async function (test) { // Using local collection const Collection = new Mongo.Collection( `localop_persistence${test.runId()}`, ); - // Using local collection await Collection._collection.insertAsync({ _id: 'a' }); - await Collection._collection.insertAsync({ _id: 'b' }); + await Collection._collection.updateAsync({ _id: 'a' }, { $set: { num: 1 } }); + const insertedId = await Collection._collection.insertAsync({ num: 2 }); + + let items = await Collection.find().fetchAsync(); + let itemIds = items.map(_item => _item._id); + test.equal(itemIds, ['a', insertedId]); // temporary data accessible + + const aItem = items[0]; + const insertedItem = items[1]; + test.equal(aItem?.num, 1); + test.equal(insertedItem?.num, 2); + + await Collection._collection.removeAsync({ _id: insertedId }); + + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + + test.equal(itemIds, ['a']); // temporary data accessible + + if (Meteor.isClient) { + return new Promise(resolve => { + Meteor.setTimeout(async () => { + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + test.equal(itemIds, ['a']); // data is persisted + resolve(); + }, 100); + }); + } + + return Promise.resolve(); + }, + async function (test) { // Using methods + const Collection = new Mongo.Collection( + `methodop_persistence${test.runId()}`, + ); + + Meteor.methods({ + [`insertMethodPersistence${test.runId()}`]: async () => { + await Collection.insertAsync({ _id: 'a' }); + }, + }); + + Meteor.callAsync(`insertMethodPersistence${test.runId()}`); let items = await Collection.find().fetchAsync(); let itemIds = items.map(_item => _item._id); - test.equal(itemIds, ['a', 'b']); + test.equal(itemIds, ['a']); // temporary data accessible if (Meteor.isClient) { return new Promise(resolve => { - setTimeout(async () => { + Meteor.setTimeout(async () => { items = await Collection.find().fetchAsync(); itemIds = items.map(_item => _item._id); - test.equal(itemIds, ['a', 'b']); // data is persisted + test.equal(itemIds, []); // data IS NOT persisted resolve(); }, 100); }); From ed1c5105eaf3a653813139d7762d7aa20ea8a01d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 5 Mar 2024 15:08:28 +0100 Subject: [PATCH 5/7] ensure the operation method msg is run after the client result to match 2.x behavior --- packages/mongo/mongo_livedata_tests.js | 246 +++++++++++++------------ 1 file changed, 130 insertions(+), 116 deletions(-) diff --git a/packages/mongo/mongo_livedata_tests.js b/packages/mongo/mongo_livedata_tests.js index 045454dfec..86c13fa0ec 100644 --- a/packages/mongo/mongo_livedata_tests.js +++ b/packages/mongo/mongo_livedata_tests.js @@ -4276,139 +4276,153 @@ if (Meteor.isServer) { }); } -Tinytest.addAsync('mongo-livedata - maintained isomorphism on collection operations for both client and server', async function(test, expect) { - const Collection = new Mongo.Collection(`maintained_col_op_iso${test.runId()}`); - - await Collection.insertAsync({ _id: 'a' }); - await Collection.insertAsync({ _id: 'b' }); - - let items = await Collection.find().fetchAsync(); - let itemIds = items.map(_item => _item._id); - - test.equal(itemIds, ['a', 'b']); - - await Collection.updateAsync({ _id: 'a' }, { $set: { num: 1 } }); - await Collection.updateAsync({ _id: 'b' }, { $set: { num: 2 } }); - - items = await Collection.find().fetchAsync(); - itemIds = items.map(_item => _item.num); - - test.equal(itemIds, [1, 2]); - - await Collection.removeAsync({ _id: 'a' }); - await Collection.removeAsync({ _id: 'b' }); - - items = await Collection.find().fetchAsync(); - - test.equal(items, []); -}); - -testAsyncMulti('mongo-livedata - collection async operations data persistence', [ - async function (test) { // Using remote collection +Tinytest.addAsync( + 'mongo-livedata - maintained isomorphism on collection operations for both client and server', + async function(test, expect) { const Collection = new Mongo.Collection( - `remoteop_persistence${test.runId()}`, + `maintained_col_op_iso${test.runId()}`, ); await Collection.insertAsync({ _id: 'a' }); + await Collection.insertAsync({ _id: 'b' }); + + let items = await Collection.find().fetchAsync(); + let itemIds = items.map(_item => _item._id); + + test.equal(itemIds, ['a', 'b']); + await Collection.updateAsync({ _id: 'a' }, { $set: { num: 1 } }); - const insertedId = await Collection.insertAsync({ num: 2 }); - - let items = await Collection.find().fetchAsync(); - let itemIds = items.map(_item => _item._id); - test.equal(itemIds, ['a', insertedId]); // temporary data accessible - - const aItem = items[0]; - const insertedItem = items[1]; - test.equal(aItem?.num, 1); - test.equal(insertedItem?.num, 2); - - await Collection.removeAsync({ _id: insertedId }); + await Collection.updateAsync({ _id: 'b' }, { $set: { num: 2 } }); items = await Collection.find().fetchAsync(); - itemIds = items.map(_item => _item._id); + itemIds = items.map(_item => _item.num); - test.equal(itemIds, ['a']); // temporary data accessible + test.equal(itemIds, [1, 2]); - if (Meteor.isClient) { - return new Promise(resolve => { - Meteor.setTimeout(async () => { - items = await Collection.find().fetchAsync(); - itemIds = items.map(_item => _item._id); - test.equal(itemIds, []); // data IS NOT persisted - resolve(); - }, 100); - }); - } - - return Promise.resolve(); - }, - async function (test) { // Using local collection - const Collection = new Mongo.Collection( - `localop_persistence${test.runId()}`, - ); - - await Collection._collection.insertAsync({ _id: 'a' }); - await Collection._collection.updateAsync({ _id: 'a' }, { $set: { num: 1 } }); - const insertedId = await Collection._collection.insertAsync({ num: 2 }); - - let items = await Collection.find().fetchAsync(); - let itemIds = items.map(_item => _item._id); - test.equal(itemIds, ['a', insertedId]); // temporary data accessible - - const aItem = items[0]; - const insertedItem = items[1]; - test.equal(aItem?.num, 1); - test.equal(insertedItem?.num, 2); - - await Collection._collection.removeAsync({ _id: insertedId }); + await Collection.removeAsync({ _id: 'a' }); + await Collection.removeAsync({ _id: 'b' }); items = await Collection.find().fetchAsync(); - itemIds = items.map(_item => _item._id); - test.equal(itemIds, ['a']); // temporary data accessible - - if (Meteor.isClient) { - return new Promise(resolve => { - Meteor.setTimeout(async () => { - items = await Collection.find().fetchAsync(); - itemIds = items.map(_item => _item._id); - test.equal(itemIds, ['a']); // data is persisted - resolve(); - }, 100); - }); - } - - return Promise.resolve(); + test.equal(items, []); }, - async function (test) { // Using methods - const Collection = new Mongo.Collection( - `methodop_persistence${test.runId()}`, - ); +); - Meteor.methods({ - [`insertMethodPersistence${test.runId()}`]: async () => { - await Collection.insertAsync({ _id: 'a' }); - }, - }); +testAsyncMulti( + 'mongo-livedata - collection async operations data persistence', + [ + async function(test) { + // Using remote collection + const Collection = new Mongo.Collection( + `remoteop_persistence${test.runId()}`, + ); - Meteor.callAsync(`insertMethodPersistence${test.runId()}`); + await Collection.insertAsync({ _id: 'a' }); + await Collection.updateAsync({ _id: 'a' }, { $set: { num: 1 } }); + const insertedId = await Collection.insertAsync({ num: 2 }); - let items = await Collection.find().fetchAsync(); - let itemIds = items.map(_item => _item._id); + let items = await Collection.find().fetchAsync(); + let itemIds = items.map(_item => _item._id); + test.equal(itemIds, ['a', insertedId]); // temporary data accessible - test.equal(itemIds, ['a']); // temporary data accessible + const aItem = items[0]; + const insertedItem = items[1]; + test.equal(aItem?.num, 1); + test.equal(insertedItem?.num, 2); - if (Meteor.isClient) { - return new Promise(resolve => { - Meteor.setTimeout(async () => { - items = await Collection.find().fetchAsync(); - itemIds = items.map(_item => _item._id); - test.equal(itemIds, []); // data IS NOT persisted - resolve(); - }, 100); + await Collection.removeAsync({ _id: insertedId }); + + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + + test.equal(itemIds, ['a']); // temporary data accessible + + if (Meteor.isClient) { + return new Promise(resolve => { + Meteor.setTimeout(async () => { + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + test.equal(itemIds, []); // data IS NOT persisted + resolve(); + }, 100); + }); + } + + return Promise.resolve(); + }, + async function(test) { + // Using local collection + const Collection = new Mongo.Collection( + `localop_persistence${test.runId()}`, + ); + + await Collection._collection.insertAsync({ _id: 'a' }); + await Collection._collection.updateAsync( + { _id: 'a' }, + { $set: { num: 1 } }, + ); + const insertedId = await Collection._collection.insertAsync({ num: 2 }); + + let items = await Collection.find().fetchAsync(); + let itemIds = items.map(_item => _item._id); + test.equal(itemIds, ['a', insertedId]); // temporary data accessible + + const aItem = items[0]; + const insertedItem = items[1]; + test.equal(aItem?.num, 1); + test.equal(insertedItem?.num, 2); + + await Collection._collection.removeAsync({ _id: insertedId }); + + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + + test.equal(itemIds, ['a']); // temporary data accessible + + if (Meteor.isClient) { + return new Promise(resolve => { + Meteor.setTimeout(async () => { + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + test.equal(itemIds, ['a']); // data is persisted + resolve(); + }, 100); + }); + } + + return Promise.resolve(); + }, + async function(test) { + // Using methods + const Collection = new Mongo.Collection( + `methodop_persistence${test.runId()}`, + ); + + Meteor.methods({ + [`insertMethodPersistence${test.runId()}`]: async () => { + await Collection.insertAsync({ _id: 'a' }); + }, }); - } - return Promise.resolve(); - }, -]); + Meteor.callAsync(`insertMethodPersistence${test.runId()}`); + + let items = await Collection.find().fetchAsync(); + let itemIds = items.map(_item => _item._id); + + test.equal(itemIds, ['a']); // temporary data accessible + + if (Meteor.isClient) { + return new Promise(resolve => { + Meteor.setTimeout(async () => { + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + test.equal(itemIds, []); // data IS NOT persisted + resolve(); + }, 100); + }); + } + + return Promise.resolve(); + }, + ], +); From fab11594a0c72411f496c479b07066c631c27272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 5 Mar 2024 18:00:30 +0100 Subject: [PATCH 6/7] Revert "ensure the operation method msg is run after the client result to match 2.x behavior" This reverts commit 47ed012b0fdf5fedb198ff345e4768bda574d6cb. --- packages/ddp-client/common/livedata_connection.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/packages/ddp-client/common/livedata_connection.js b/packages/ddp-client/common/livedata_connection.js index 3a36227272..395da44ac9 100644 --- a/packages/ddp-client/common/livedata_connection.js +++ b/packages/ddp-client/common/livedata_connection.js @@ -850,17 +850,7 @@ export class Connection { } // If we added it to the first block, send it out now. - if (self._outstandingMethodBlocks.length === 1) { - if (callback && future) { - // Ensure the method message after the result of the method ran in the client. - future = new Promise((resolve) => { - methodInvoker.sendMessage(); - resolve(); - }); - } else { - methodInvoker.sendMessage(); - } - } + if (self._outstandingMethodBlocks.length === 1) methodInvoker.sendMessage(); // If we're using the default callback on the server, // block waiting for the result. From 84ab049ccf298eee60701c8c702a362d931720f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Wed, 20 Mar 2024 14:58:30 +0100 Subject: [PATCH 7/7] fix and provide proper tests of data persistence on async behaviors --- packages/mongo/mongo_livedata_tests.js | 68 +++++++++++++++++++------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/packages/mongo/mongo_livedata_tests.js b/packages/mongo/mongo_livedata_tests.js index 86c13fa0ec..121262f559 100644 --- a/packages/mongo/mongo_livedata_tests.js +++ b/packages/mongo/mongo_livedata_tests.js @@ -4278,9 +4278,10 @@ if (Meteor.isServer) { Tinytest.addAsync( 'mongo-livedata - maintained isomorphism on collection operations for both client and server', - async function(test, expect) { + async function (test) { const Collection = new Mongo.Collection( `maintained_col_op_iso${test.runId()}`, + { resolverType: 'stub' } ); await Collection.insertAsync({ _id: 'a' }); @@ -4311,10 +4312,13 @@ Tinytest.addAsync( testAsyncMulti( 'mongo-livedata - collection async operations data persistence', [ - async function(test) { + async function (test) { // Using remote collection const Collection = new Mongo.Collection( `remoteop_persistence${test.runId()}`, + { + resolverType: Meteor.isClient ? 'stub' : 'server', + }, ); await Collection.insertAsync({ _id: 'a' }); @@ -4350,7 +4354,7 @@ testAsyncMulti( return Promise.resolve(); }, - async function(test) { + async function (test) { // Using local collection const Collection = new Mongo.Collection( `localop_persistence${test.runId()}`, @@ -4392,11 +4396,19 @@ testAsyncMulti( return Promise.resolve(); }, - async function(test) { + async function (test) { // Using methods const Collection = new Mongo.Collection( `methodop_persistence${test.runId()}`, ); + Collection.allow({ + insertAsync() { + return true; + }, + insert() { + return true; + }, + }); Meteor.methods({ [`insertMethodPersistence${test.runId()}`]: async () => { @@ -4404,25 +4416,45 @@ testAsyncMulti( }, }); - Meteor.callAsync(`insertMethodPersistence${test.runId()}`); + const promise = Meteor.callAsync( + `insertMethodPersistence${test.runId()}`, + ); - let items = await Collection.find().fetchAsync(); - let itemIds = items.map(_item => _item._id); + let items; + let itemIds; + if (Meteor.isServer) { + await promise; - test.equal(itemIds, ['a']); // temporary data accessible + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); - if (Meteor.isClient) { - return new Promise(resolve => { - Meteor.setTimeout(async () => { - items = await Collection.find().fetchAsync(); - itemIds = items.map(_item => _item._id); - test.equal(itemIds, []); // data IS NOT persisted - resolve(); - }, 100); - }); + test.equal(itemIds, ['a']); // temporary data accessible } - return Promise.resolve(); + if (Meteor.isClient) { + await promise.stubPromise; + + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + + test.equal(itemIds, ['a']); // temporary data accessible + + try { + await promise.serverPromise; + } catch (e) { + // error as no insert method enabled on server + return new Promise(resolve => { + Meteor.setTimeout(async () => { + items = await Collection.find().fetchAsync(); + itemIds = items.map(_item => _item._id); + test.equal(itemIds, []); // data IS NOT persisted + resolve(); + }, 100); + }); + } + } else { + return Promise.resolve(); + } }, ], );