From 16a1cf5ba8255e7537eb1fdb20ee42951bea38af Mon Sep 17 00:00:00 2001 From: VLE2FE Date: Fri, 8 May 2020 09:58:12 +0200 Subject: [PATCH] deleting a material is rejected if it is referenced by a sample --- api/material.yaml | 2 ++ api/sample.yaml | 2 +- package.json | 3 ++- src/routes/material.spec.ts | 16 ++++++++++++---- src/routes/material.ts | 21 +++++++++++++++------ src/routes/root.spec.ts | 2 +- src/routes/sample.spec.ts | 2 +- src/routes/sample.ts | 2 +- src/routes/template.spec.ts | 2 +- src/routes/user.spec.ts | 2 +- src/{helpers/test.ts => test/helper.ts} | 2 +- src/test/loadDev.ts | 12 ++++++++++++ 12 files changed, 50 insertions(+), 18 deletions(-) rename src/{helpers/test.ts => test/helper.ts} (98%) create mode 100644 src/test/loadDev.ts diff --git a/api/material.yaml b/api/material.yaml index a3b80da..5e8bc13 100644 --- a/api/material.yaml +++ b/api/material.yaml @@ -79,6 +79,8 @@ responses: 200: $ref: 'api.yaml#/components/responses/Ok' + 400: + $ref: 'api.yaml#/components/responses/400' 401: $ref: 'api.yaml#/components/responses/401' 403: diff --git a/api/sample.yaml b/api/sample.yaml index 8ba92af..e911d9c 100644 --- a/api/sample.yaml +++ b/api/sample.yaml @@ -123,7 +123,7 @@ /sample/notes/fields: get: - summary: TODO list all existing field names for custom notes fields + summary: list all existing field names for custom notes fields description: 'Auth: all, levels: read, write, maintain, dev, admin' tags: - /sample diff --git a/package.json b/package.json index d3f9e63..9a69ea2 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "tsc": "tsc", "test": "mocha dist/**/**.spec.js", "start": "tsc && node dist/index.js || exit 1", - "dev": "nodemon -e ts,yaml --exec \"npm run start\"" + "dev": "nodemon -e ts,yaml --exec \"npm run start\"", + "loadDev": "node dist/test/loadDev.js" }, "keywords": [], "author": "", diff --git a/src/routes/material.spec.ts b/src/routes/material.spec.ts index aa9a484..dbc646b 100644 --- a/src/routes/material.spec.ts +++ b/src/routes/material.spec.ts @@ -1,6 +1,6 @@ import should from 'should/as-function'; import MaterialModel from '../models/material'; -import TestHelper from "../helpers/test"; +import TestHelper from "../test/helper"; describe('/material', () => { @@ -271,20 +271,28 @@ describe('/material', () => { it('deletes the material', done => { TestHelper.request(server, done, { method: 'delete', - url: '/material/100000000000000000000001', + url: '/material/100000000000000000000002', auth: {basic: 'janedoe'}, httpStatus: 200 }).end((err, res) => { if (err) return done(err); should(res.body).be.eql({status: 'OK'}); - MaterialModel.findById('100000000000000000000001').lean().exec((err, data) => { + MaterialModel.findById('100000000000000000000002').lean().exec((err, data) => { if (err) return done(err); should(data).be.null(); done(); }); }); }); - it('rejects deleting a material referenced by samples'); + it('rejects deleting a material referenced by samples', done => { + TestHelper.request(server, done, { + method: 'delete', + url: '/material/100000000000000000000004', + auth: {basic: 'janedoe'}, + httpStatus: 400, + res: {status: 'Material still in use'} + }) + }); it('rejects an invalid id', done => { TestHelper.request(server, done, { method: 'delete', diff --git a/src/routes/material.ts b/src/routes/material.ts index 29362e2..292f02f 100644 --- a/src/routes/material.ts +++ b/src/routes/material.ts @@ -2,8 +2,10 @@ import express from 'express'; import MaterialValidate from './validate/material'; import MaterialModel from '../models/material' +import SampleModel from '../models/sample'; import IdValidate from './validate/id'; import res400 from './validate/res400'; +import mongoose from 'mongoose'; const router = express.Router(); @@ -69,14 +71,21 @@ router.put('/material/' + IdValidate.parameter(), (req, res, next) => { router.delete('/material/' + IdValidate.parameter(), (req, res, next) => { if (!req.auth(res, ['write', 'maintain', 'dev', 'admin'], 'basic')) return; - MaterialModel.findByIdAndDelete(req.params.id).lean().exec((err, data) => { + // check if there are still samples referencing this material + SampleModel.find({'material_id': new mongoose.Types.ObjectId(req.params.id)}).lean().exec((err, data) => { if (err) return next(err); - if (data) { - res.json({status: 'OK'}) - } - else { - res.status(404).json({status: 'Not found'}); + if (data.length) { + return res.status(400).json({status: 'Material still in use'}); } + MaterialModel.findByIdAndDelete(req.params.id).lean().exec((err, data) => { + if (err) return next(err); + if (data) { + res.json({status: 'OK'}) + } + else { + res.status(404).json({status: 'Not found'}); + } + }); }); }); diff --git a/src/routes/root.spec.ts b/src/routes/root.spec.ts index 25be1ba..f8a803f 100644 --- a/src/routes/root.spec.ts +++ b/src/routes/root.spec.ts @@ -1,4 +1,4 @@ -import TestHelper from "../helpers/test"; +import TestHelper from "../test/helper"; describe('/', () => { diff --git a/src/routes/sample.spec.ts b/src/routes/sample.spec.ts index 98017f0..aa01a39 100644 --- a/src/routes/sample.spec.ts +++ b/src/routes/sample.spec.ts @@ -2,7 +2,7 @@ import should from 'should/as-function'; import SampleModel from '../models/sample'; import NoteModel from '../models/note'; import NoteFieldModel from '../models/note_field'; -import TestHelper from "../helpers/test"; +import TestHelper from "../test/helper"; describe('/sample', () => { diff --git a/src/routes/sample.ts b/src/routes/sample.ts index 7415912..fe12ed0 100644 --- a/src/routes/sample.ts +++ b/src/routes/sample.ts @@ -10,7 +10,6 @@ import NoteFieldModel from '../models/note_field'; import IdValidate from './validate/id'; - const router = express.Router(); router.get('/samples', (req, res, next) => { @@ -129,6 +128,7 @@ router.post('/sample/new', async (req, res, next) => { delete sample.notes; sample.note_id = data._id; sample.user_id = req.authDetails.id; + console.log(sample); new SampleModel(sample).save((err, data) => { if (err) return next(err); res.json(SampleValidate.output(data.toObject())); diff --git a/src/routes/template.spec.ts b/src/routes/template.spec.ts index 6a4c7af..fa9361f 100644 --- a/src/routes/template.spec.ts +++ b/src/routes/template.spec.ts @@ -1,7 +1,7 @@ import should from 'should/as-function'; import TemplateTreatmentModel from '../models/treatment_template'; import TemplateMeasurementModel from '../models/measurement_template'; -import TestHelper from "../helpers/test"; +import TestHelper from "../test/helper"; describe('/template', () => { diff --git a/src/routes/user.spec.ts b/src/routes/user.spec.ts index a3a0ed9..e294cb2 100644 --- a/src/routes/user.spec.ts +++ b/src/routes/user.spec.ts @@ -1,6 +1,6 @@ import should from 'should/as-function'; import UserModel from '../models/user'; -import TestHelper from "../helpers/test"; +import TestHelper from "../test/helper"; describe('/user', () => { diff --git a/src/helpers/test.ts b/src/test/helper.ts similarity index 98% rename from src/helpers/test.ts rename to src/test/helper.ts index 6c2fa72..26cb5a5 100644 --- a/src/helpers/test.ts +++ b/src/test/helper.ts @@ -28,7 +28,7 @@ export default class TestHelper { server = require('../index'); db.drop(err => { // reset database if (err) return done(err); - db.loadJson(require('../test/db.json'), done); + db.loadJson(require('./db.json'), done); }); return server } diff --git a/src/test/loadDev.ts b/src/test/loadDev.ts new file mode 100644 index 0000000..690044d --- /dev/null +++ b/src/test/loadDev.ts @@ -0,0 +1,12 @@ +import db from '../db'; + +db.connect('dev', () => { + console.info('dropping data...'); + db.drop(() => { // reset database + console.info('loading data...'); + db.loadJson(require('./db.json'), () => { + console.info('done'); + process.exit(0); + }); + }); +});