Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/domain/dtos/filters/LhcFillsFilterDto.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const Joi = require('joi');
const { validateRange, RANGE_INVALID } = require('../../../utilities/rangeUtils');
const { validateBeamTypes, BEAM_TYPE_INVALID } = require('../../../utilities/beamTypeUtils');
const { validateTimeDuration } = require('../../../utilities/validateTime');
const { FromToFilterDto } = require('./FromToFilterDto.js');

exports.LhcFillsFilterDto = Joi.object({
hasStableBeams: Joi.boolean(),
Expand All @@ -23,6 +24,8 @@ exports.LhcFillsFilterDto = Joi.object({
}),
runDuration: validateTimeDuration,
beamDuration: validateTimeDuration,
stableBeamsStart: FromToFilterDto,
stableBeamsEnd: FromToFilterDto,
schemeName: Joi.string().trim().max(64),
beamTypes: Joi.string()
.trim()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { fillNumberFilter } from '../../../components/Filters/LhcFillsFilter/fil
import { durationFilter } from '../../../components/Filters/LhcFillsFilter/durationFilter.js';
import { beamTypeFilter } from '../../../components/Filters/LhcFillsFilter/beamTypeFilter.js';
import { schemeNameFilter } from '../../../components/Filters/LhcFillsFilter/schemeNameFilter.js';
import { timeRangeFilter } from '../../../components/Filters/common/filters/timeRangeFilter.js';

/**
* List of active columns for a lhc fills table
Expand Down Expand Up @@ -65,6 +66,14 @@ export const lhcFillsActiveColumns = {
visible: true,
size: 'w-8',
format: (timestamp) => formatTimestamp(timestamp, false),

/**
* Stable Beam start filter component
*
* @param {RunsOverviewModel} lhcFillsOverviewModel the lhcFills overview model
* @return {Component} the filter component
*/
filter: (lhcFillsOverviewModel) => timeRangeFilter(lhcFillsOverviewModel.filteringModel.get('stableBeamsStart').timeRangeInputModel),
profiles: {
lhcFill: true,
environment: true,
Expand All @@ -80,6 +89,14 @@ export const lhcFillsActiveColumns = {
visible: true,
size: 'w-8',
format: (timestamp) => formatTimestamp(timestamp, false),

/**
* Stable Beam end filter component
*
* @param {LhcFillsOverviewModel} lhcFillsOverviewModel the lhcFills overview model
* @return {Component} the filter component
*/
filter: (lhcFillsOverviewModel) => timeRangeFilter(lhcFillsOverviewModel.filteringModel.get('stableBeamsEnd').timeRangeInputModel),
profiles: {
lhcFill: true,
environment: true,
Expand Down
3 changes: 3 additions & 0 deletions lib/public/views/LhcFills/Overview/LhcFillsOverviewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { OverviewPageModel } from '../../../models/OverviewModel.js';
import { addStatisticsToLhcFill } from '../../../services/lhcFill/addStatisticsToLhcFill.js';
import { BeamTypeFilterModel } from '../../../components/Filters/LhcFillsFilter/BeamTypeFilterModel.js';
import { TextComparisonFilterModel } from '../../../components/Filters/common/filters/TextComparisonFilterModel.js';
import { TimeRangeFilterModel } from '../../../components/Filters/RunsFilter/TimeRangeFilter.js';

/**
* Model for the LHC fills overview page
Expand All @@ -39,6 +40,8 @@ export class LhcFillsOverviewModel extends OverviewPageModel {
beamDuration: new TextComparisonFilterModel(),
runDuration: new TextComparisonFilterModel(),
hasStableBeams: new StableBeamFilterModel(),
stableBeamsStart: new TimeRangeFilterModel(),
stableBeamsEnd: new TimeRangeFilterModel(),
beamTypes: new BeamTypeFilterModel(),
schemeName: new RawTextFilterModel(),
});
Expand Down
14 changes: 13 additions & 1 deletion lib/usecases/lhcFill/GetAllLhcFillsUseCase.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,24 @@ class GetAllLhcFillsUseCase {
let associatedStatisticsRequired = false;

if (filter) {
const { hasStableBeams, fillNumbers, schemeName, beamDuration, runDuration, beamTypes } = filter;
const { hasStableBeams, fillNumbers, schemeName, beamDuration, stableBeamsStart, stableBeamsEnd, runDuration, beamTypes } = filter;
if (hasStableBeams) {
// For now, if a stableBeamsStart is present, then a beam is stable
queryBuilder.where('stableBeamsStart').not().is(null);
}

if (stableBeamsStart) {
const from = stableBeamsStart.from !== undefined ? stableBeamsStart.from : 0;
const to = stableBeamsStart.to !== undefined ? stableBeamsStart.to : new Date().getTime();
queryBuilder.where('stableBeamsStart').between(from, to);
}

if (stableBeamsEnd) {
const from = stableBeamsEnd.from !== undefined ? stableBeamsEnd.from : 0;
const to = stableBeamsEnd.to !== undefined ? stableBeamsEnd.to : new Date().getTime();
queryBuilder.where('stableBeamsEnd').between(from, to);
}

if (fillNumbers) {
const fillNumberCriteria = splitStringToStringsTrimmed(fillNumbers, SEARCH_ITEMS_SEPARATOR);

Expand Down
56 changes: 56 additions & 0 deletions test/lib/usecases/lhcFill/GetAllLhcFillsUseCase.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,4 +317,60 @@ module.exports = () => {

expect(lhcFills).to.be.an('array').and.lengthOf(0)
})

it('should return an array with only \'from\' values given', async () => {
getAllLhcFillsDto.query = {
filter: {
stableBeamsStart: {
from: 1647867600000,
},
stableBeamsEnd: {
from: 1647867600000,
},
},
};

const { lhcFills } = await new GetAllLhcFillsUseCase().execute(getAllLhcFillsDto);

expect(lhcFills).to.be.an('array');
expect(lhcFills).to.have.lengthOf(3);
});

it('should return an array with only \'to\' values given', async () => {
getAllLhcFillsDto.query = {
filter: {
stableBeamsStart: {
to: 2000000000000
},
stableBeamsEnd: {
to: 2000000000000
},
},
};

const { lhcFills } = await new GetAllLhcFillsUseCase().execute(getAllLhcFillsDto);

expect(lhcFills).to.be.an('array');
expect(lhcFills).to.have.lengthOf(4);
});

it('should return an array with fills on certain timestamps', async () => {
getAllLhcFillsDto.query = {
filter: {
stableBeamsStart: {
from: 1647867600000,
to: 1647867600000,
},
stableBeamsEnd: {
from: 1647961200000,
to: 1647961200000,
},
},
};

const { lhcFills } = await new GetAllLhcFillsUseCase().execute(getAllLhcFillsDto);

expect(lhcFills).to.be.an('array');
expect(lhcFills).to.have.lengthOf(3);
});
};
90 changes: 81 additions & 9 deletions test/public/lhcFills/overview.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const {
openFilteringPanel,
expectAttributeValue,
fillInput,
getPeriodInputsSelectors,
getPopoverSelector,
} = require('../defaults.js');
const { resetDatabaseContent } = require('../../utilities/resetDatabaseContent.js');

Expand Down Expand Up @@ -161,16 +163,19 @@ module.exports = () => {
});

it('fill dropdown menu should be correct', async() => {
// activate the popover
await pressElement(page, `#row6-fillNumber-text > div:nth-child(1) > div:nth-child(2)`)
await page.waitForSelector(`body > div:nth-child(3) > div:nth-child(1)`);
await expectInnerText(page, `#copy-6 > div:nth-child(1)`, 'Copy Fill Number')
const popoverTrigger = '#row6-fillNumber-text > div:nth-child(1) > div:nth-child(2)';

await expectLink(page, 'body > div:nth-child(4) > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > a:nth-child(3)', {
await pressElement(page, popoverTrigger);
await expectInnerText(page, '#copy-6 > div:nth-child(1)', 'Copy Fill Number');

const popoverSelector = await getPopoverSelector(await page.waitForSelector(popoverTrigger));


await expectLink(page, `${popoverSelector} a:nth-of-type(2)`, {
href: `http://localhost:4000/?page=log-create&lhcFillNumbers=6`, innerText: ' Add log to this fill'
})
// disable the popover
await pressElement(page, `#row6-fillNumber-text > div:nth-child(1) > div:nth-child(2)`)
await pressElement(page, popoverTrigger)
})

it('can set how many lhcFills are available per page', async () => {
Expand Down Expand Up @@ -272,12 +277,14 @@ module.exports = () => {
it('should successfully display filter elements', async () => {
const filterSBExpect = { selector: '.stableBeams-filter .w-30', value: 'Stable Beams Only' };
const filterFillNRExpect = {selector: 'div.items-baseline:nth-child(1) > div:nth-child(1)', value: 'Fill #'};
const filterSBDurationExpect = {selector: 'div.items-baseline:nth-child(3) > div:nth-child(1)', value: 'SB Duration'};
const filterSBStartExpect = {selector: 'div.items-baseline:nth-child(2) > div:nth-child(1)', value: 'SB START'};
const filterSBEndExpect = {selector: 'div.items-baseline:nth-child(3) > div:nth-child(1)', value: 'SB END'};
const filterSBDurationExpect = {selector: 'div.items-baseline:nth-child(5) > div:nth-child(1)', value: 'SB Duration'};
const filterSBDurationPlaceholderExpect = {selector: '#beam-duration-filter-operand', value: 'e.g 16:14:15 (HH:MM:SS)'}
const filterRunDurationExpect = {selector: 'div.flex-row:nth-child(4) > div:nth-child(1)', value: 'Total runs duration'}
const filterRunDurationExpect = {selector: 'div.flex-row:nth-child(6) > div:nth-child(1)', value: 'Total runs duration'}
const filterRunDurationPlaceholderExpect = {selector: '#run-duration-filter-operand', value: 'e.g 16:14:15 (HH:MM:SS)'};
const filterSBDurationOperatorExpect = { value: true };
const filterBeamTypeExpect = {selector: 'div.flex-row:nth-child(5) > div:nth-child(1)', value: 'Beam Type'}
const filterBeamTypeExpect = {selector: 'div.flex-row:nth-child(7) > div:nth-child(1)', value: 'Beam Type'}
const filterSchemeNamePlaceholderExpect = {selector: '.fillingSchemeName-filter input', value: 'e.g. Single_12b_8_1024_8_2018'}

await goToPage(page, 'lhc-fill-overview');
Expand All @@ -287,6 +294,8 @@ module.exports = () => {
expect(await page.evaluate(() => document.querySelector('#beam-duration-filter-operator > option:nth-child(3)').selected)).to.equal(filterSBDurationOperatorExpect.value);
await expectInnerText(page, filterSBExpect.selector, filterSBExpect.value);
await expectInnerText(page, filterFillNRExpect.selector, filterFillNRExpect.value);
await expectInnerText(page, filterSBStartExpect.selector, filterSBStartExpect.value);
await expectInnerText(page, filterSBEndExpect.selector, filterSBEndExpect.value);
await expectInnerText(page, filterSBDurationExpect.selector, filterSBDurationExpect.value);
await expectAttributeValue(page, filterSBDurationPlaceholderExpect.selector, 'placeholder', filterSBDurationPlaceholderExpect.value);
await expectInnerText(page, filterRunDurationExpect.selector, filterRunDurationExpect.value);
Expand Down Expand Up @@ -354,6 +363,69 @@ module.exports = () => {
await waitForTableLength(page, 2);
});

it('should successfully apply stableBeamStart filter', async () => {
const popoverTrigger = '.stableBeamsStart-filter .popover-trigger';

await goToPage(page, 'lhc-fill-overview');
await waitForTableLength(page, 5);
await page.waitForSelector('.column-stableBeamsStart');

const filterButton = await page.waitForSelector('#openFilterToggle');
const popoverKey = await filterButton.evaluate((button) => {
return button.parentElement.getAttribute('data-popover-key');
});

const filterPanelSelector = `.popover[data-popover-key="${popoverKey}"]`;

await openFilteringPanel(page);
await page.waitForSelector(filterPanelSelector, { visible: true });
await page.waitForSelector(popoverTrigger);

const popOverSelector = await getPopoverSelector(await page.$(popoverTrigger));
const { fromDateSelector, toDateSelector, fromTimeSelector, toTimeSelector } = getPeriodInputsSelectors(popOverSelector);
console.log({ fromDateSelector, toDateSelector, fromTimeSelector, toTimeSelector });


await fillInput(page, fromDateSelector, '2019-08-08', ['change']);
await fillInput(page, toDateSelector, '2019-08-08', ['change']);
await fillInput(page, fromTimeSelector, '10:00', ['change']);
await fillInput(page, toTimeSelector, '12:00', ['change']);

await openFilteringPanel(page);
await pressElement(page, popoverTrigger);
await waitForTableLength(page, 1);
});

it('should successfully apply stableBeamEnd filter', async () => {
const popoverTrigger = '.stableBeamsEnd-filter .popover-trigger';

await goToPage(page, 'lhc-fill-overview');
await waitForTableLength(page, 5);
await page.waitForSelector('.column-stableBeamsEnd');

const filterButton = await page.waitForSelector('#openFilterToggle');
const popoverKey = await filterButton.evaluate((button) => {
return button.parentElement.getAttribute('data-popover-key');
});

const filterPanelSelector = `.popover[data-popover-key="${popoverKey}"]`;

await openFilteringPanel(page);
await page.waitForSelector(filterPanelSelector, { visible: true });
await page.waitForSelector(popoverTrigger);

const popOverSelector = await getPopoverSelector(await page.$(popoverTrigger));
const { fromDateSelector, toDateSelector, fromTimeSelector, toTimeSelector } = getPeriodInputsSelectors(popOverSelector);

await fillInput(page, fromDateSelector, '2022-03-22', ['change']);
await fillInput(page, toDateSelector, '2022-03-22', ['change']);
await fillInput(page, fromTimeSelector, '01:00', ['change']);
await fillInput(page, toTimeSelector, '23:59', ['change']);
await openFilteringPanel(page);
await pressElement(page, popoverTrigger);
await waitForTableLength(page, 3);
});

it('should successfully apply scheme name filter', async () => {
const filterSchemeNameInputField= '.fillingSchemeName-filter input';
await goToPage(page, 'lhc-fill-overview');
Expand Down