diff --git a/app/middleware/template.js b/app/middleware/template.js index 1f5fc23b8..eb0bf3d4d 100644 --- a/app/middleware/template.js +++ b/app/middleware/template.js @@ -10,6 +10,11 @@ module.exports = async (req, res, next, ident) => { include: [ {as: 'logoImage', model: db.models.image.scope('public')}, {as: 'headerImage', model: db.models.image.scope('public')}, + {as: 'signatureTypes', + model: db.models.templateSignatureTypes, + attributes: { + exclude: ['id', 'templateId', 'deletedAt', 'updatedAt', 'createdAt', 'updatedBy'], + }}, ], }); } catch (error) { diff --git a/app/models/index.js b/app/models/index.js index 78c5ea395..502d2d3ea 100644 --- a/app/models/index.js +++ b/app/models/index.js @@ -566,8 +566,8 @@ templateAppendix.belongsTo(project, { // Template Signature Types const templateSignatureTypes = require('./template/templateSignatureTypes')(sequelize, Sq); -template.hasOne(templateSignatureTypes, { - as: 'signature_types', foreignKey: 'templateId', targetKey: 'id', onDelete: 'CASCADE', constraints: true, +template.hasMany(templateSignatureTypes, { + as: 'signatureTypes', foreignKey: 'templateId', targetKey: 'id', onDelete: 'CASCADE', constraints: true, }); templateSignatureTypes.belongsTo(template, { diff --git a/app/routes/template/template.js b/app/routes/template/template.js index 6c2adedab..0b46ac30d 100644 --- a/app/routes/template/template.js +++ b/app/routes/template/template.js @@ -144,6 +144,23 @@ router.route('/') ...((name) ? {name: {[Op.iLike]: `%${name}%`}} : {}), ...((organization) ? {organization: {[Op.iLike]: `%${organization}%`}} : {}), }, + include: [ + { + model: db.models.image.scope('public'), + as: 'logoImage', + }, + { + model: db.models.image.scope('public'), + as: 'headerImage', + }, + { + model: db.models.templateSignatureTypes, + as: 'signatureTypes', + attributes: { + exclude: ['id', 'templateId', 'deletedAt', 'updatedAt', 'createdAt', 'updatedBy'], + }, + }, + ], }; try { diff --git a/app/routes/template/templateSignatureTypes.js b/app/routes/template/templateSignatureTypes.js index 8b3113ab3..d0ad2f110 100644 --- a/app/routes/template/templateSignatureTypes.js +++ b/app/routes/template/templateSignatureTypes.js @@ -14,16 +14,19 @@ const {BASE_EXCLUDE} = require('../../schemas/exclude'); const createSchema = schemaGenerator(db.models.templateSignatureTypes, { baseUri: '/create', exclude: [...BASE_EXCLUDE, 'templateId'], }); -const updateSchema = schemaGenerator(db.models.templateSignatureTypes, { - baseUri: '/update', exclude: [...BASE_EXCLUDE, 'templateId'], nothingRequired: true, -}); // Add middleware to get template signature type router.use('/', async (req, res, next) => { try { - req.templateSignatureTypes = await db.models.templateSignatureTypes.findOne({ - where: {templateId: req.template.id}, - }); + if (req.body.signatureType) { + req.templateSignatureTypes = await db.models.templateSignatureTypes.scope('public').findOne({ + where: {templateId: req.template.id, signatureType: req.body.signatureType}, + }); + } else { + req.templateSignatureTypes = await db.models.templateSignatureTypes.scope('public').findAll({ + where: {templateId: req.template.id}, + }); + } } catch (error) { logger.error(`Unable to get template signature type ${error}`); return res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ @@ -33,14 +36,12 @@ router.use('/', async (req, res, next) => { // Throw an error for a POST when a template signature already exists if (req.templateSignatureTypes && req.method === 'POST') { - logger.error(`Template signature type already exists for ${req.template.name}`); - return res.status(HTTP_STATUS.CONFLICT).json({ - error: {message: `Template signature type already exists for ${req.template.name}`}, - }); + logger.warn(`Template signature type ${req.body.signatureType} already exists for ${req.template.name}`); + return res.status(HTTP_STATUS.CREATED).json(req.templateSignatureTypes.view('public')); } // Throw an error for everything but a POST if the signature doesn't exist - if (!req.templateSignatureTypes && req.method !== 'POST') { + if ((!req.templateSignatureTypes || req.templateSignatureTypes.length === 0) && req.method !== 'POST') { logger.error(`Template signature type does not exist for ${req.template.name}`); return res.status(HTTP_STATUS.NOT_FOUND).json({ error: {message: `Template signature type does not exist for ${req.template.name}`}, @@ -52,7 +53,7 @@ router.use('/', async (req, res, next) => { // Handle requests for template by ident router.route('/') .get((req, res) => { - return res.json(req.templateSignatureTypes.view('public')); + return res.json(req.templateSignatureTypes); }) .post(async (req, res) => { // Validate request against schema @@ -77,30 +78,10 @@ router.route('/') }); } }) - .put(async (req, res) => { - // Validate request against schema - try { - validateAgainstSchema(updateSchema, req.body, false); - } catch (error) { - const message = `Error while validating template signature type update request ${error}`; - logger.error(message); - return res.status(HTTP_STATUS.BAD_REQUEST).json({error: {message}}); - } - // Update db entry - try { - await req.templateSignatureTypes.update(req.body, {userId: req.user.id}); - return res.json(req.templateSignatureTypes.view('public')); - } catch (error) { - logger.error(`Unable to update template signature type ${error}`); - return res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ - error: {message: 'Unable to update template signature type'}, - }); - } - }) .delete(async (req, res) => { // Soft delete template signature type try { - await req.templateSignatureTypes.destroy(); + await db.models.templateSignatureTypes.destroy({where: {templateId: req.template.id}}); return res.status(HTTP_STATUS.NO_CONTENT).send(); } catch (error) { logger.error(`Error while removing template signature type ${error}`); diff --git a/test/routes/template/template.test.js b/test/routes/template/template.test.js index dabbe7292..1dc6da520 100644 --- a/test/routes/template/template.test.js +++ b/test/routes/template/template.test.js @@ -125,9 +125,26 @@ const checkTemplate = (reportObject) => { })); }; -const checkTemplates = (templates) => { +const templatePropertiesWithSignature = [ + 'ident', 'createdAt', 'updatedAt', 'name', 'organization', + 'sections', 'signatureTypes', +]; + +const checkTemplateWithSignature = (reportObject) => { + templatePropertiesWithSignature.forEach((element) => { + expect(reportObject).toHaveProperty(element); + }); + expect(reportObject).toEqual(expect.not.objectContaining({ + id: expect.any(Number), + logoId: expect.any(Number), + headerId: expect.any(Number), + deletedAt: expect.any(String), + })); +}; + +const checkTemplatesWithSignature = (templates) => { templates.forEach((template) => { - checkTemplate(template); + checkTemplateWithSignature(template); }); }; @@ -155,7 +172,7 @@ describe('/templates', () => { .expect(HTTP_STATUS.OK); expect(Array.isArray(res.body)).toBe(true); - checkTemplates(res.body); + checkTemplatesWithSignature(res.body); }, LONGER_TIMEOUT); test('/ - template name query - 200 success', async () => { @@ -166,7 +183,7 @@ describe('/templates', () => { .type('json') .expect(HTTP_STATUS.OK); - checkTemplates(res.body); + checkTemplatesWithSignature(res.body); expect(res.body).toEqual(expect.arrayContaining([ expect.objectContaining({name: expect.stringContaining('Template')}), ])); @@ -180,7 +197,7 @@ describe('/templates', () => { .type('json') .expect(HTTP_STATUS.OK); - checkTemplates(res.body); + checkTemplatesWithSignature(res.body); expect(res.body).toEqual(expect.arrayContaining([ expect.objectContaining({organization: expect.stringContaining('Test')}), ])); diff --git a/test/routes/template/templateSignatureTypes.test.js b/test/routes/template/templateSignatureTypes.test.js index 69e49d0c0..20de3d085 100644 --- a/test/routes/template/templateSignatureTypes.test.js +++ b/test/routes/template/templateSignatureTypes.test.js @@ -16,12 +16,8 @@ const CREATE_DATA = { signatureType: 'reviewer', }; -const UPDATE_DATA = { - signatureType: 'reviewerupdate', -}; - const templateSignatureProperties = [ - 'ident', 'createdAt', 'updatedAt', 'signatureType', + 'createdAt', 'ident', 'signatureType', 'updatedAt', ]; const checkTemplateSignatureTypes = (signatureObject) => { @@ -82,8 +78,8 @@ describe('/templates/{template}/signature-types', () => { .expect(HTTP_STATUS.OK); expect(res.body).not.toBeNull(); - checkTemplateSignatureTypes(res.body); - expect(res.body).toEqual(expect.objectContaining(CREATE_DATA)); + checkTemplateSignatureTypes(res.body[0]); + expect(res.body[0]).toEqual(expect.objectContaining(CREATE_DATA)); }); test('/ - 404 Not Found', async () => { @@ -139,89 +135,6 @@ describe('/templates/{template}/signature-types', () => { }) .expect(HTTP_STATUS.BAD_REQUEST); }); - - test('/ - 409 Conflict - Signature type already exists for template', async () => { - const dupSignature = await db.models.templateSignatureTypes.create({ - ...CREATE_DATA, - templateId: template.id, - }); - - await request - .post(`/api/templates/${template.ident}/signature-types`) - .auth(username, password) - .type('json') - .send(CREATE_DATA) - .expect(HTTP_STATUS.CONFLICT); - - await dupSignature.destroy({force: true}); - }); - }); - - describe('PUT', () => { - let putTest; - - beforeEach(async () => { - putTest = await db.models.templateSignatureTypes.create({ - ...CREATE_DATA, - templateId: template.id, - }); - }); - - afterEach(async () => { - await db.models.templateSignatureTypes.destroy({ - where: {ident: putTest.ident}, - force: true, - }); - }); - - test('/ - 200 Success', async () => { - const res = await request - .put(`/api/templates/${template.ident}/signature-types`) - .auth(username, password) - .type('json') - .send(UPDATE_DATA) - .expect(HTTP_STATUS.OK); - - expect(res.body).not.toBeNull(); - checkTemplateSignatureTypes(res.body); - expect(res.body).toEqual(expect.objectContaining(UPDATE_DATA)); - }); - - test('/ - 403 forbidden to bioinformatician', async () => { - await request - .put(`/api/templates/${template.ident}/signature-types`) - .auth(bioinformaticianUsername, password) - .type('json') - .send(UPDATE_DATA) - .expect(HTTP_STATUS.FORBIDDEN); - }); - - test('/ - 404 Not Found', async () => { - // First soft-delete record - await putTest.destroy(); - - await request - .put(`/api/templates/${template.ident}/signature-types`) - .send({ - signatureType: 'reviewer', - }) - .auth(username, password) - .type('json') - .expect(HTTP_STATUS.NOT_FOUND); - }); - - test('/ - 400 Bad Request - Invalid type', async () => { - await request - .put(`/api/templates/${template.ident}/signature-types`) - .send({ - text: { - data: 'TEST DATA', - }, - }) - .auth(username, password) - .type('json') - .expect(HTTP_STATUS.BAD_REQUEST); - }); }); describe('DELETE', () => {