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": [