/* eslint-disable no-unused-expressions */ const { expect } = require('chai'); const mongoMocker = require('mongo-mocker'); const joi = require('joi'); const { makeMongoCrud } = require('server/modules/crud'); describe('API - Crud module', () => { let db = null; let crud = null; const schema = { name: joi.string(), email: joi.string().email() }; const testUsers = [ { name: 'John Doe', email: 'john.doe@mubaloo.com' }, { name: 'Jill Doe', email: 'jill.doe@mubaloo.com' } ]; const collection = 'users'; before(() => { db = mongoMocker('mongoDriver/path', { [collection]: testUsers }); crud = makeMongoCrud(collection, schema); }); beforeEach(async () => { const users = await db.collection(collection); await Promise.all(testUsers.map(user => users.insert(user))); }); afterEach(() => { db.mock.clearAll(); }); describe('insertDoc', () => { it('should be defined', () => { expect(crud).to.have.property('insertDoc'); expect(crud.insertDoc).to.be.a('function'); }); it('should insert a document into the collection', async () => { const users = await db.collection(collection); const testUser = { name: 'Jack Doe', email: 'jack.doe@mubaloo.com' }; const rowsBefore = await users.find(testUser) .toArray(); expect(rowsBefore).to.be.an('array').of.length(0); const newUserResult = await crud.insertDoc(db, testUser); const rowsAfter = await users.find(testUser) .toArray(); expect(rowsAfter).to.be.an('array').of.length(1); expect(rowsAfter[0]).to.have.property('name', 'Jack Doe'); expect(rowsAfter[0]).to.have.property('email', 'jack.doe@mubaloo.com'); expect(rowsAfter[0]).to.have.property('_id'); expect(rowsAfter[0]._id).to.be.an('object'); expect(newUserResult).to.be.an('object'); expect(newUserResult).to.have.property('name', 'Jack Doe'); expect(newUserResult).to.have.property('email', 'jack.doe@mubaloo.com'); }); const badUsers = [ {}, { name: 'Some name' }, { email: 'some.email@mubaloo.com' }, { name: 'Some name', email: 'notanemail' } ]; badUsers.forEach((user, index) => { it(`should throw an error if information is missing or invalid (${index + 1}/${badUsers.length})`, async () => { let errorThrown = false; try { await crud.insertDoc(db, user); } catch (err) { expect(err).to.have.property('statusCode', 400); errorThrown = true; } if (!errorThrown) { throw new Error('Did not throw an error'); } }); }); }); describe('modifyDoc', () => { it('should be defined', () => { expect(crud).to.have.property('modifyDoc'); expect(crud.modifyDoc).to.be.a('function'); }); it('should modify a specific document', async () => { const users = await db.collection(collection); const user = await users.findOne({ name: 'John Doe' }); const id = String(user._id); await crud.modifyDoc(db, id, { name: 'Jack Doe' }); const modifiedUser = await users.findOne({ _id: user._id }); expect(modifiedUser).to.have.property('name', 'Jack Doe'); expect(modifiedUser).to.have.property('email', 'john.doe@mubaloo.com'); }); const badUsers = [ { email: 'notanemail' } ]; badUsers.forEach((user, index) => { it(`should throw an error if information is invalid (${index + 1}/${badUsers.length})`, async () => { const users = await db.collection(collection); const userResult = await users.findOne({ name: 'John Doe' }); const id = String(userResult._id); let errorThrown = false; try { await crud.modifyDoc(db, id, user); } catch (err) { errorThrown = true; expect(err).to.have.property('statusCode', 400); } if (!errorThrown) { throw new Error('Did not throw an error'); } }); }); }); describe('deleteDoc', () => { it('should be defined', () => { expect(crud).to.have.property('deleteDoc'); expect(crud.deleteDoc).to.be.a('function'); }); it('should delete a document', async () => { const users = await db.collection(collection); const existingUser = await users.findOne({ name: 'John Doe' }); expect(existingUser).to.be.an('object'); const id = String(existingUser._id); await crud.deleteDoc(db, id); const newQueryResult = await users.findOne({ name: 'John Doe' }); expect(newQueryResult).to.be.undefined; }); }); describe('getDocs', () => { it('should be defined', () => { expect(crud).to.have.property('getDocs'); expect(crud.getDocs).to.be.a('function'); }); it('should get a complete list of documents', async () => { const result = await crud.getDocs(db); expect(result).to.be.an('array').of.length(2); expect(result[0]).to.deep.include({ name: 'John Doe', email: 'john.doe@mubaloo.com' }); expect(result[1]).to.deep.include({ name: 'Jill Doe', email: 'jill.doe@mubaloo.com' }); expect(result[0]).to.have.property('id'); expect(result[1]).to.have.property('id'); expect(result[0].id).to.be.a('string'); expect(result[1].id).to.be.a('string'); }); }); });