How to run script in mongoDb during the cypress test - mongodb

I'm trying to run script in mongodb at the beginning of cypress test. I've added method in plugins/index.js to connect to mongo but I'm not sure what to do next. I've try to add in taks db.command with script, but it doesn't work. Any ideas, how I can do this ?
const { MongoClient } = require('mongodb')
const uri = "someUri"
if (!uri) {
throw new Error('Missing MONGO_URI')
}
const client = new MongoClient(uri)
async function connect() {
await client.connect()
return client.db()
}
module.exports = async (on, config) => {
const db = await connect()
on('task', {
};

I found solution to this if anybody will have same problem.
on('task', {
async updateCarColor() {
await db.collection('collectionName').updateOne({"Id": "45"},
{
"$set": {"car.color": "red"}
})
return null
},
})

Related

Module Error and the program not running (mongo documentation)

const { MongoClient } = require('mongodb');
async function main() {
const uri = "mongodb+srv://rohailmalik:<password>#cluster0.1aaikod.mongodb.net/?retryWrites=true&w=majority";
const client = new MongoClient(uri);
try {
await client.connect();
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
main().catch(console.error);
///Error: Cannot find module '/Users/malikrohail/waitlist/demo.js'
///Error: Cannot find module '/Users/malikrohail/waitlist/demo.js'
please look into this
please look into this

Incorrect State for operation: "new", allowed States: "[running,starting]"

There is just one test case that I'm testing. I verified the MongoDB methods and they seem to be up to
date. No open issues on GitHub as well.
Error: at MongoMemoryServer.getUri (node_modules/mongodb-memory-server-
core/src/MongoMemoryServer.ts:706:15)
at src/test/setup.ts:7:32
at src/test/setup.ts:8:71
at Object.<anonymous>.__awaiter (src/test/setup.ts:4:12)
at Object.<anonymous> (src/test/setup.ts:5:22)
import { MongoMemoryServer } from "mongodb-memory-server";
import mongoose from "mongoose";
let mongo: any;
beforeAll(async () => {
mongo = new MongoMemoryServer();
const mongoUri = await mongo.getUri();
await mongoose.connect(mongoUri);
});
beforeEach(async () => {
const collections = await mongoose.connection.db.collections();
for (let collection of collections) {
await collection.deleteMany({});
}
});
afterAll(async () => {
await mongo.stop();
await mongoose.connection.close();
});
channge the line mongo = new MongoMemoryServer(); to mongo = await MongoMemoryServer.create()
I had your same issue and by looking at the documentation I figure out that you first have to create the object with new and then start the instance with start():
mongod = new MongoMemoryServer()
await mongod.start()
const uri = await mongod.getUri()
const mongooseOptions = {
useNewUrlParser:true,
};
await mongoose.connect(uri,mongooseOptions)
You have 2 options to solve this problem:
1- Change the line:
mongo = new MongoMemoryServer();
to:
mongo = await MongoMemoryServer.create();
2- Change the lines:
mongo = new MongoMemoryServer();
const mongoUri = await mongo.getUri();
await mongoose.connect(mongoUri);
To:
mongod = new MongoMemoryServer()
await mongod.start()
const uri = await mongod.getUri()
const mongooseOptions = {
useNewUrlParser:true,
};
await mongoose.connect(uri, mongooseOptions)

mongodb insertOne inside a loop

I want to insert different collections inside a loop.
I already wrote this and it works once.
const client = new MongoClient(uri, {
useNewUrlParser: true,
useUnifiedTopology: true
});
let insertflowers = async (collectionname,query) => {
try {
await client.connect();
const database = client.db('flowers');
const collection = database.collection(collectionname);
return await collection.insertOne(query);
} finally {
await client.close();
}
}
insertflowers('alocasias',{name:'...'}).catch(console.dir);
What I want to do is put it inside a loop like this.
arrayofflowers.forEach( val => {
let flowerType = ...
insertflowers(flowerType,{name:'...'}).catch(console.dir);
});
But I get the following error
MongoError: Topology is closed, please connect
Thank you for reading
In short remove await client.close();
Check https://docs.mongodb.com/drivers/node/usage-examples/insertMany/ to insert bulk records at once.
You're in race condition so when insertflowers process is running in parallel connection is closed and opening.
So when you try to insert data connection is closed by another call to insertflowers.
const client = new MongoClient(uri, {
useNewUrlParser: true,
useUnifiedTopology: true
});
let connection;
const connect = async () => {
if (!connection) { // return connection if already connected
connection = await client.connect();
}
return connection;
});
let insertflowers = async (collectionname,query) => {
try {
const conn = await connect();
const database = conn.db('flowers');
const collection = database.collection(collectionname);
return await collection.insertOne(query);
} finally {
console.log('insertflowers completed');
// await client.close(); remove this
}
}
Another option - Not a good idea though
Make insertflowers is run the sync.

Jest mock mongoose.startSession() throws error

i'm implemented transaction in the post method. it was work fine. But now I have to update unit test case for that method. I tried to mock startSession() and startTransaction() to check toHaveBeenCalled.But while running test case i got like MongooseError: Connection 0 was disconnected when calling startSession``. I am new to that so i don't know how to mock that?.
Method:
static post = (funcCall: Promise<Document>) => async (response: Response, fields?: string[]) => {
const session = await startSession();
session.startTransaction();
try {
const dbResponse = await funcCall; // model.save(request.body)
// commit the changes if everything was successful
await session.commitTransaction();
success(pick(dbResponse, fields ? fields : ['_id']), 201)(response);
} catch (error) {
// this will rollback any changes made in the database
await session.abortTransaction();
throwError(error);
} finally {
// ending the session
session.endSession();
}
};
My Test case:
it('should perform post when valid parameters is passed.', async () => {
// Preparing
const mockSaveReturn = {
_id: objectID,
test_name: 'sample',
};
jest.spyOn(mongoose, 'startSession')
const spySave = jest.spyOn(modelPrototype.prototype, 'save').mockReturnValueOnce(mockSaveReturn);
const document = new modelPrototype(mockSaveReturn);
// Executing
await post(document.save())(response as Response);
expect(response.send).toHaveBeenCalledWith({ _id: '54759eb3c090d83494e2d804' });
expect(spySave).toHaveBeenCalled();
// Cleaning
spySave.mockClear();
});

Connect Apollo with mongodb

I want to connect my Apollo server with my mongoDB. I know there are many examples out there, but I get stuck at the async part and did not found a solution or example for that (that's strange, am I completly wrong?)
I started with the example from next.js https://github.com/zeit/next.js/tree/master/examples/api-routes-apollo-server-and-client .
But the mongodb integration is missing.
My code
pages/api/graphql.js
import {ApolloServer} from 'apollo-server-micro';
import {schema} from '../../apollo/schema';
const apolloServer = new ApolloServer({schema});
export const config = {
api: {
bodyParser: false
}
};
export default apolloServer.createHandler({path: '/api/graphql'});
apollo/schema.js
import {makeExecutableSchema} from 'graphql-tools';
import {typeDefs} from './type-defs';
import {resolvers} from './resolvers';
export const schema = makeExecutableSchema({
typeDefs,
resolvers
});
apollo/resolvers.js
const Items = require('./connector').Items;
export const resolvers = {
Query: {
item: async (_parent, args) => {
const {id} = args;
const item = await Items.findOne(objectId(id));
return item;
},
...
}
}
apollo/connector.js
require('dotenv').config();
const MongoClient = require('mongodb').MongoClient;
const password = process.env.MONGO_PASSWORD;
const username = process.env.MONGO_USER;
const uri = `mongodb+srv://${username}:${password}#example.com`;
const client = await MongoClient.connect(uri);
const db = await client.db('databaseName')
const Items = db.collection('items')
module.exports = {Items}
So the problem is the await in connector.js. I have no idea how to call this in an async function or how to provide the MongoClient on an other way to the resolver. If I just remove the await, it returns – obviously – an pending promise and can't call the function .db('databaseName') on it.
Unfortunately, we're still a ways off from having top-level await.
You can delay running the rest of your code until the Promise resolves by putting it inside the then callback of the Promise.
async function getDb () {
const client = await MongoClient.connect(uri)
return client.db('databaseName')
}
getDb()
.then(db => {
const apollo = new ApolloServer({
schema,
context: { db },
})
apollo.listen()
})
.catch(e => {
// handle any errors
})
Alternatively, you can create your connection the first time you need it and just cache it:
let db
const apollo = new ApolloServer({
schema,
context: async () => {
if (!db) {
try {
const client = await MongoClient.connect(uri)
db = await client.db('databaseName')
catch (e) {
// handle any errors
}
}
return { db }
},
})
apollo.listen()