added GET /sample/number/{number} route
This commit is contained in:
@ -13,11 +13,16 @@ function flatten (data) { // flatten object: {a: {b: true}} -> {a.b: true}
|
||||
result[prop] = cur;
|
||||
}
|
||||
else if (Array.isArray(cur)) {
|
||||
let l = 0;
|
||||
for(let i = 0, l = cur.length; i < l; i++)
|
||||
recurse(cur[i], prop + "[" + i + "]");
|
||||
if (l == 0)
|
||||
result[prop] = [];
|
||||
if (cur.length && (Object(cur[0]) !== cur || Object.keys(cur[0]).length === 0)) { // array of non-objects
|
||||
result[prop] = '[' + cur.join(', ') + ']';
|
||||
}
|
||||
else {
|
||||
let l = 0;
|
||||
for(let i = 0, l = cur.length; i < l; i++)
|
||||
recurse(cur[i], prop + "[" + i + "]");
|
||||
if (l == 0)
|
||||
result[prop] = [];
|
||||
}
|
||||
}
|
||||
else {
|
||||
let isEmpty = true;
|
||||
|
@ -1343,6 +1343,67 @@ describe('/sample', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /sample/number/{number}', () => {
|
||||
it('returns the right sample', done => {
|
||||
TestHelper.request(server, done, {
|
||||
method: 'get',
|
||||
url: '/sample/number/33',
|
||||
auth: {basic: 'janedoe'},
|
||||
httpStatus: 200,
|
||||
res: {_id: '400000000000000000000003', number: '33', type: 'part', color: 'black', batch: '1704-005', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material: {_id: '100000000000000000000005', name: 'Amodel A 1133 HS', supplier: 'Solvay', group: 'PPA', properties: {material_template: '130000000000000000000003', mineral: 0, glass_fiber: 33, carbon_fiber: 0}, numbers: ['5514262406']}, notes: {comment: '', sample_references: [{sample_id: '400000000000000000000004', relation: 'granulate to sample'}], custom_fields: {'not allowed for new applications': true}}, measurements: [{_id: '800000000000000000000003', sample_id: '400000000000000000000003', values: {val1: 1}, measurement_template: '300000000000000000000003'}], user: 'admin'}
|
||||
});
|
||||
});
|
||||
it('works with an API key', done => {
|
||||
TestHelper.request(server, done, {
|
||||
method: 'get',
|
||||
url: '/sample/number/33',
|
||||
auth: {key: 'janedoe'},
|
||||
httpStatus: 200,
|
||||
res: {_id: '400000000000000000000003', number: '33', type: 'part', color: 'black', batch: '1704-005', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material: {_id: '100000000000000000000005', name: 'Amodel A 1133 HS', supplier: 'Solvay', group: 'PPA', properties: {material_template: '130000000000000000000003', mineral: 0, glass_fiber: 33, carbon_fiber: 0}, numbers: ['5514262406']}, notes: {comment: '', sample_references: [{sample_id: '400000000000000000000004', relation: 'granulate to sample'}], custom_fields: {'not allowed for new applications': true}}, measurements: [{_id: '800000000000000000000003', sample_id: '400000000000000000000003', values: {val1: 1}, measurement_template: '300000000000000000000003'}], user: 'admin'}
|
||||
});
|
||||
});
|
||||
it('returns a deleted sample for a maintain/admin user', done => {
|
||||
TestHelper.request(server, done, {
|
||||
method: 'get',
|
||||
url: '/sample/number/Rng33',
|
||||
auth: {basic: 'admin'},
|
||||
httpStatus: 200,
|
||||
res: {_id: '400000000000000000000005', number: 'Rng33', type: 'granulate', color: 'black', batch: '1653000308', condition: {condition_template: '200000000000000000000003'}, material: {_id: '100000000000000000000005', name: 'Amodel A 1133 HS', supplier: 'Solvay', group: 'PPA', properties: {material_template: '130000000000000000000003', mineral: 0, glass_fiber: 33, carbon_fiber: 0}, numbers: ['5514262406']}, notes: {}, measurements: [], user: 'admin'}
|
||||
});
|
||||
});
|
||||
it('returns 403 for a write user when requesting a deleted sample', done => {
|
||||
TestHelper.request(server, done, {
|
||||
method: 'get',
|
||||
url: '/sample/number/Rng33',
|
||||
auth: {basic: 'janedoe'},
|
||||
httpStatus: 403
|
||||
});
|
||||
});
|
||||
it('returns 404 for an unknown sample', done => {
|
||||
TestHelper.request(server, done, {
|
||||
method: 'get',
|
||||
url: '/sample/number/Rng883',
|
||||
auth: {basic: 'janedoe'},
|
||||
httpStatus: 404
|
||||
});
|
||||
});
|
||||
it('rejects an invalid id', done => {
|
||||
TestHelper.request(server, done, {
|
||||
method: 'get',
|
||||
url: '/sample/number/xx-xx',
|
||||
auth: {basic: 'janedoe'},
|
||||
httpStatus: 404
|
||||
});
|
||||
});
|
||||
it('rejects unauthorized requests', done => {
|
||||
TestHelper.request(server, done, {
|
||||
method: 'get',
|
||||
url: '/sample/number/33',
|
||||
httpStatus: 401
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /sample/restore/{id}', () => {
|
||||
it('sets the status', done => {
|
||||
TestHelper.request(server, done, {
|
||||
|
@ -242,6 +242,13 @@ router.get('/samples', async (req, res, next) => {
|
||||
&& e !== filters.sort[0] // field was not in sort
|
||||
);
|
||||
|
||||
if (fieldsToAdd.find(e => e === 'notes')) { // add notes
|
||||
queryPtr.push(
|
||||
{$lookup: {from: 'notes', localField: 'note_id', foreignField: '_id', as: 'notes'}},
|
||||
{$addFields: {notes: { $arrayElemAt: ['$notes', 0]}}}
|
||||
);
|
||||
}
|
||||
|
||||
if (fieldsToAdd.find(e => /material\./.test(e)) && !materialAdded) { // add material, was not added already
|
||||
queryPtr.push(
|
||||
{$lookup: {from: 'materials', localField: 'material_id', foreignField: '_id', as: 'material'}},
|
||||
@ -387,26 +394,7 @@ router.get('/sample/' + IdValidate.parameter(), (req, res, next) => {
|
||||
|
||||
SampleModel.findById(req.params.id).populate('material_id').populate('user_id', 'name').populate('note_id').exec(async (err, sampleData: any) => {
|
||||
if (err) return next(err);
|
||||
|
||||
if (sampleData) {
|
||||
await sampleData.populate('material_id.group_id').populate('material_id.supplier_id').execPopulate().catch(err => next(err));
|
||||
if (sampleData instanceof Error) return;
|
||||
sampleData = sampleData.toObject();
|
||||
|
||||
if (sampleData.status === globals.status.deleted && !req.auth(res, ['maintain', 'admin'], 'all')) return; // deleted samples only available for maintain/admin
|
||||
sampleData.material = sampleData.material_id; // map data to right keys
|
||||
sampleData.material.group = sampleData.material.group_id.name;
|
||||
sampleData.material.supplier = sampleData.material.supplier_id.name;
|
||||
sampleData.user = sampleData.user_id.name;
|
||||
sampleData.notes = sampleData.note_id ? sampleData.note_id : {};
|
||||
MeasurementModel.find({sample_id: mongoose.Types.ObjectId(req.params.id), status: {$ne: globals.status.deleted}}).lean().exec((err, data) => {
|
||||
sampleData.measurements = data;
|
||||
res.json(SampleValidate.output(sampleData, 'details'));
|
||||
});
|
||||
}
|
||||
else {
|
||||
res.status(404).json({status: 'Not found'});
|
||||
}
|
||||
await sampleReturn(sampleData, req, res, next);
|
||||
});
|
||||
});
|
||||
|
||||
@ -514,6 +502,15 @@ router.delete('/sample/' + IdValidate.parameter(), (req, res, next) => {
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/sample/number/:number', (req, res, next) => {
|
||||
if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'all')) return;
|
||||
|
||||
SampleModel.findOne({number: req.params.number}).populate('material_id').populate('user_id', 'name').populate('note_id').exec(async (err, sampleData: any) => {
|
||||
if (err) return next(err);
|
||||
await sampleReturn(sampleData, req, res, next);
|
||||
});
|
||||
});
|
||||
|
||||
router.put('/sample/restore/' + IdValidate.parameter(), (req, res, next) => {
|
||||
if (!req.auth(res, ['maintain', 'admin'], 'basic')) return;
|
||||
|
||||
@ -769,4 +766,27 @@ function filterQueries (filters) {
|
||||
|
||||
function dateToOId (date) { // convert date to ObjectId
|
||||
return mongoose.Types.ObjectId(Math.floor(date / 1000).toString(16) + '0000000000000000');
|
||||
}
|
||||
|
||||
async function sampleReturn (sampleData, req, res, next) {
|
||||
if (sampleData) {
|
||||
console.log(sampleData);
|
||||
await sampleData.populate('material_id.group_id').populate('material_id.supplier_id').execPopulate().catch(err => next(err));
|
||||
if (sampleData instanceof Error) return;
|
||||
sampleData = sampleData.toObject();
|
||||
|
||||
if (sampleData.status === globals.status.deleted && !req.auth(res, ['maintain', 'admin'], 'all')) return; // deleted samples only available for maintain/admin
|
||||
sampleData.material = sampleData.material_id; // map data to right keys
|
||||
sampleData.material.group = sampleData.material.group_id.name;
|
||||
sampleData.material.supplier = sampleData.material.supplier_id.name;
|
||||
sampleData.user = sampleData.user_id.name;
|
||||
sampleData.notes = sampleData.note_id ? sampleData.note_id : {};
|
||||
MeasurementModel.find({sample_id: sampleData._id, status: {$ne: globals.status.deleted}}).lean().exec((err, data) => {
|
||||
sampleData.measurements = data;
|
||||
res.json(SampleValidate.output(sampleData, 'details'));
|
||||
});
|
||||
}
|
||||
else {
|
||||
res.status(404).json({status: 'Not found'});
|
||||
}
|
||||
}
|
@ -70,13 +70,14 @@ export default class SampleValidate {
|
||||
private static fieldKeys = [
|
||||
...SampleValidate.sortKeys,
|
||||
'condition',
|
||||
'notes',
|
||||
'material_id',
|
||||
'material',
|
||||
'note_id',
|
||||
'user_id',
|
||||
'material._id',
|
||||
'material.numbers',
|
||||
'measurements.spectrum.dpt'
|
||||
'measurements.spectrum.dpt',
|
||||
];
|
||||
|
||||
static input (data, param) { // validate input, set param to 'new' to make all attributes required
|
||||
@ -134,6 +135,7 @@ export default class SampleValidate {
|
||||
material_id: IdValidate.get(),
|
||||
material: MaterialValidate.outputV().append({number: Joi.string().max(128).allow('')}),
|
||||
note_id: IdValidate.get().allow(null),
|
||||
notes: this.sample.notes,
|
||||
user_id: IdValidate.get(),
|
||||
added: this.sample.added
|
||||
};
|
||||
|
Reference in New Issue
Block a user