Skip to content

Commit 37517ad

Browse files
committed
[O2B-1503] fillNumbers work, todo ranges
1 parent eea313a commit 37517ad

6 files changed

Lines changed: 92 additions & 31 deletions

File tree

lib/domain/dtos/filters/LhcFillsFilterDto.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
* or submit itself to any jurisdiction.
1212
*/
1313
const Joi = require('joi');
14+
const { validateRange } = require('../../../utilities/validateRange');
1415

1516
exports.LhcFillsFilterDto = Joi.object({
1617
hasStableBeams: Joi.boolean(),
18+
fillNumbers: Joi.string().trim().custom(validateRange).messages({
19+
'any.invalid': '{{#message}}',
20+
}),
1721
});

lib/domain/dtos/filters/RunFilterDto.js

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const { IntegerComparisonDto, FloatComparisonDto } = require('./NumericalCompari
1818
const { RUN_CALIBRATION_STATUS } = require('../../enums/RunCalibrationStatus.js');
1919
const { RUN_DEFINITIONS } = require('../../enums/RunDefinition.js');
2020
const { singleRunsCollectionCustomCheck } = require('../utils.js');
21+
const { validateRange } = require('../../../utilities/validateRange.js');
2122

2223
const DetectorsFilterDto = Joi.object({
2324
operator: Joi.string().valid('or', 'and', 'none').required(),
@@ -30,35 +31,6 @@ const EorReasonFilterDto = Joi.object({
3031
description: Joi.string(),
3132
});
3233

33-
/**
34-
* Validates run numbers ranges to not exceed 100 runs
35-
*
36-
* @param {*} value The value to validate
37-
* @param {*} helpers The helpers object
38-
* @returns {Object} The value if validation passes
39-
*/
40-
const validateRange = (value, helpers) => {
41-
const MAX_RANGE_SIZE = 100;
42-
43-
const runNumbers = value.split(',').map((runNumber) => runNumber.trim());
44-
45-
for (const runNumber of runNumbers) {
46-
if (runNumber.includes('-')) {
47-
const [start, end] = runNumber.split('-').map((n) => parseInt(n, 10));
48-
if (Number.isNaN(start) || Number.isNaN(end) || start > end) {
49-
return helpers.error('any.invalid', { message: `Invalid range: ${runNumber}` });
50-
}
51-
const rangeSize = end - start + 1;
52-
53-
if (rangeSize > MAX_RANGE_SIZE) {
54-
return helpers.error('any.invalid', { message: `Given range exceeds max size of ${MAX_RANGE_SIZE} runs: ${runNumber}` });
55-
}
56-
}
57-
}
58-
59-
return value;
60-
};
61-
6234
exports.RunFilterDto = Joi.object({
6335
runNumbers: Joi.string().trim().custom(validateRange).messages({
6436
'any.invalid': '{{#message}}',

lib/usecases/lhcFill/GetAllLhcFillsUseCase.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,20 @@ class GetAllLhcFillsUseCase {
4141
const queryBuilder = new QueryBuilder();
4242

4343
if (filter) {
44-
const { hasStableBeams } = filter;
44+
const { hasStableBeams, fillNumbers } = filter;
4545
if (hasStableBeams) {
4646
// For now, if a stableBeamsStart is present, then a beam is stable
4747
queryBuilder.where('stableBeamsStart').not().is(null);
4848
}
49+
50+
if (fillNumbers) {
51+
const fillNumbersSplit = fillNumbers.split(',');
52+
53+
const fillNumbersValidated = fillNumbersSplit.filter((number) => !Number.isNaN(number));
54+
if (fillNumbersValidated.length > 0) {
55+
queryBuilder.where('fillNumber').oneOf(...fillNumbersValidated);
56+
}
57+
}
4958
}
5059

5160
const { count, rows } = await TransactionHelper.provide(async () => {

lib/utilities/validateRange.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Validates numbers ranges to not exceed 100 entities
3+
*
4+
* @param {*} value The value to validate
5+
* @param {*} helpers The helpers object
6+
* @returns {Object} The value if validation passes
7+
*/
8+
export const validateRange = (value, helpers) => {
9+
const MAX_RANGE_SIZE = 100;
10+
11+
const numbers = value.split(',').map((runNumber) => runNumber.trim());
12+
13+
for (const number of numbers) {
14+
if (number.includes('-')) {
15+
const [start, end] = number.split('-').map((n) => parseInt(n, 10));
16+
if (Number.isNaN(start) || Number.isNaN(end) || start > end) {
17+
return helpers.error('any.invalid', { message: `Invalid range: ${number}` });
18+
}
19+
const rangeSize = end - start + 1;
20+
21+
if (rangeSize > MAX_RANGE_SIZE) {
22+
return helpers.error('any.invalid', { message: `Given range exceeds max size of ${MAX_RANGE_SIZE} range: ${number}` });
23+
}
24+
}
25+
}
26+
27+
return value;
28+
};

test/api/runs.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ module.exports = () => {
166166
expect(response.status).to.equal(400);
167167
const { errors: [error] } = response.body;
168168
expect(error.title).to.equal('Invalid Attribute');
169-
expect(error.detail).to.equal(`Given range exceeds max size of ${MAX_RANGE_SIZE} runs: ${runNumberRange}`);
169+
expect(error.detail).to.equal(`Given range exceeds max size of ${MAX_RANGE_SIZE} range: ${runNumberRange}`);
170170
});
171171

172172
it('should return 400 if the calibration status filter is invalid', async () => {

test/lib/usecases/lhcFill/GetAllLhcFillsUseCase.test.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,52 @@ module.exports = () => {
4040
expect(lhcFill.stableBeamsStart).to.not.be.null;
4141
});
4242
});
43+
44+
// Fill number filter tests
45+
46+
it('should only contain specified fill number', async () => {
47+
getAllLhcFillsDto.query = { filter: { hasStableBeams: true, fillNumbers: '6' } };
48+
const { lhcFills } = await new GetAllLhcFillsUseCase().execute(getAllLhcFillsDto);
49+
expect(lhcFills).to.be.an('array').and.lengthOf(1)
50+
51+
lhcFills.forEach((lhcFill) => {
52+
expect(lhcFill.fillNumber).to.equal(6)
53+
});
54+
})
55+
56+
it('should only contain specified fill numbers', async () => {
57+
getAllLhcFillsDto.query = { filter: { hasStableBeams: true, fillNumbers: '6,3' } };
58+
const { lhcFills } = await new GetAllLhcFillsUseCase().execute(getAllLhcFillsDto);
59+
60+
61+
expect(lhcFills).to.be.an('array').and.lengthOf(2)
62+
63+
lhcFills.forEach((lhcFill) => {
64+
expect(lhcFill.fillNumber).oneOf([6,3])
65+
});
66+
})
67+
68+
it('should only contain specified fill numbers, whitespace', async () => {
69+
getAllLhcFillsDto.query = { filter: { hasStableBeams: true, fillNumbers: ' 6 , 3 ' } };
70+
const { lhcFills } = await new GetAllLhcFillsUseCase().execute(getAllLhcFillsDto);
71+
72+
73+
expect(lhcFills).to.be.an('array').and.lengthOf(2)
74+
75+
lhcFills.forEach((lhcFill) => {
76+
expect(lhcFill.fillNumber).oneOf([6,3])
77+
});
78+
})
79+
80+
it('should only contain specified fill numbers, comma misplacement', async () => {
81+
getAllLhcFillsDto.query = { filter: { hasStableBeams: true, fillNumbers: ',6,3,' } };
82+
const { lhcFills } = await new GetAllLhcFillsUseCase().execute(getAllLhcFillsDto);
83+
84+
85+
expect(lhcFills).to.be.an('array').and.lengthOf(2)
86+
87+
lhcFills.forEach((lhcFill) => {
88+
expect(lhcFill.fillNumber).oneOf([6,3])
89+
});
90+
})
4391
};

0 commit comments

Comments
 (0)