Skip to content

Commit 3e42cff

Browse files
committed
Merge branch 'main' of github.com:AliceO2Group/Bookkeeping into feature/O2B-1509/lhcfills-scheme-name-filter
2 parents f1f2c00 + bda5d52 commit 3e42cff

11 files changed

Lines changed: 105 additions & 29 deletions

File tree

lib/database/seeders/20220503120937-lhc-fills.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ module.exports = {
6363
},
6464
{
6565
fill_number: 6,
66-
beam_type: ' PROTON-PROTON ',
66+
beam_type: 'PROTON-PROTON ',
6767
stable_beams_start: '2019-08-08 11:00:00',
6868
stable_beams_end: '2019-08-08 23:00:00',
6969
stable_beams_duration: 60 * 60 * 12,

lib/domain/dtos/filters/LhcFillsFilterDto.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
*/
1313
const Joi = require('joi');
1414
const { validateRange, RANGE_INVALID } = require('../../../utilities/rangeUtils');
15+
const { validateBeamTypes, BEAM_TYPE_INVALID } = require('../../../utilities/beamTypeUtils');
1516
const { validateTimeDuration } = require('../../../utilities/validateTime');
1617

1718
exports.LhcFillsFilterDto = Joi.object({
@@ -22,6 +23,12 @@ exports.LhcFillsFilterDto = Joi.object({
2223
}),
2324
runDuration: validateTimeDuration,
2425
beamDuration: validateTimeDuration,
25-
beamType: Joi.string(),
2626
schemeName: Joi.string().trim().max(64),
27+
beamTypes: Joi.string()
28+
.trim()
29+
.custom(validateBeamTypes)
30+
.messages({
31+
[BEAM_TYPE_INVALID]: '{{#message}}',
32+
'string.base': 'Beam type must be a string',
33+
}),
2734
});

lib/public/components/Filters/LhcFillsFilter/BeamTypeFilterModel.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class BeamTypeFilterModel extends SelectionFilterModel {
2222
* Constructor
2323
*/
2424
constructor() {
25-
super({ multiple: true, allowEmpty: true });
25+
super({});
2626

2727
beamTypesProvider.items$.observe(() => {
2828
beamTypesProvider.items$.getCurrent().apply({

lib/public/views/LhcFills/ActiveColumns/lhcFillsActiveColumns.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export const lhcFillsActiveColumns = {
163163
visible: true,
164164
size: 'w-8',
165165
format: (value) => formatBeamType(value),
166-
filter: (lhcFillModel) => beamTypeFilter(lhcFillModel.filteringModel.get('beamType')),
166+
filter: (lhcFillModel) => beamTypeFilter(lhcFillModel.filteringModel.get('beamTypes')),
167167
},
168168
collidingBunches: {
169169
name: 'Colliding bunches',

lib/public/views/LhcFills/Overview/LhcFillsOverviewModel.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export class LhcFillsOverviewModel extends OverviewPageModel {
3939
beamDuration: new TextComparisonFilterModel(),
4040
runDuration: new TextComparisonFilterModel(),
4141
hasStableBeams: new StableBeamFilterModel(),
42-
beamType: new BeamTypeFilterModel(),
42+
beamTypes: new BeamTypeFilterModel(),
4343
schemeName: new RawTextFilterModel(),
4444
});
4545

lib/usecases/lhcFill/GetAllLhcFillsUseCase.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class GetAllLhcFillsUseCase {
4747
let associatedStatisticsRequired = false;
4848

4949
if (filter) {
50-
const { hasStableBeams, fillNumbers, schemeName, beamDuration, runDuration, beamType } = filter;
50+
const { hasStableBeams, fillNumbers, schemeName, beamDuration, runDuration, beamTypes } = filter;
5151
if (hasStableBeams) {
5252
// For now, if a stableBeamsStart is present, then a beam is stable
5353
queryBuilder.where('stableBeamsStart').not().is(null);
@@ -65,10 +65,6 @@ class GetAllLhcFillsUseCase {
6565
}
6666
}
6767

68-
if (schemeName) {
69-
queryBuilder.where('filling_scheme_name').substring(schemeName);
70-
}
71-
7268
if (runDuration?.limit !== undefined && runDuration?.operator) {
7369
associatedStatisticsRequired = true;
7470
// 00:00:00 aka 0 value is saved in the DB as null (bookkeeping.fill_statistics.runs_coverage)
@@ -89,9 +85,14 @@ class GetAllLhcFillsUseCase {
8985
queryBuilder.where('stableBeamsDuration').applyOperator(beamDuration.operator, beamDuration.limit);
9086
}
9187

92-
if (beamType) {
93-
const beamTypes = beamType.split(',');
94-
queryBuilder.where('beamType').oneOf(beamTypes);
88+
if (beamTypes) {
89+
const beamTypesArray = beamTypes.split(',');
90+
queryBuilder.where('beamType').oneOf(beamTypesArray);
91+
}
92+
93+
94+
if (schemeName) {
95+
queryBuilder.where('filling_scheme_name').substring(schemeName);
9596
}
9697
}
9798

lib/utilities/beamTypeUtils.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* @license
3+
* Copyright CERN and copyright holders of ALICE O2. This software is
4+
* distributed under the terms of the GNU General Public License v3 (GPL
5+
* Version 3), copied verbatim in the file "COPYING".
6+
*
7+
* See http://alice-o2.web.cern.ch/license for full licensing information.
8+
*
9+
* In applying this license CERN does not waive the privileges and immunities
10+
* granted to it by virtue of its status as an Intergovernmental Organization
11+
* or submit itself to any jurisdiction.
12+
*/
13+
14+
export const BEAM_TYPE_INVALID = 'beamType.invalid';
15+
16+
/**
17+
* Validates beam types to have correct format
18+
* Expects a string containing comma separated values.
19+
*
20+
* @param {string} value Beam types string to validate
21+
* @param {*} helpers The helpers object
22+
* @returns {string} The value if validation passes
23+
*/
24+
export const validateBeamTypes = (value, helpers) => {
25+
const beamTypes = value.split(',');
26+
27+
for (const type of beamTypes) {
28+
// Max length accepted is 15 characters including spaces (e.g. "PROTON - PROTON")
29+
if (type.length > 15) {
30+
return helpers.error(BEAM_TYPE_INVALID, {
31+
message: `Beam type exceeds max length of 15 characters: ${type}`,
32+
});
33+
}
34+
35+
/*
36+
* Accepts combinations of letters and numbers separated by a hyphen, with optional spaces
37+
* around the hyphen (e.g. "PROTON-PROTON", "PROTON - PROTON", "P1-P2")
38+
*/
39+
if (!/^[A-Za-z0-9]+ ?- ?[A-Za-z0-9]+$/.test(type)) {
40+
return helpers.error(BEAM_TYPE_INVALID, {
41+
message: `Invalid beam type format: ${type}`,
42+
});
43+
}
44+
}
45+
46+
return value;
47+
};

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"chai": "4.5.0",
5656
"date-and-time": "3.6.0",
5757
"eslint": "^9.37.0",
58-
"eslint-plugin-jsdoc": "^62.4.1",
58+
"eslint-plugin-jsdoc": "^62.5.0",
5959
"globals": "^17.3.0",
6060
"js-yaml": "4.1.1",
6161
"mocha": "11.7.0",

test/api/lhcFills.test.js

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ module.exports = () => {
522522

523523
it('should return 200 and an LHCFill array for beam types filter, correct', (done) => {
524524
request(server)
525-
.get('/api/lhcFills?page[offset]=0&page[limit]=15&filter[beamType]=Pb-Pb')
525+
.get('/api/lhcFills?page[offset]=0&page[limit]=15&filter[beamTypes]=Pb-Pb')
526526
.expect(200)
527527
.end((err, res) => {
528528
if (err) {
@@ -539,7 +539,7 @@ module.exports = () => {
539539

540540
it('should return 200 and an LHCFill array for beam types filter, multiple correct', (done) => {
541541
request(server)
542-
.get('/api/lhcFills?page[offset]=0&page[limit]=15&filter[beamType]=Pb-Pb,p-p,p-Pb')
542+
.get('/api/lhcFills?page[offset]=0&page[limit]=15&filter[beamTypes]=Pb-Pb,p-p,p-Pb')
543543
.expect(200)
544544
.end((err, res) => {
545545
if (err) {
@@ -557,7 +557,7 @@ module.exports = () => {
557557
// API accepts filters that do not exist, this is because it does not affect the results
558558
it('should return 200 for beam types filter, one wrong', (done) => {
559559
request(server)
560-
.get('/api/lhcFills?page[offset]=0&page[limit]=15&filter[beamType]=Pb-Pb,Hello-World,p-p,p-Pb')
560+
.get('/api/lhcFills?page[offset]=0&page[limit]=15&filter[beamTypes]=Pb-Pb,Hello-World,p-p,p-Pb')
561561
.expect(200)
562562
.end((err, res) => {
563563
if (err) {
@@ -574,7 +574,7 @@ module.exports = () => {
574574

575575
it('should return 200 and an empty LHC Fill array for beam types filter that does not exist', (done) => {
576576
request(server)
577-
.get('/api/lhcFills?page[offset]=0&page[limit]=15&filter[beamType]=Hello-World')
577+
.get('/api/lhcFills?page[offset]=0&page[limit]=15&filter[beamTypes]=Hello-World')
578578
.expect(200)
579579
.end((err, res) => {
580580
if (err) {
@@ -589,7 +589,7 @@ module.exports = () => {
589589

590590
it('should return 400 for beam types filter that is empty', (done) => {
591591
request(server)
592-
.get('/api/lhcFills?page[offset]=0&page[limit]=15&filter[beamType]=')
592+
.get('/api/lhcFills?page[offset]=0&page[limit]=15&filter[beamTypes]=')
593593
.expect(400)
594594
.end((err, res) => {
595595
if (err) {
@@ -599,7 +599,28 @@ module.exports = () => {
599599

600600
const { errors: [error] } = res.body;
601601
expect(error.title).to.equal('Invalid Attribute');
602-
expect(error.detail).to.equal('"query.filter.beamType" is not allowed to be empty');
602+
expect(error.detail).to.equal('"query.filter.beamTypes" is not allowed to be empty');
603+
done();
604+
});
605+
});
606+
607+
it('should return 200 for beam types with correct values', (done) => {
608+
request(server)
609+
.get('/api/lhcFills/beamTypes')
610+
.expect(200)
611+
.end((err, res) => {
612+
if (err) {
613+
done(err);
614+
return;
615+
}
616+
617+
expect(res.body.data).to.deep.equal([
618+
{ beam_type: 'p-p' },
619+
{ beam_type: 'p-Pb' },
620+
{ beam_type: 'Pb-Pb' },
621+
{ beam_type: 'PROTON-PROTON' },
622+
]);
623+
603624
done();
604625
});
605626
});

0 commit comments

Comments
 (0)