diff --git a/.idea/dataSources.local.xml b/.idea/dataSources.local.xml new file mode 100644 index 0000000..ca0dc03 --- /dev/null +++ b/.idea/dataSources.local.xml @@ -0,0 +1,15 @@ + + + + + + + master_key + + + + + + + + \ No newline at end of file diff --git a/.idea/dataSources/46f112fc-d60d-4217-873f-f5ffea06180c.xml b/.idea/dataSources/46f112fc-d60d-4217-873f-f5ffea06180c.xml new file mode 100644 index 0000000..1619391 --- /dev/null +++ b/.idea/dataSources/46f112fc-d60d-4217-873f-f5ffea06180c.xml @@ -0,0 +1,584 @@ + + + + + 4.2.5 + + + + + + + + 1 + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + ObjectId(0)|12s + + + 1 + Integer|4s + + + 2 + String(0)|12s + + + 3 + String(0)|12s + + + 4 + String(0)|12s + + + 5 + String(0)|12s + + + 6 + String(0)|12s + + + 7 + list(0)|4999545s + + + 8 + ObjectId(0)|12s + + + 9 + String(0)|12s + + + 10 + Double(0)|8s + + + 11 + String(0)|12s + + + ObjectId(0)|12s + + + 1 + Integer|4s + + + 2 + String(0)|12s + + + 3 + list(0)|4999545s + + + ObjectId(0)|12s + + + 1 + Integer|4s + + + 2 + String(0)|12s + + + 3 + String(0)|12s + + + 4 + ObjectId(0)|12s + + + 5 + ObjectId(0)|12s + + + 6 + String(0)|12s + + + 7 + String(0)|12s + + + 8 + ObjectId(0)|12s + + + ObjectId(0)|12s + + + 1 + Integer|4s + + + 2 + String(0)|12s + + + 3 + String(0)|12s + + + 4 + String(0)|12s + + + 5 + String(0)|12s + + + 6 + String(0)|12s + + + 7 + String(0)|12s + + + 8 + String(0)|12s + + + ObjectId(0)|12s + + + 1 + Integer|4s + + + 2 + Integer|4s + + + 3 + Integer|4s + + + 4 + String(0)|12s + + + 5 + Integer|4s + + + 6 + String(0)|12s + + + 7 + list(0)|4999545s + + + 8 + String(0)|12s + + + 9 + Double(0)|8s + + + 10 + String(0)|12s + + + ObjectId(0)|12s + + + 1 + String(0)|12s + + + 2 + list(0)|4999545s + + + 3 + String(0)|12s + + + 4 + map(0)|4999544s + + + 5 + Double(0)|8s + + + 6 + Integer|4s + + + ObjectId(0)|12s + + + 1 + Integer|4s + + + 2 + String(0)|12s + + + 3 + Integer|4s + + + ObjectId(0)|12s + + + 1 + Integer|4s + + + 2 + String(0)|12s + + + 3 + map(0)|4999544s + + + 4 + String(0)|12s + + + 5 + Boolean|12s + + + 6 + list(0)|4999545s + + + 7 + String(0)|12s + + + 8 + String(0)|12s + + + ObjectId(0)|12s + + + 1 + Integer|4s + + + 2 + String(0)|12s + + + 3 + String(0)|12s + + + 4 + ObjectId(0)|12s + + + 5 + String(0)|12s + + + 6 + String(0)|12s + + + 7 + String(0)|12s + + + 8 + ObjectId(0)|12s + + + 9 + Boolean|12s + + + ObjectId(0)|12s + + + 1 + String(0)|12s + + + 2 + list(0)|4999545s + + + 3 + String(0)|12s + + + 4 + map(0)|4999544s + + + 5 + Integer|4s + + + 6 + Integer|4s + + + 7 + array(0)|2003s + + + ObjectId(0)|12s + + + 1 + Integer|4s + + + 2 + String(0)|12s + + + 3 + String(0)|12s + + + 4 + String(0)|12s + + + 5 + String(0)|12s + + + 6 + String(0)|12s + + + 7 + String(0)|12s + + + 8 + String(0)|12s + + + String(0)|12s + + + 1 + map(0)|4999544s + + + 2 + String(0)|12s + + + 3 + Integer|4s + + + 4 + map(0)|4999544s + + + 5 + String(0)|12s + + + 6 + String(0)|12s + + + 7 + String(0)|12s + + + 8 + String(0)|12s + + + 9 + String(0)|12s + + + 10 + String(0)|12s + + + 11 + String(0)|12s + + + 12 + String(0)|12s + + + 13 + String(0)|12s + + + 14 + Boolean|12s + + + 15 + String(0)|12s + + + 16 + String(0)|12s + + + 17 + Integer|4s + + + 18 + list(0)|4999545s + + + 19 + map(0)|4999544s + + + 20 + String(0)|12s + + + 21 + array(0)|2003s + + + 22 + String(0)|12s + + + 23 + String(0)|12s + + + 24 + String(0)|12s + + + 25 + array(0)|2003s + + + 26 + map(0)|4999544s + + + 27 + String(0)|12s + + + 28 + map(0)|4999544s + + + 29 + String(0)|12s + + + 30 + Integer|4s + + + 31 + Boolean|12s + + + 32 + map(0)|4999544s + + + 33 + String(0)|12s + + + 34 + map(0)|4999544s + + + 35 + Boolean|12s + + + 36 + map(0)|4999544s + + + 37 + String(0)|12s + + + 38 + Boolean|12s + + + 39 + String(0)|12s + + + 40 + String(0)|12s + + + 41 + Long(0)|12s + + + 42 + Date(0)|91s + + + 43 + String(0)|12s + + + ObjectId(0)|12s + + + 1 + Integer|4s + + + 2 + Integer|4s + + + ObjectId(0)|12s + + + 1 + String(0)|12s + + + \ No newline at end of file diff --git a/api/condition.yaml b/api/condition.yaml index 38bc56c..32f410b 100644 --- a/api/condition.yaml +++ b/api/condition.yaml @@ -2,7 +2,7 @@ parameters: - $ref: 'api.yaml#/components/parameters/Id' get: - summary: TODO condition by id + summary: condition by id description: 'Auth: all, levels: read, write, maintain, dev, admin' tags: - /condition @@ -74,7 +74,7 @@ /condition/new: post: - summary: TODO add condition + summary: add condition description: 'Auth: basic, levels: write, maintain, dev, admin
Only maintain and admin are allowed to reference samples created by another user' tags: - /condition diff --git a/src/routes/condition.spec.ts b/src/routes/condition.spec.ts index 2f17028..60e7d78 100644 --- a/src/routes/condition.spec.ts +++ b/src/routes/condition.spec.ts @@ -9,7 +9,7 @@ describe('/condition', () => { beforeEach(done => server = TestHelper.beforeEach(server, done)); afterEach(done => TestHelper.afterEach(server, done)); - describe('GET /condition/id', () => { + describe('GET /condition/{id}', () => { it('returns the right condition', done => { TestHelper.request(server, done, { method: 'get', @@ -19,10 +19,117 @@ describe('/condition', () => { res: {_id: '700000000000000000000001', sample_id: '400000000000000000000001', number: 'B1', parameters: {material: 'copper', weeks: 3}, treatment_template: '200000000000000000000001'} }); }); - it('returns the right condition for an API key'); - it('rejects an invalid id'); - it('rejects an unknown id'); - it('rejects unauthorized requests'); + it('returns the right condition for an API key', done => { + TestHelper.request(server, done, { + method: 'get', + url: '/condition/700000000000000000000001', + auth: {key: 'janedoe'}, + httpStatus: 200, + res: {_id: '700000000000000000000001', sample_id: '400000000000000000000001', number: 'B1', parameters: {material: 'copper', weeks: 3}, treatment_template: '200000000000000000000001'} + }); + }); + it('rejects an invalid id', done => { + TestHelper.request(server, done, { + method: 'get', + url: '/condition/70000000000t000000000001', + auth: {basic: 'janedoe'}, + httpStatus: 404 + }); + }); + it('rejects an unknown id', done => { + TestHelper.request(server, done, { + method: 'get', + url: '/condition/000000000000000000000001', + auth: {basic: 'janedoe'}, + httpStatus: 404 + }); + }); + it('rejects unauthorized requests', done => { + TestHelper.request(server, done, { + method: 'get', + url: '/condition/700000000000000000000001', + httpStatus: 401 + }); + }); + }); + + describe('DELETE /condition/{id}', () => { + it('deletes the condition', done => { + TestHelper.request(server, done, { + method: 'delete', + url: '/condition/700000000000000000000002', + auth: {basic: 'janedoe'}, + httpStatus: 200 + }).end((err, res) => { + if (err) return done(err); + should(res.body).be.eql({status: 'OK'}); + ConditionModel.findById('700000000000000000000002').lean().exec((err, data) => { + if (err) return done(err); + should(data).be.null(); + done(); + }); + }); + }); + it('rejects a deleting a condition referenced by measurements'); + it('rejects an invalid id', done => { + TestHelper.request(server, done, { + method: 'delete', + url: '/condition/70000000000w000000000002', + auth: {basic: 'janedoe'}, + httpStatus: 404 + }); + }); + it('rejects an API key', done => { + TestHelper.request(server, done, { + method: 'delete', + url: '/condition/700000000000000000000002', + auth: {key: 'janedoe'}, + httpStatus: 401 + }); + }); + it('rejects requests from a read user', done => { + TestHelper.request(server, done, { + method: 'delete', + url: '/condition/700000000000000000000002', + auth: {basic: 'user'}, + httpStatus: 403 + }); + }); + it('rejects a write user deleting a condition belonging to a sample of another user', done => { + TestHelper.request(server, done, { + method: 'delete', + url: '/condition/700000000000000000000003', + auth: {basic: 'janedoe'}, + httpStatus: 403 + }); + }); + it('accepts an maintain/admin user deleting a condition belonging to a sample of another user', done => { + TestHelper.request(server, done, { + method: 'delete', + url: '/condition/700000000000000000000002', + auth: {basic: 'admin'}, + httpStatus: 200 + }).end((err, res) => { + if (err) return done(err); + should(res.body).be.eql({status: 'OK'}); + done(); + }); + }); + it('returns 404 for an unknown id', done => { + TestHelper.request(server, done, { + method: 'delete', + url: '/condition/00000000000w000000000002', + auth: {basic: 'janedoe'}, + httpStatus: 404 + }); + }); + it('rejects unauthorized requests', done => { + TestHelper.request(server, done, { + method: 'delete', + url: '/condition/700000000000000000000002', + httpStatus: 401 + }); + }); }); describe('POST /condition/new', () => { diff --git a/src/routes/condition.ts b/src/routes/condition.ts index 0cf113d..f5fa085 100644 --- a/src/routes/condition.ts +++ b/src/routes/condition.ts @@ -7,10 +7,41 @@ import res400 from './validate/res400'; import SampleModel from '../models/sample'; import ConditionModel from '../models/condition'; import TreatmentTemplateModel from '../models/treatment_template'; +import IdValidate from './validate/id'; const router = express.Router(); +router.get('/condition/' + IdValidate.parameter(), (req, res, next) => { + if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'all')) return; + + ConditionModel.findById(req.params.id).lean().exec((err, data) => { + if (err) return next(err); + if (data) { + res.json(ConditionValidate.output(data)); + } + else { + res.status(404).json({status: 'Not found'}); + } + }); +}); + +router.delete('/condition/' + IdValidate.parameter(), (req, res, next) => { + if (!req.auth(res, ['write', 'maintain', 'dev', 'admin'], 'basic')) return; + + ConditionModel.findById(req.params.id).lean().exec(async (err, data: any) => { + if (err) return next(err); + if (!data) { + res.status(404).json({status: 'Not found'}); + } + if (!await sampleIdCheck(data, req, res, next)) return; + ConditionModel.findByIdAndDelete(req.params.id).lean().exec(async err => { + if (err) return next(err); + res.json({status: 'OK'}); + }); + }); +}); + router.post('/condition/new', async (req, res, next) => { if (!req.auth(res, ['write', 'maintain', 'dev', 'admin'], 'basic')) return; diff --git a/src/routes/material.ts b/src/routes/material.ts index 292f02f..c6f0c60 100644 --- a/src/routes/material.ts +++ b/src/routes/material.ts @@ -80,7 +80,7 @@ router.delete('/material/' + IdValidate.parameter(), (req, res, next) => { MaterialModel.findByIdAndDelete(req.params.id).lean().exec((err, data) => { if (err) return next(err); if (data) { - res.json({status: 'OK'}) + res.json({status: 'OK'}); } else { res.status(404).json({status: 'Not found'}); diff --git a/src/test/db.json b/src/test/db.json index 95ff0fc..2545a71 100644 --- a/src/test/db.json +++ b/src/test/db.json @@ -194,6 +194,28 @@ }, "treatment_template": {"$oid":"200000000000000000000001"}, "__v": 0 + }, + { + "_id": {"$oid":"700000000000000000000002"}, + "sample_id": {"$oid":"400000000000000000000002"}, + "number": "B1", + "parameters": { + "material": "copper", + "weeks": 3 + }, + "treatment_template": {"$oid":"200000000000000000000001"}, + "__v": 0 + }, + { + "_id": {"$oid":"700000000000000000000003"}, + "sample_id": {"$oid":"400000000000000000000004"}, + "number": "B1", + "parameters": { + "material": "copper", + "weeks": 3 + }, + "treatment_template": {"$oid":"200000000000000000000001"}, + "__v": 0 } ], "treatment_templates": [