I am using a dbSnapshot manager to save and load snapshots from/into the database/mongodb.
Since I am making the snapshots over the client the server and client use different connections to the database.
The problem is that I don’t know a way to wait until the publications or the mergebox are ready/updated or if there is a way to trigger a reload of them.
Since I am using puppeteer+cucumber+jest I need a way to wait until the data is ready.
Example:
I am registering a user then I take a snapshot of the database. In another scenario, I load the snapshot into the database but at the moment the user would log in the data is not ready and the login fails.
I save the snapshot with:
async storeSnapshot(fixtureFileName) {
const fullFixturePath = getFullSnapshotPath(fixtureFileName)
// todo need to transfer dbSnapshotManager to server side because of
// todo race condition: server mongo call and puppeteer mongo call
await this.delay(4000)
const connection = await MongoClient.connect("mongodb://localhost:3101/meteor", {native_parser: true})
const db = await connection.db('meteor')
const collections = await db.listCollections().toArray()
const collectionsData = await Promise.all(collections.map(async (collectionObj) => {
const collection = await db.collection(collectionObj.name)
const data = await collection.find().toArray()
return {name: collectionObj.name, data: data}
}))
await fs.writeFileSync(fullFixturePath, ejson.stringify(collectionsData, null, 2))
//await db.close()
await connection.close(false, () => {
})
},
And I load the snapshot with:
async restoreSnapshot(fixtureFileName, data) {
if (!data && !fixtureFileName) {
throw new Error("Error, no fixture file name or data given to restore DB snapshot")
}
const fullFixturePath = getFullSnapshotPath(fixtureFileName)
const connection = await MongoClient.connect("mongodb://localhost:3101/meteor", {native_parser: true})
const db = await connection.db('meteor')
data = data ? data : await fs.readFileSync(fullFixturePath, {encoding: 'utf-8'})
const collectionsData = await ejson.parse(data)
// delete all collections
await Promise.all(collectionsData.map(async (fixtureDataObj) => {
const name = fixtureDataObj.name
const collection = await db.collection(name)
await collection.remove()
}))
await Promise.all(collectionsData.map(async (fixtureDataObj) => {
const name = fixtureDataObj.name
const data = fixtureDataObj.data
// skip empty tables, because that's an error
if (!_.isArray(data) || !data.length) {
return
}
const collection = await db.collection(name)
await collection.insertMany(data)
}))
},