From 2c5fdf50ba659297258b99da2b0383770946a10e Mon Sep 17 00:00:00 2001 From: Ehevi Date: Fri, 22 Sep 2023 13:59:48 +0200 Subject: [PATCH 01/20] Add esm-wallaby to devDependencies --- .sequelizerc | 9 --------- package-lock.json | 10 ++++++++++ package.json | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) delete mode 100644 .sequelizerc diff --git a/.sequelizerc b/.sequelizerc deleted file mode 100644 index b0312fdc5..000000000 --- a/.sequelizerc +++ /dev/null @@ -1,9 +0,0 @@ - -const path = require('path'); - -module.exports = { - 'config': path.resolve('app', 'config', 'database.js'), - 'models-path': path.resolve('app', 'lib', 'database', 'models'), - 'seeders-path': path.resolve('app', 'lib', 'database', 'seeders'), - 'migrations-path': path.resolve('app', 'lib', 'database', 'migrations') -}; diff --git a/package-lock.json b/package-lock.json index 0ee4b2f6f..2310ffe78 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "chai": "^4.3.6", "eslint": "^8.49.0", "eslint-output": "^3.0.1", + "esm-wallaby": "^3.2.26", "mocha": "^10.1.0", "nodemon": "^3.0.1", "nyc": "^15.1.0", @@ -2561,6 +2562,15 @@ "node": ">=6" } }, + "node_modules/esm-wallaby": { + "version": "3.2.26", + "resolved": "https://registry.npmjs.org/esm-wallaby/-/esm-wallaby-3.2.26.tgz", + "integrity": "sha512-DtbO0pdJj7kv/abkQ1BjIpk/Rm6vy9ueGcsXuQT7jH6qw6RQby/i/qeVyIcf2pbpAT5UW8PN+dL2YZakTw+URA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", diff --git a/package.json b/package.json index 16653eafb..a51ea6555 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "chai": "^4.3.6", "eslint": "^8.49.0", "eslint-output": "^3.0.1", + "esm-wallaby": "^3.2.26", "mocha": "^10.1.0", "nodemon": "^3.0.1", "nyc": "^15.1.0", From 65e1821ae2403dd07ff9d5f79e3af9ea176e200e Mon Sep 17 00:00:00 2001 From: Ehevi Date: Fri, 22 Sep 2023 14:18:36 +0200 Subject: [PATCH 02/20] Restore .sequelizerc file --- .sequelizerc | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .sequelizerc diff --git a/.sequelizerc b/.sequelizerc new file mode 100644 index 000000000..f0fa8e328 --- /dev/null +++ b/.sequelizerc @@ -0,0 +1,8 @@ +const path = require('path'); + +module.exports = { + 'config': path.resolve('app', 'config', 'database.js'), + 'models-path': path.resolve('app', 'lib', 'database', 'models'), + 'seeders-path': path.resolve('app', 'lib', 'database', 'seeders'), + 'migrations-path': path.resolve('app', 'lib', 'database', 'migrations') +}; From 583e3417ad7bb500e1444be487945f0c17699f3c Mon Sep 17 00:00:00 2001 From: xsalonx Date: Fri, 15 Sep 2023 15:46:51 +0200 Subject: [PATCH 03/20] init --- scripts/setup-frontend-on-mocha-tests-environemt.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100755 scripts/setup-frontend-on-mocha-tests-environemt.sh diff --git a/scripts/setup-frontend-on-mocha-tests-environemt.sh b/scripts/setup-frontend-on-mocha-tests-environemt.sh new file mode 100755 index 000000000..64537ed4e --- /dev/null +++ b/scripts/setup-frontend-on-mocha-tests-environemt.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [ "$RUNNING_ENV" != 'DOCKER' ]; then + echo \ + "Warning this script is rather intended + to setup environment in docker contatiner. + If it is docker contatiner check wheter + env var RUNNING_ENV has proper value assign, + it should be 'DOCKER'"; +fi From cdfabafef2556a687f79c056d1dc70427bdfec86 Mon Sep 17 00:00:00 2001 From: xsalonx <65893715+xsalonx@users.noreply.github.com> Date: Mon, 18 Sep 2023 11:09:53 +0200 Subject: [PATCH 04/20] allow command injection to coverage task --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a51ea6555..e2c3f58e5 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "eslint:show:linux": "npm run eslint; firefox ./reports/static/static-analysis.html", "eslint:show:macos": "npm run eslint; open -a firefox ./reports/static/static-analysis.html", "static": "npm run eslint", - "coverage:test": "mocha --exit test/* $MOCHA_OPTIONS", + "coverage:test": "bash -c \"$( echo \"mocha --exit test/* $MOCHA_OPTIONS\" )\" ", "coverage:report": "nyc report --report=html --report=json", "coverage": "nyc npm run coverage:test && npm run coverage:report", "start:test": "npm run coverage", From 40a8a5adfcaba20f05b75f9ce408adc8e92c9eec Mon Sep 17 00:00:00 2001 From: xsalonx <65893715+xsalonx@users.noreply.github.com> Date: Mon, 18 Sep 2023 11:10:47 +0200 Subject: [PATCH 05/20] mockup of renderers --- ...etup-frontend-on-mocha-tests-environemt.sh | 21 ++- scripts/web-ui-renderers.mocha.js | 156 ++++++++++++++++++ 2 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 scripts/web-ui-renderers.mocha.js diff --git a/scripts/setup-frontend-on-mocha-tests-environemt.sh b/scripts/setup-frontend-on-mocha-tests-environemt.sh index 64537ed4e..60a7bb31a 100755 --- a/scripts/setup-frontend-on-mocha-tests-environemt.sh +++ b/scripts/setup-frontend-on-mocha-tests-environemt.sh @@ -2,9 +2,24 @@ if [ "$RUNNING_ENV" != 'DOCKER' ]; then echo \ - "Warning this script is rather intended - to setup environment in docker contatiner. - If it is docker contatiner check wheter + "Warning this script is intended + to setup environment in docker container. + If it is docker container check whether env var RUNNING_ENV has proper value assign, it should be 'DOCKER'"; + exit 1; fi + + +NODE_MODULES_DIR_PATH=${1:-$(dirname $0)/../node_modules} +if [ -n "$NODE_MODULES_DIR_PATH" ]; then + echo "Path to node_modules not specified, it must be given as first argument"; +fi + +FRONTEND_DIR="$NODE_MODULES_DIR_PATH/\@aliceo2/web-ui/Frontend/"; + +FILE_TO_BE_REPLACED_PATH="/js/src/renderer.js"; +SRC_MOCHA_CODE=$(dirname $0)/web-ui-renderers.mocha.js; + +cp -r $FRONTEND_DIR/js /js; +cp $SRC_MOCHA_CODE $FILE_TO_BE_REPLACED_PATH; diff --git a/scripts/web-ui-renderers.mocha.js b/scripts/web-ui-renderers.mocha.js new file mode 100644 index 000000000..68ad71338 --- /dev/null +++ b/scripts/web-ui-renderers.mocha.js @@ -0,0 +1,156 @@ +/** + * @license + * Copyright 2019-2020 CERN and copyright holders of ALICE O2. + * See http://alice-o2.web.cern.ch/copyright for details of the copyright holders. + * All rights not expressly granted are reserved. + * + * This software is distributed under the terms of the GNU General Public + * License v3 (GPL Version 3), copied verbatim in the file "COPYING". + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. +*/ + +/** + * Template engine functions using vnode and DOM diff algo + * @module renderer + */ + +// mithril function 'm' will be injected into window +// it is used by renderer as an abstracted engine +// import '/mithril/mithril.min.js'; + +// if (!window.m) { +// throw new Error('mithril must be loaded into window'); +// } +// if (!window.requestAnimationFrame) { +// throw new Error('renderer must be run inside a browser envirnnement'); +// } + +/** + * Register a callback to be called one time at browser render time if + * the trigger was called before. Used to push new renderings efficitly. + * @param {function} fn - The callback to be registered + * @return {function} The trigger to be called + */ +function frameDebouncer(fn) { + return function(...args) { + // if (requestFrame) { + // window.cancelAnimationFrame(requestFrame); + // } + // requestFrame = window.requestAnimationFrame(function() { + return fn(...args); + // }); + }; +} + +/** + * Renders a vnode tree inside the dom element. + * @param {Element} element - the dom element + * @param {vnode} vnode - the vnode tree + * @example + * import {h, render} from '/js/src/index.js'; + * let virtualNode = h('h1.title', 'World'); + * render(document.body, virtualNode); + */ +function render(element, vnode) { + // encapsulate mithril engine so we can change if needed +// window.m.render(element, vnode); +} + +/** + * This callback type is a Hook. + * Hooks are lifecycle methods of vnodes. + * They are only called as a side effect of template engine (`render` or `mount`). + * Properties of vnode argument must not be used, except `dom`. + * It's very useful to connect with another template engine like a chart lib or a canvas. + * Don't forget to remove any link to DOM element when `onremove` is called to avoid memory leaks. + * + * @callback Hook + * @param {Object} vnode + * @param {DOMElement} vnode.dom - DOM element you can access + */ + +/** + * Hyperscript function to represente a DOM element + * it produces a vnode usable by render function. + * + * @param {String} selector - Tag name (div, p, h1...) and optional classes as CSS selector (.foo.bar.baz), empty string =~ 'div' + * @param {Object} attributes - (optional) Properties and attributes of DOM elements and hooks (see description). Here is a non-exhaustive list of common uses: + * @param {string} attributes.className - Additional class names + * @param {function} attributes.onclick - On mouse click [DOM handler onclick](https://developer.mozilla.org/fr/docs/Web/API/GlobalEventHandlers/onclick) + * @param {function} attributes.oninput - On content typed inside input tag [DOM handler oninput](https://developer.mozilla.org/fr/docs/Web/API/GlobalEventHandlers/oninput) + * @param {string|Object} attributes.style - `style: "background:red;"` or `style: {background: "red"}` + * @param {string} attributes.href - Destination for links [DOM href property](https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/href) + * @param {string} attributes.placeholder - Placeholder for inputs [DOM input, all properties](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) + * @param {string} attributes.value - Value for inputs [DOM input, all properties](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) + * @param {Hook} attributes.oncreate - Hook called after a DOM element is created and attached to the document + * @param {Hook} attributes.onupdate - Hook is called after each render, while DOM element is attached to the document + * @param {Hook} attributes.onremove - Hook is called before a DOM element is removed from the document + * @param {Array.|string} children - Children inside this tag + * @return {vnode} the vnode representation + * @example Simple tag declaration + * import {h, render} from '/js/src/index.js'; + * const virtualNode1 = h('h1.text-center', 'World'); + * render(document.body, virtualNode1); + * @example Usage of click and hooks + * import {h, render} from '/js/src/index.js'; + * const virtualNode1 = h('h1.text-center', 'World'); + * const virtualNode2 = h('h1.text-center', {className: 'primary'}, 'World'); + * const virtualNode3 = h('h1', {onclick: () => console.log('clicked')}, 'World'); + * const chart = h('div', { + * oncreate: (vnode) => chartlib.attachTo(vnode.dom), + * onremove: (vnode) => chartlib.detachFrom(vnode.dom) + * }); + * const containerNode = h('div', [ + * virtualNode1, + * virtualNode2, + * virtualNode3, + * chart + * ]); + * render(document.body, containerNode); + */ +function h(...args) { + // encapsulate mithril engine so we can change if needed +// return window.m(...args); +} + +/** + * Bind together a model and a view to render both on a DOM element. + * When the model change and is an `Observable`, view refresh by itself (unlike `render()`) + * @param {Element} element - The DOM element + * @param {Function} view - The functional view which produces a vnode tree + * @param {Observable} model - The model containing the state + * @param {boolean} debug - Facultative. Shows the rendering time each time + * @example + * import {h, mount, Observable} from '/js/src/index.js'; + * const model = new Observable(); + * const view = (model) => h('h1.title', `hello ${model.name}`); + * mount(document.body, view, model); + * model.name = 'Joueur du Grenier'; + * model.notify(); + */ +function mount(element, view, model, debug) { + const smartRender = frameDebouncer((model) => { + if (debug) { + // eslint-disable-next-line no-console + console.time('render'); + } + try { + render(element, view(model)); + } finally { + if (debug) { + // eslint-disable-next-line no-console + console.timeEnd('render'); + } + } + }); + + if (model.observe) { + model.observe(smartRender); // redraw on changes + } + render(element, view(model)); // first draw +} + +export {h, render, frameDebouncer, mount}; From da2a00887726941e449c93b31724929a07d62ec9 Mon Sep 17 00:00:00 2001 From: xsalonx <65893715+xsalonx@users.noreply.github.com> Date: Mon, 18 Sep 2023 13:38:23 +0200 Subject: [PATCH 06/20] defined procedure for serving forntend files to mocha on backend --- ...etup-frontend-on-mocha-tests-environemt.sh | 35 +++- scripts/web-ui-renderers.mocha.js | 156 ------------------ 2 files changed, 30 insertions(+), 161 deletions(-) delete mode 100644 scripts/web-ui-renderers.mocha.js diff --git a/scripts/setup-frontend-on-mocha-tests-environemt.sh b/scripts/setup-frontend-on-mocha-tests-environemt.sh index 60a7bb31a..7a6a11ba4 100755 --- a/scripts/setup-frontend-on-mocha-tests-environemt.sh +++ b/scripts/setup-frontend-on-mocha-tests-environemt.sh @@ -11,15 +11,40 @@ if [ "$RUNNING_ENV" != 'DOCKER' ]; then fi -NODE_MODULES_DIR_PATH=${1:-$(dirname $0)/../node_modules} -if [ -n "$NODE_MODULES_DIR_PATH" ]; then +NODE_MODULES_DIR_PATH=${1:-$(dirname $(realpath $0) )/../node_modules} +if [ -z "$NODE_MODULES_DIR_PATH" ]; then echo "Path to node_modules not specified, it must be given as first argument"; fi -FRONTEND_DIR="$NODE_MODULES_DIR_PATH/\@aliceo2/web-ui/Frontend/"; +FRONTEND_DIR="$NODE_MODULES_DIR_PATH/@aliceo2/web-ui/Frontend/"; -FILE_TO_BE_REPLACED_PATH="/js/src/renderer.js"; SRC_MOCHA_CODE=$(dirname $0)/web-ui-renderers.mocha.js; + + +NODEJS_WINDOW_CODE=" +// Provide pseudo window object with uploaded mithril +const m = () => ({}); +m.render = () => ({}); +const window = { + location: new URL('http://localhost:8081/?personid=0&name=_&token=_&username=_&access=_'), + history: { + replaceState: () => ({}), + }, + m, + requestAnimationFrame: () => ({}), + cancelAnimationFrame: () => ({}), +}; +" + +rm -rf /js cp -r $FRONTEND_DIR/js /js; -cp $SRC_MOCHA_CODE $FILE_TO_BE_REPLACED_PATH; + +TARGET_SRC_DIR=/js/src/ +for fp in $(ls $TARGET_SRC_DIR ); do + FPATH=$TARGET_SRC_DIR/$fp; + echo "$NODEJS_WINDOW_CODE" $'\n' "$(cat $FPATH)" > $FPATH; +done; + +FILE_TO_BE_REPLACED_PATH="/js/src/renderer.js"; +echo "$( cat "$FILE_TO_BE_REPLACED_PATH" | grep -v "import '/mithril/mithril.min.js'" )" > "$FILE_TO_BE_REPLACED_PATH"; diff --git a/scripts/web-ui-renderers.mocha.js b/scripts/web-ui-renderers.mocha.js deleted file mode 100644 index 68ad71338..000000000 --- a/scripts/web-ui-renderers.mocha.js +++ /dev/null @@ -1,156 +0,0 @@ -/** - * @license - * Copyright 2019-2020 CERN and copyright holders of ALICE O2. - * See http://alice-o2.web.cern.ch/copyright for details of the copyright holders. - * All rights not expressly granted are reserved. - * - * This software is distributed under the terms of the GNU General Public - * License v3 (GPL Version 3), copied verbatim in the file "COPYING". - * - * In applying this license CERN does not waive the privileges and immunities - * granted to it by virtue of its status as an Intergovernmental Organization - * or submit itself to any jurisdiction. -*/ - -/** - * Template engine functions using vnode and DOM diff algo - * @module renderer - */ - -// mithril function 'm' will be injected into window -// it is used by renderer as an abstracted engine -// import '/mithril/mithril.min.js'; - -// if (!window.m) { -// throw new Error('mithril must be loaded into window'); -// } -// if (!window.requestAnimationFrame) { -// throw new Error('renderer must be run inside a browser envirnnement'); -// } - -/** - * Register a callback to be called one time at browser render time if - * the trigger was called before. Used to push new renderings efficitly. - * @param {function} fn - The callback to be registered - * @return {function} The trigger to be called - */ -function frameDebouncer(fn) { - return function(...args) { - // if (requestFrame) { - // window.cancelAnimationFrame(requestFrame); - // } - // requestFrame = window.requestAnimationFrame(function() { - return fn(...args); - // }); - }; -} - -/** - * Renders a vnode tree inside the dom element. - * @param {Element} element - the dom element - * @param {vnode} vnode - the vnode tree - * @example - * import {h, render} from '/js/src/index.js'; - * let virtualNode = h('h1.title', 'World'); - * render(document.body, virtualNode); - */ -function render(element, vnode) { - // encapsulate mithril engine so we can change if needed -// window.m.render(element, vnode); -} - -/** - * This callback type is a Hook. - * Hooks are lifecycle methods of vnodes. - * They are only called as a side effect of template engine (`render` or `mount`). - * Properties of vnode argument must not be used, except `dom`. - * It's very useful to connect with another template engine like a chart lib or a canvas. - * Don't forget to remove any link to DOM element when `onremove` is called to avoid memory leaks. - * - * @callback Hook - * @param {Object} vnode - * @param {DOMElement} vnode.dom - DOM element you can access - */ - -/** - * Hyperscript function to represente a DOM element - * it produces a vnode usable by render function. - * - * @param {String} selector - Tag name (div, p, h1...) and optional classes as CSS selector (.foo.bar.baz), empty string =~ 'div' - * @param {Object} attributes - (optional) Properties and attributes of DOM elements and hooks (see description). Here is a non-exhaustive list of common uses: - * @param {string} attributes.className - Additional class names - * @param {function} attributes.onclick - On mouse click [DOM handler onclick](https://developer.mozilla.org/fr/docs/Web/API/GlobalEventHandlers/onclick) - * @param {function} attributes.oninput - On content typed inside input tag [DOM handler oninput](https://developer.mozilla.org/fr/docs/Web/API/GlobalEventHandlers/oninput) - * @param {string|Object} attributes.style - `style: "background:red;"` or `style: {background: "red"}` - * @param {string} attributes.href - Destination for links [DOM href property](https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/href) - * @param {string} attributes.placeholder - Placeholder for inputs [DOM input, all properties](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) - * @param {string} attributes.value - Value for inputs [DOM input, all properties](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) - * @param {Hook} attributes.oncreate - Hook called after a DOM element is created and attached to the document - * @param {Hook} attributes.onupdate - Hook is called after each render, while DOM element is attached to the document - * @param {Hook} attributes.onremove - Hook is called before a DOM element is removed from the document - * @param {Array.|string} children - Children inside this tag - * @return {vnode} the vnode representation - * @example Simple tag declaration - * import {h, render} from '/js/src/index.js'; - * const virtualNode1 = h('h1.text-center', 'World'); - * render(document.body, virtualNode1); - * @example Usage of click and hooks - * import {h, render} from '/js/src/index.js'; - * const virtualNode1 = h('h1.text-center', 'World'); - * const virtualNode2 = h('h1.text-center', {className: 'primary'}, 'World'); - * const virtualNode3 = h('h1', {onclick: () => console.log('clicked')}, 'World'); - * const chart = h('div', { - * oncreate: (vnode) => chartlib.attachTo(vnode.dom), - * onremove: (vnode) => chartlib.detachFrom(vnode.dom) - * }); - * const containerNode = h('div', [ - * virtualNode1, - * virtualNode2, - * virtualNode3, - * chart - * ]); - * render(document.body, containerNode); - */ -function h(...args) { - // encapsulate mithril engine so we can change if needed -// return window.m(...args); -} - -/** - * Bind together a model and a view to render both on a DOM element. - * When the model change and is an `Observable`, view refresh by itself (unlike `render()`) - * @param {Element} element - The DOM element - * @param {Function} view - The functional view which produces a vnode tree - * @param {Observable} model - The model containing the state - * @param {boolean} debug - Facultative. Shows the rendering time each time - * @example - * import {h, mount, Observable} from '/js/src/index.js'; - * const model = new Observable(); - * const view = (model) => h('h1.title', `hello ${model.name}`); - * mount(document.body, view, model); - * model.name = 'Joueur du Grenier'; - * model.notify(); - */ -function mount(element, view, model, debug) { - const smartRender = frameDebouncer((model) => { - if (debug) { - // eslint-disable-next-line no-console - console.time('render'); - } - try { - render(element, view(model)); - } finally { - if (debug) { - // eslint-disable-next-line no-console - console.timeEnd('render'); - } - } - }); - - if (model.observe) { - model.observe(smartRender); // redraw on changes - } - render(element, view(model)); // first draw -} - -export {h, render, frameDebouncer, mount}; From 85151052e780bb06c02fca16bb28ebe43c2f7f46 Mon Sep 17 00:00:00 2001 From: xsalonx <65893715+xsalonx@users.noreply.github.com> Date: Mon, 18 Sep 2023 13:39:08 +0200 Subject: [PATCH 07/20] amend import paths --- app/public/components/flags/flagsVisualization.js | 2 +- app/public/model/data/FetchedData.js | 2 +- app/public/views/flags/overview/flagsContent.js | 4 ++-- app/public/views/flags/overview/flagsPanel.js | 2 +- app/public/views/flags/overview/flagsTable.js | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/public/components/flags/flagsVisualization.js b/app/public/components/flags/flagsVisualization.js index 67c775b87..31908d198 100644 --- a/app/public/components/flags/flagsVisualization.js +++ b/app/public/components/flags/flagsVisualization.js @@ -14,7 +14,7 @@ import { h } from '/js/src/index.js'; import flagVisualization from './flagVisualization.js'; -import { RCT } from '../../../../config.js'; +import { RCT } from '../../config.js'; const { flagReasonColors } = RCT.quality; function filterDistinct(a) { diff --git a/app/public/model/data/FetchedData.js b/app/public/model/data/FetchedData.js index 659a01ec9..fe9d1ba8f 100644 --- a/app/public/model/data/FetchedData.js +++ b/app/public/model/data/FetchedData.js @@ -14,7 +14,7 @@ const defaultPageNumber = 1; -import { RCT } from '../../../config.js'; +import { RCT } from '../../config.js'; import { shouldDisplayDetectorField } from '../../utils/dataProcessing/dataProcessingUtils.js'; const DRF = RCT.dataResponseFields; diff --git a/app/public/views/flags/overview/flagsContent.js b/app/public/views/flags/overview/flagsContent.js index 51cf2cf24..11a43e703 100644 --- a/app/public/views/flags/overview/flagsContent.js +++ b/app/public/views/flags/overview/flagsContent.js @@ -15,8 +15,8 @@ import { h } from '/js/src/index.js'; import flagsVisualization from '../../../components/flags/flagsVisualization.js'; import flagsTable from './flagsTable.js'; -import flagBreadCrumbs from '../../../../components/flags/flagBreadcrumbs.js'; -import { noRunNumbers } from '../../../../utils/defaults.js'; +import flagBreadCrumbs from '../../../components/flags/flagBreadcrumbs.js'; +import { noRunNumbers } from '../../../utils/defaults.js'; import noSubPageSelected from '../../userView/data/table/noSubPageSelected.js'; import dataActionButtons, { dataActions } from '../../../components/buttons/dataActionButtons.js'; diff --git a/app/public/views/flags/overview/flagsPanel.js b/app/public/views/flags/overview/flagsPanel.js index d47204ed9..ae5f560bc 100644 --- a/app/public/views/flags/overview/flagsPanel.js +++ b/app/public/views/flags/overview/flagsPanel.js @@ -12,7 +12,7 @@ * or submit itself to any jurisdiction. */ -import { noRunNumbers } from '../../../../utils/defaults.js'; +import { noRunNumbers } from '../../../utils/defaults.js'; import noSubPageSelected from '../../userView/data/table/noSubPageSelected.js'; import flagsContent from './flagsContent.js'; diff --git a/app/public/views/flags/overview/flagsTable.js b/app/public/views/flags/overview/flagsTable.js index c858409d3..de014f35a 100644 --- a/app/public/views/flags/overview/flagsTable.js +++ b/app/public/views/flags/overview/flagsTable.js @@ -13,7 +13,7 @@ */ import { h } from '/js/src/index.js'; -import { RCT } from '../../../../config.js'; +import { RCT } from '../../../config.js'; import flagsTableHeader from '../table/flagsTableHeader.js'; import flagsTableRow from '../table/flagsTableRow.js'; import pagesCellsSpecials from '../../userView/data/pagesCellsSpecials.js'; From f2f3a61928db59292ad7b4c855847865792d9516 Mon Sep 17 00:00:00 2001 From: xsalonx <65893715+xsalonx@users.noreply.github.com> Date: Mon, 18 Sep 2023 13:39:56 +0200 Subject: [PATCH 08/20] add exemplary test --- test/public/index.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/public/index.js b/test/public/index.js index 1cf988e4a..92d42dfd1 100644 --- a/test/public/index.js +++ b/test/public/index.js @@ -15,8 +15,16 @@ const UtilitiesSuite = require('./utils'); const ComponentsSuite = require('./components'); const PeriodsSuite = require('./periods'); +const assert = require('assert'); + module.exports = () => { describe('Components', ComponentsSuite); describe('Utilities', UtilitiesSuite); describe('Periods', PeriodsSuite); + describe('EXPERIMENT', () => { + it('should import frontend dependencies with path /js/src/index.js', () => { + assert.doesNotThrow(() => require('esm-wallaby')(module)('../../app/public/view.js')); + assert.doesNotThrow(() => require('esm-wallaby')(module)('../../app/public/Model.js')); + }); + }); }; From a563910e23fee6823cf2e06169ee6aef032a724b Mon Sep 17 00:00:00 2001 From: xsalonx <65893715+xsalonx@users.noreply.github.com> Date: Tue, 19 Sep 2023 08:53:38 +0200 Subject: [PATCH 09/20] utilize setuping script --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e2c3f58e5..f99a17b98 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "coverage:test": "bash -c \"$( echo \"mocha --exit test/* $MOCHA_OPTIONS\" )\" ", "coverage:report": "nyc report --report=html --report=json", "coverage": "nyc npm run coverage:test && npm run coverage:report", - "start:test": "npm run coverage", + "setup:test": "./scripts/setup-frontend-on-mocha-tests-environemt.sh", + "start:test": "npm run setup:test ; npm run coverage", "reports:show": "open ./reports/**/*.html", "reports:clean": "rm -rf ./reports; rm -rf .nyc_output", "start:dev": "nodemon app/main.js --watch main.js --watch app --ignore app/public", From f56b2218cba7ff8de581c98c0494c835c78423e5 Mon Sep 17 00:00:00 2001 From: xsalonx <65893715+xsalonx@users.noreply.github.com> Date: Tue, 19 Sep 2023 09:05:35 +0200 Subject: [PATCH 10/20] docs, usage --- package.json | 2 +- ...etup-frontend-on-mocha-tests-environemt.sh | 26 +++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index f99a17b98..bd8db1900 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "coverage:report": "nyc report --report=html --report=json", "coverage": "nyc npm run coverage:test && npm run coverage:report", "setup:test": "./scripts/setup-frontend-on-mocha-tests-environemt.sh", - "start:test": "npm run setup:test ; npm run coverage", + "start:test": "npm run setup:test && npm run coverage", "reports:show": "open ./reports/**/*.html", "reports:clean": "rm -rf ./reports; rm -rf .nyc_output", "start:dev": "nodemon app/main.js --watch main.js --watch app --ignore app/public", diff --git a/scripts/setup-frontend-on-mocha-tests-environemt.sh b/scripts/setup-frontend-on-mocha-tests-environemt.sh index 7a6a11ba4..a54e64372 100755 --- a/scripts/setup-frontend-on-mocha-tests-environemt.sh +++ b/scripts/setup-frontend-on-mocha-tests-environemt.sh @@ -1,12 +1,26 @@ #!/bin/bash +usage() { + cat << USAGE >&2 + +The script adjust @aliceo2/web-ui frontend dependencies +to be used within backend unit test environment with mocha. +The only and the first (optional) argument is path +to node_modules directory where the framework is installed. +It is resolved to /../node_modules by default. + +USAGE +exit 1; +} + + if [ "$RUNNING_ENV" != 'DOCKER' ]; then echo \ - "Warning this script is intended + "Warning!!! This script is intended to setup environment in docker container. - If it is docker container check whether - env var RUNNING_ENV has proper value assign, - it should be 'DOCKER'"; + If, indeed, it was an attempt to run on docker + container check whether env var RUNNING_ENV has + proper value assign, it should be 'DOCKER' "; exit 1; fi @@ -38,7 +52,9 @@ const window = { " rm -rf /js -cp -r $FRONTEND_DIR/js /js; +if ! cp -r $FRONTEND_DIR/js /js; then + usage +fi TARGET_SRC_DIR=/js/src/ for fp in $(ls $TARGET_SRC_DIR ); do From 46d2568a48c523497af2459a711c5803456d09e0 Mon Sep 17 00:00:00 2001 From: xsalonx <65893715+xsalonx@users.noreply.github.com> Date: Tue, 19 Sep 2023 17:23:22 +0200 Subject: [PATCH 11/20] tmp commit --- test/public/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/public/index.js b/test/public/index.js index 92d42dfd1..c98b10706 100644 --- a/test/public/index.js +++ b/test/public/index.js @@ -25,6 +25,6 @@ module.exports = () => { it('should import frontend dependencies with path /js/src/index.js', () => { assert.doesNotThrow(() => require('esm-wallaby')(module)('../../app/public/view.js')); assert.doesNotThrow(() => require('esm-wallaby')(module)('../../app/public/Model.js')); - }); + }).timeout(10000); }); }; From b2da056d1effa538988786552aea6fde2fd9f833 Mon Sep 17 00:00:00 2001 From: Ehevi Date: Fri, 22 Sep 2023 14:39:26 +0200 Subject: [PATCH 12/20] Add sample test --- test/public/index.js | 10 ++-------- test/public/models/FilterModel.test.js | 26 ++++++++++++++++++++++++++ test/public/models/index.js | 18 ++++++++++++++++++ 3 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 test/public/models/FilterModel.test.js create mode 100644 test/public/models/index.js diff --git a/test/public/index.js b/test/public/index.js index c98b10706..4d252f8ac 100644 --- a/test/public/index.js +++ b/test/public/index.js @@ -14,17 +14,11 @@ const UtilitiesSuite = require('./utils'); const ComponentsSuite = require('./components'); const PeriodsSuite = require('./periods'); - -const assert = require('assert'); +const ModelsSuite = require('./models'); module.exports = () => { describe('Components', ComponentsSuite); describe('Utilities', UtilitiesSuite); describe('Periods', PeriodsSuite); - describe('EXPERIMENT', () => { - it('should import frontend dependencies with path /js/src/index.js', () => { - assert.doesNotThrow(() => require('esm-wallaby')(module)('../../app/public/view.js')); - assert.doesNotThrow(() => require('esm-wallaby')(module)('../../app/public/Model.js')); - }).timeout(10000); - }); + describe('Models', ModelsSuite); }; diff --git a/test/public/models/FilterModel.test.js b/test/public/models/FilterModel.test.js new file mode 100644 index 000000000..b9de63661 --- /dev/null +++ b/test/public/models/FilterModel.test.js @@ -0,0 +1,26 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE O2. This software is + * distributed under the terms of the GNU General Public License v3 (GPL + * Version 3), copied verbatim in the file "COPYING". + * + * See http://alice-o2.web.cern.ch/license for full licensing information. + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. + */ + +const req = require('esm-wallaby')(module); +const assert = require('assert'); + +const FilterModel = req('../../../app/public/model/filtering/FilterModel.js').default; + +module.exports = () => { + describe('Filter model', () => { + const fModel = new FilterModel(); + it('should instantialte the class with no active filters', () => { + assert.equal(fModel.isAnyFilterActive(), false); + }); + }); +}; diff --git a/test/public/models/index.js b/test/public/models/index.js new file mode 100644 index 000000000..22c093c1f --- /dev/null +++ b/test/public/models/index.js @@ -0,0 +1,18 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE O2. This software is + * distributed under the terms of the GNU General Public License v3 (GPL + * Version 3), copied verbatim in the file "COPYING". + * + * See http://alice-o2.web.cern.ch/license for full licensing information. + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. + */ + +const filterSuite = require('./FilterModel.test'); + +module.exports = () => { + describe('Filter', filterSuite); +}; From f4dd6b9dce0408eaebc7403d940be67ef0ed1a82 Mon Sep 17 00:00:00 2001 From: Ehevi Date: Fri, 22 Sep 2023 14:49:34 +0200 Subject: [PATCH 13/20] Rename variables --- app/public/components/buttons/dataActionButtons.js | 4 ++-- app/public/views/periods/PeriodsModel.js | 8 ++++---- app/public/views/periods/overview/periodsContent.js | 2 +- test/public/models/FilterModel.test.js | 4 ++-- test/public/models/index.js | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/public/components/buttons/dataActionButtons.js b/app/public/components/buttons/dataActionButtons.js index 2b9c2a6dd..72a955f31 100644 --- a/app/public/components/buttons/dataActionButtons.js +++ b/app/public/components/buttons/dataActionButtons.js @@ -94,8 +94,8 @@ export default function dataActionButtons(model, applicableDataActions, dataMode applicableDataActions[dataActions.showFilteringPanel] && dataModel ? h('button.btn.icon-only-button', { - className: dataModel.filterPanelVisible ? 'btn-primary' : 'btn-secondary', + className: dataModel.isFilterPanelVisible ? 'btn-primary' : 'btn-secondary', onclick: () => dataModel.toggleFilterPanelVisibility(), - }, dataModel.filterPanelVisible ? h('.slider-20-off-white.abs-center') : h('.slider-20-primary.abs-center')) + }, dataModel.isFilterPanelVisible ? h('.slider-20-off-white.abs-center') : h('.slider-20-primary.abs-center')) : ''); } diff --git a/app/public/views/periods/PeriodsModel.js b/app/public/views/periods/PeriodsModel.js index 05e5e2de4..979eddaea 100644 --- a/app/public/views/periods/PeriodsModel.js +++ b/app/public/views/periods/PeriodsModel.js @@ -44,7 +44,7 @@ export default class PeriodsModel extends Observable { }); this._fields = periodsActiveColumns; - this._filterPanelVisible = false; + this._isFilterPanelVisible = false; this._shouldHideSelectedPeriods = false; this._sortingRowVisible = false; @@ -177,8 +177,8 @@ export default class PeriodsModel extends Observable { return Object.keys(this._fields).map((field) => ({ ...this._fields[field] })).filter((field) => field.visible); } - get filterPanelVisible() { - return this._filterPanelVisible; + get isFilterPanelVisible() { + return this._isFilterPanelVisible; } get fields() { @@ -202,7 +202,7 @@ export default class PeriodsModel extends Observable { } toggleFilterPanelVisibility() { - this._filterPanelVisible = !this._filterPanelVisible; + this._isFilterPanelVisible = !this._isFilterPanelVisible; this.notify(); } diff --git a/app/public/views/periods/overview/periodsContent.js b/app/public/views/periods/overview/periodsContent.js index 2c9634c31..fb6d3c082 100644 --- a/app/public/views/periods/overview/periodsContent.js +++ b/app/public/views/periods/overview/periodsContent.js @@ -51,7 +51,7 @@ export default function periodsContent(periodsModel, model) { title(pageName)), dataActionButtons(dataAccess, applicableDataActions, periodsModel)), - periodsModel.filterPanelVisible ? filteringPanel(periodsModel) : '', + periodsModel.isFilterPanelVisible ? filteringPanel(periodsModel) : '', periodsModel.filtering.isAnyFilterActive() ? activeFilters(periodsModel.filtering) : '', periods.length > 0 diff --git a/test/public/models/FilterModel.test.js b/test/public/models/FilterModel.test.js index b9de63661..2a274d604 100644 --- a/test/public/models/FilterModel.test.js +++ b/test/public/models/FilterModel.test.js @@ -17,9 +17,9 @@ const assert = require('assert'); const FilterModel = req('../../../app/public/model/filtering/FilterModel.js').default; module.exports = () => { - describe('Filter model', () => { + describe('Class instance creation', () => { const fModel = new FilterModel(); - it('should instantialte the class with no active filters', () => { + it('should instantiate the class with no active filters', () => { assert.equal(fModel.isAnyFilterActive(), false); }); }); diff --git a/test/public/models/index.js b/test/public/models/index.js index 22c093c1f..54c5f1dd0 100644 --- a/test/public/models/index.js +++ b/test/public/models/index.js @@ -14,5 +14,5 @@ const filterSuite = require('./FilterModel.test'); module.exports = () => { - describe('Filter', filterSuite); + describe('Filter model', filterSuite); }; From cc75c0cedaf44f124e87dc89ee85d76b44ae81c9 Mon Sep 17 00:00:00 2001 From: Ehevi Date: Fri, 22 Sep 2023 14:51:12 +0200 Subject: [PATCH 14/20] Make isAnyFilterActive a getter --- app/public/model/filtering/FilterModel.js | 2 +- app/public/views/periods/overview/periodsContent.js | 2 +- test/public/models/FilterModel.test.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/public/model/filtering/FilterModel.js b/app/public/model/filtering/FilterModel.js index 03e3f3910..9cbfd5efd 100644 --- a/app/public/model/filtering/FilterModel.js +++ b/app/public/model/filtering/FilterModel.js @@ -74,7 +74,7 @@ export default class FilterModel extends Observable { .map(([type, values]) => values.map((value) => ({ field, type, value })))).flat(2); } - isAnyFilterActive() { + get isAnyFilterActive() { return Object.keys(this._activeFilters).length > 0; } diff --git a/app/public/views/periods/overview/periodsContent.js b/app/public/views/periods/overview/periodsContent.js index fb6d3c082..b495880a4 100644 --- a/app/public/views/periods/overview/periodsContent.js +++ b/app/public/views/periods/overview/periodsContent.js @@ -52,7 +52,7 @@ export default function periodsContent(periodsModel, model) { dataActionButtons(dataAccess, applicableDataActions, periodsModel)), periodsModel.isFilterPanelVisible ? filteringPanel(periodsModel) : '', - periodsModel.filtering.isAnyFilterActive() ? activeFilters(periodsModel.filtering) : '', + periodsModel.filtering.isAnyFilterActive ? activeFilters(periodsModel.filtering) : '', periods.length > 0 ? periodsModel.visibleFields.length > 0 diff --git a/test/public/models/FilterModel.test.js b/test/public/models/FilterModel.test.js index 2a274d604..8f4447046 100644 --- a/test/public/models/FilterModel.test.js +++ b/test/public/models/FilterModel.test.js @@ -20,7 +20,7 @@ module.exports = () => { describe('Class instance creation', () => { const fModel = new FilterModel(); it('should instantiate the class with no active filters', () => { - assert.equal(fModel.isAnyFilterActive(), false); + assert.equal(fModel.isAnyFilterActive, false); }); }); }; From 09f22d8a5937011a64bc1c769d7197eb1517533b Mon Sep 17 00:00:00 2001 From: Ehevi Date: Fri, 22 Sep 2023 15:04:00 +0200 Subject: [PATCH 15/20] Prepare test structure --- app/public/model/filtering/FilterModel.js | 10 +++---- app/public/views/periods/PeriodsModel.js | 4 +-- test/public/models/FilterModel.test.js | 36 +++++++++++++++++++++-- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/app/public/model/filtering/FilterModel.js b/app/public/model/filtering/FilterModel.js index 9cbfd5efd..62c24987e 100644 --- a/app/public/model/filtering/FilterModel.js +++ b/app/public/model/filtering/FilterModel.js @@ -67,6 +67,10 @@ export default class FilterModel extends Observable { } } + buildSingleFilterPhrase(field, type, value) { + return `filter[${field}]${this.buildOperatorPhrase(type, value)}`; + } + get filterObjects() { return Object.entries(this._activeFilters) .map(([field, typeToValues]) => @@ -78,11 +82,7 @@ export default class FilterModel extends Observable { return Object.keys(this._activeFilters).length > 0; } - buildSingleFilterPhrase(field, type, value) { - return `filter[${field}]${this.buildOperatorPhrase(type, value)}`; - } - - buildFilterPhrase() { + get filterPhrase() { return this.filterObjects.map(({ field, type, value }) => this.buildSingleFilterPhrase(field, type, value)).join('&'); } } diff --git a/app/public/views/periods/PeriodsModel.js b/app/public/views/periods/PeriodsModel.js index 979eddaea..360a7ccb2 100644 --- a/app/public/views/periods/PeriodsModel.js +++ b/app/public/views/periods/PeriodsModel.js @@ -75,7 +75,7 @@ export default class PeriodsModel extends Observable { this._allPeriods = RemoteData.notAsked(); - const endpoint = `/api/periods/?${encodeURI(this._filtering.buildFilterPhrase())}`; + const endpoint = `/api/periods/?${encodeURI(this._filtering.filterPhrase)}`; try { const { items, totalCount } = await getRemoteDataSlice(endpoint); this._allPeriods = RemoteData.success([...items]); @@ -97,7 +97,7 @@ export default class PeriodsModel extends Observable { * @type {Period[]} */ - const filterPhrase = this._filtering.buildFilterPhrase(); + const filterPhrase = this._filtering.filterPhrase; if (this._allPeriods.kind === 'NotAsked') { await this.fetchAllPeriods(); diff --git a/test/public/models/FilterModel.test.js b/test/public/models/FilterModel.test.js index 8f4447046..92bc3c157 100644 --- a/test/public/models/FilterModel.test.js +++ b/test/public/models/FilterModel.test.js @@ -17,10 +17,42 @@ const assert = require('assert'); const FilterModel = req('../../../app/public/model/filtering/FilterModel.js').default; module.exports = () => { + const filterModel = new FilterModel(); + describe('Class instance creation', () => { - const fModel = new FilterModel(); it('should instantiate the class with no active filters', () => { - assert.equal(fModel.isAnyFilterActive, false); + assert.equal(filterModel.isAnyFilterActive, false); + }); + }); + + describe('Adding a new filter', () => { + it('should add a new filter', () => { + filterModel.addFilter('name', 'LHC', 'like'); + assert.equal(filterModel.isAnyFilterActive, true); + }); + }); + + describe('Removing filters', () => { + it('should add a new filter', () => { + assert.equal(false, false); + }); + }); + + describe('Reseting', () => { + it('should add a new filter', () => { + assert.equal(false, false); + }); + }); + + describe('Building filter phrases', () => { + it('should add a new filter', () => { + assert.equal(false, false); + }); + }); + + describe('Filter objects', () => { + it('should add a new filter', () => { + assert.equal(false, false); }); }); }; From d7ee29151dc113d073a21819067b66f0a369c0c0 Mon Sep 17 00:00:00 2001 From: Ehevi Date: Fri, 22 Sep 2023 15:05:22 +0200 Subject: [PATCH 16/20] Apply eslint rules --- app/public/views/periods/PeriodsModel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/public/views/periods/PeriodsModel.js b/app/public/views/periods/PeriodsModel.js index 360a7ccb2..4c35ada11 100644 --- a/app/public/views/periods/PeriodsModel.js +++ b/app/public/views/periods/PeriodsModel.js @@ -97,7 +97,7 @@ export default class PeriodsModel extends Observable { * @type {Period[]} */ - const filterPhrase = this._filtering.filterPhrase; + const { filterPhrase } = this._filtering; if (this._allPeriods.kind === 'NotAsked') { await this.fetchAllPeriods(); From 1b6a84046c25afec5923d30e0ee679903afe76a3 Mon Sep 17 00:00:00 2001 From: Ehevi Date: Fri, 22 Sep 2023 15:11:41 +0200 Subject: [PATCH 17/20] Adding a new filter tests --- test/public/models/FilterModel.test.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/public/models/FilterModel.test.js b/test/public/models/FilterModel.test.js index 92bc3c157..74ab5cae9 100644 --- a/test/public/models/FilterModel.test.js +++ b/test/public/models/FilterModel.test.js @@ -27,8 +27,15 @@ module.exports = () => { describe('Adding a new filter', () => { it('should add a new filter', () => { - filterModel.addFilter('name', 'LHC', 'like'); + filterModel.addFilter('name', 'LHC', 'match'); + filterModel.addFilter('name', 'zt', 'exclude'); + + const expectedFilterObjects = [ + { field: 'name', type: 'match', value: 'LHC' }, + { field: 'name', type: 'exclude', value: 'zt' }, + ]; assert.equal(filterModel.isAnyFilterActive, true); + assert.deepEqual(filterModel.filterObjects, expectedFilterObjects); }); }); From 5da14322461733d5cb174c27129385844effcb71 Mon Sep 17 00:00:00 2001 From: Ehevi Date: Fri, 22 Sep 2023 15:16:29 +0200 Subject: [PATCH 18/20] Some tests --- test/public/models/FilterModel.test.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/public/models/FilterModel.test.js b/test/public/models/FilterModel.test.js index 74ab5cae9..7f10c02c5 100644 --- a/test/public/models/FilterModel.test.js +++ b/test/public/models/FilterModel.test.js @@ -40,14 +40,18 @@ module.exports = () => { }); describe('Removing filters', () => { - it('should add a new filter', () => { - assert.equal(false, false); + it('should remove a specified filter', () => { + filterModel.removeFilter('name', 'zt', 'exclude'); + + const expectedFilterObjects = [{ field: 'name', type: 'match', value: 'LHC' }]; + assert.deepEqual(filterModel.filterObjects, expectedFilterObjects); }); }); describe('Reseting', () => { - it('should add a new filter', () => { - assert.equal(false, false); + it('should reset the filter model', () => { + filterModel.reset(); + assert.equal(filterModel.isAnyFilterActive, false); }); }); From 0d0adc20571bd2ac71d55e2fd5548a3a3ff34e89 Mon Sep 17 00:00:00 2001 From: Ehevi Date: Fri, 22 Sep 2023 16:26:06 +0200 Subject: [PATCH 19/20] Tests --- test/public/models/FilterModel.test.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/test/public/models/FilterModel.test.js b/test/public/models/FilterModel.test.js index 7f10c02c5..658085a7f 100644 --- a/test/public/models/FilterModel.test.js +++ b/test/public/models/FilterModel.test.js @@ -17,15 +17,15 @@ const assert = require('assert'); const FilterModel = req('../../../app/public/model/filtering/FilterModel.js').default; module.exports = () => { - const filterModel = new FilterModel(); - describe('Class instance creation', () => { + const filterModel = new FilterModel(); it('should instantiate the class with no active filters', () => { assert.equal(filterModel.isAnyFilterActive, false); }); }); describe('Adding a new filter', () => { + const filterModel = new FilterModel(); it('should add a new filter', () => { filterModel.addFilter('name', 'LHC', 'match'); filterModel.addFilter('name', 'zt', 'exclude'); @@ -40,6 +40,10 @@ module.exports = () => { }); describe('Removing filters', () => { + const filterModel = new FilterModel(); + filterModel.addFilter('name', 'LHC', 'match'); + filterModel.addFilter('name', 'zt', 'exclude'); + it('should remove a specified filter', () => { filterModel.removeFilter('name', 'zt', 'exclude'); @@ -49,6 +53,10 @@ module.exports = () => { }); describe('Reseting', () => { + const filterModel = new FilterModel(); + filterModel.addFilter('name', 'LHC', 'match'); + filterModel.addFilter('name', 'zt', 'exclude'); + it('should reset the filter model', () => { filterModel.reset(); assert.equal(filterModel.isAnyFilterActive, false); @@ -56,8 +64,13 @@ module.exports = () => { }); describe('Building filter phrases', () => { - it('should add a new filter', () => { - assert.equal(false, false); + const filterModel = new FilterModel(); + filterModel.addFilter('year', '2020', 'from'); + + const expectedFilterPhrase = 'filter[year][gte]=2020'; + + it('should build a correct filter phrase', () => { + assert.equal(filterModel.filterPhrase, expectedFilterPhrase); }); }); From f4d0d1a99d19afd310fb846a90ed3df50304709e Mon Sep 17 00:00:00 2001 From: Ehevi Date: Fri, 22 Sep 2023 16:27:33 +0200 Subject: [PATCH 20/20] Cleanup :broom: --- test/public/models/FilterModel.test.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/test/public/models/FilterModel.test.js b/test/public/models/FilterModel.test.js index 658085a7f..713600c84 100644 --- a/test/public/models/FilterModel.test.js +++ b/test/public/models/FilterModel.test.js @@ -56,7 +56,7 @@ module.exports = () => { const filterModel = new FilterModel(); filterModel.addFilter('name', 'LHC', 'match'); filterModel.addFilter('name', 'zt', 'exclude'); - + it('should reset the filter model', () => { filterModel.reset(); assert.equal(filterModel.isAnyFilterActive, false); @@ -66,17 +66,11 @@ module.exports = () => { describe('Building filter phrases', () => { const filterModel = new FilterModel(); filterModel.addFilter('year', '2020', 'from'); - + const expectedFilterPhrase = 'filter[year][gte]=2020'; it('should build a correct filter phrase', () => { assert.equal(filterModel.filterPhrase, expectedFilterPhrase); }); }); - - describe('Filter objects', () => { - it('should add a new filter', () => { - assert.equal(false, false); - }); - }); };