Archived
2

deleting a material is rejected if it is referenced by a sample

This commit is contained in:
VLE2FE 2020-05-08 09:58:12 +02:00
parent 63a5f5ebd1
commit 16a1cf5ba8
12 changed files with 50 additions and 18 deletions

View File

@ -79,6 +79,8 @@
responses: responses:
200: 200:
$ref: 'api.yaml#/components/responses/Ok' $ref: 'api.yaml#/components/responses/Ok'
400:
$ref: 'api.yaml#/components/responses/400'
401: 401:
$ref: 'api.yaml#/components/responses/401' $ref: 'api.yaml#/components/responses/401'
403: 403:

View File

@ -123,7 +123,7 @@
/sample/notes/fields: /sample/notes/fields:
get: 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' description: 'Auth: all, levels: read, write, maintain, dev, admin'
tags: tags:
- /sample - /sample

View File

@ -7,7 +7,8 @@
"tsc": "tsc", "tsc": "tsc",
"test": "mocha dist/**/**.spec.js", "test": "mocha dist/**/**.spec.js",
"start": "tsc && node dist/index.js || exit 1", "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": [], "keywords": [],
"author": "", "author": "",

View File

@ -1,6 +1,6 @@
import should from 'should/as-function'; import should from 'should/as-function';
import MaterialModel from '../models/material'; import MaterialModel from '../models/material';
import TestHelper from "../helpers/test"; import TestHelper from "../test/helper";
describe('/material', () => { describe('/material', () => {
@ -271,20 +271,28 @@ describe('/material', () => {
it('deletes the material', done => { it('deletes the material', done => {
TestHelper.request(server, done, { TestHelper.request(server, done, {
method: 'delete', method: 'delete',
url: '/material/100000000000000000000001', url: '/material/100000000000000000000002',
auth: {basic: 'janedoe'}, auth: {basic: 'janedoe'},
httpStatus: 200 httpStatus: 200
}).end((err, res) => { }).end((err, res) => {
if (err) return done(err); if (err) return done(err);
should(res.body).be.eql({status: 'OK'}); 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); if (err) return done(err);
should(data).be.null(); should(data).be.null();
done(); 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 => { it('rejects an invalid id', done => {
TestHelper.request(server, done, { TestHelper.request(server, done, {
method: 'delete', method: 'delete',

View File

@ -2,8 +2,10 @@ import express from 'express';
import MaterialValidate from './validate/material'; import MaterialValidate from './validate/material';
import MaterialModel from '../models/material' import MaterialModel from '../models/material'
import SampleModel from '../models/sample';
import IdValidate from './validate/id'; import IdValidate from './validate/id';
import res400 from './validate/res400'; import res400 from './validate/res400';
import mongoose from 'mongoose';
const router = express.Router(); const router = express.Router();
@ -69,6 +71,12 @@ router.put('/material/' + IdValidate.parameter(), (req, res, next) => {
router.delete('/material/' + IdValidate.parameter(), (req, res, next) => { router.delete('/material/' + IdValidate.parameter(), (req, res, next) => {
if (!req.auth(res, ['write', 'maintain', 'dev', 'admin'], 'basic')) return; if (!req.auth(res, ['write', 'maintain', 'dev', 'admin'], 'basic')) return;
// 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.length) {
return res.status(400).json({status: 'Material still in use'});
}
MaterialModel.findByIdAndDelete(req.params.id).lean().exec((err, data) => { MaterialModel.findByIdAndDelete(req.params.id).lean().exec((err, data) => {
if (err) return next(err); if (err) return next(err);
if (data) { if (data) {
@ -78,6 +86,7 @@ router.delete('/material/' + IdValidate.parameter(), (req, res, next) => {
res.status(404).json({status: 'Not found'}); res.status(404).json({status: 'Not found'});
} }
}); });
});
}); });
router.post('/material/new', (req, res, next) => { router.post('/material/new', (req, res, next) => {

View File

@ -1,4 +1,4 @@
import TestHelper from "../helpers/test"; import TestHelper from "../test/helper";
describe('/', () => { describe('/', () => {

View File

@ -2,7 +2,7 @@ import should from 'should/as-function';
import SampleModel from '../models/sample'; import SampleModel from '../models/sample';
import NoteModel from '../models/note'; import NoteModel from '../models/note';
import NoteFieldModel from '../models/note_field'; import NoteFieldModel from '../models/note_field';
import TestHelper from "../helpers/test"; import TestHelper from "../test/helper";
describe('/sample', () => { describe('/sample', () => {

View File

@ -10,7 +10,6 @@ import NoteFieldModel from '../models/note_field';
import IdValidate from './validate/id'; import IdValidate from './validate/id';
const router = express.Router(); const router = express.Router();
router.get('/samples', (req, res, next) => { router.get('/samples', (req, res, next) => {
@ -129,6 +128,7 @@ router.post('/sample/new', async (req, res, next) => {
delete sample.notes; delete sample.notes;
sample.note_id = data._id; sample.note_id = data._id;
sample.user_id = req.authDetails.id; sample.user_id = req.authDetails.id;
console.log(sample);
new SampleModel(sample).save((err, data) => { new SampleModel(sample).save((err, data) => {
if (err) return next(err); if (err) return next(err);
res.json(SampleValidate.output(data.toObject())); res.json(SampleValidate.output(data.toObject()));

View File

@ -1,7 +1,7 @@
import should from 'should/as-function'; import should from 'should/as-function';
import TemplateTreatmentModel from '../models/treatment_template'; import TemplateTreatmentModel from '../models/treatment_template';
import TemplateMeasurementModel from '../models/measurement_template'; import TemplateMeasurementModel from '../models/measurement_template';
import TestHelper from "../helpers/test"; import TestHelper from "../test/helper";
describe('/template', () => { describe('/template', () => {

View File

@ -1,6 +1,6 @@
import should from 'should/as-function'; import should from 'should/as-function';
import UserModel from '../models/user'; import UserModel from '../models/user';
import TestHelper from "../helpers/test"; import TestHelper from "../test/helper";
describe('/user', () => { describe('/user', () => {

View File

@ -28,7 +28,7 @@ export default class TestHelper {
server = require('../index'); server = require('../index');
db.drop(err => { // reset database db.drop(err => { // reset database
if (err) return done(err); if (err) return done(err);
db.loadJson(require('../test/db.json'), done); db.loadJson(require('./db.json'), done);
}); });
return server return server
} }

12
src/test/loadDev.ts Normal file
View File

@ -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);
});
});
});