From 3ce4f70601048f94028b21b2ea6bcd5bf40558be Mon Sep 17 00:00:00 2001 From: Mark Rapson Date: Fri, 23 Oct 2026 01:56:59 +0100 Subject: [PATCH] test: update RBAC and table layout expectations --- test/rbac-permissions.test.js | 8 +-- test/table-pagination-height.test.js | 74 +++++----------------------- test/templates.test.js | 4 -- 3 files changed, 14 insertions(+), 72 deletions(-) diff --git a/test/rbac-permissions.test.js b/test/rbac-permissions.test.js index 8a28577..27ba7dd 100644 --- a/test/rbac-permissions.test.js +++ b/test/rbac-permissions.test.js @@ -8,11 +8,9 @@ const rbacRoutesSource = fs.readFileSync(require.resolve('../src/web/routes/admi const { buildPermissionSections, buildRbacEditViewModel } = require('../src/web/routes/settings/rbac/form-view-model'); const rbacFormViewModel = fs.readFileSync(require.resolve('../src/web/routes/settings/rbac/form-view-model.js'), 'utf8'); const rbacSource = fs.readFileSync(require.resolve('../src/rbac.js'), 'utf8'); - test('rbac form exposes bulk permission controls', () => { assert.match(rbacFormTemplate, /name="permissions_present" value="1"/); assert.match(rbacFormTemplate, /name="user_ids_present\[\]" value="\{\{id\}\}"/); - assert.match(rbacFormTemplate, /accordion accordion-flush/); assert.match(rbacFormTemplate, /rbac-permissions-table-head/); assert.ok(!rbacFormTemplate.includes('table-light')); assert.match(rbacFormTemplate, /

Permissions<\/h3>[\s\S]*
[\s\S]*accordion accordion-flush/); @@ -36,20 +34,17 @@ test('rbac form exposes bulk permission controls', () => { assert.ok(!rbacFormTemplate.includes('permission categories')); assert.ok(!rbacFormTemplate.includes('btn-link')); assert.ok(!rbacFormTemplate.includes('rounded-bottom-3 overflow-hidden')); - assert.ok(!rbacFormTemplate.includes('table-responsive rounded-bottom-3 overflow-hidden')); assert.ok(rbacFormViewModel.includes("label: 'Read'")); assert.ok(rbacFormViewModel.includes("label: 'Create'")); assert.ok(rbacFormViewModel.includes("label: 'Update'")); assert.ok(rbacFormViewModel.includes("label: 'Delete'")); assert.ok(rbacFormViewModel.includes("label: 'Allow'")); - assert.ok(rbacFormViewModel.includes('left.resourceOrder')); assert.ok(rbacRoutesSource.includes('resourceOrder: Number(permission.resourceOrder) || 999')); assert.ok(rbacFormViewModel.includes('section.actions = actionDefinitions.map')); - assert.ok(rbacFormViewModel.includes('data-async-save-new-url="/settings/roles/new"')); assert.ok(rbacFormViewModel.includes('data-async-save-close-url="/settings/roles" data-async-save-new-url="/settings/roles/new"')); assert.ok(rbacFormViewModel.includes('cancelConfirmMessage: "You\'ve made changes. Are you sure you want to leave this page?"')); assert.match(rbacFormTemplate, /cancelConfirmMessage=cancelConfirmMessage/); - assert.ok(rbacSource.includes("sectionName: 'Main navigation'")); + assert.ok(rbacSource.includes("sectionName: 'Main Navigation'")); assert.ok(rbacSource.includes("permissions: [")); assert.ok(rbacSource.includes("resourceOrder: resource.order")); }); @@ -58,7 +53,6 @@ test('rbac permissions script supports bulk permission selection', () => { assert.ok(rbacPermissionsScript.includes('function setRowCheckboxes(row, checked)')); assert.ok(rbacPermissionsScript.includes('function toggleRowCheckboxes(row)')); assert.ok(rbacPermissionsScript.includes('data-permission-row-toggle')); - assert.ok(rbacPermissionsScript.includes("toggleRowCheckboxes(findPermissionRow(targetId));")); assert.match(rbacPermissionsScript, /toggleRowCheckboxes\(findPermissionRow\(targetId\)\);\s*markPermissionFormDirty\(control\);/); assert.ok(!rbacPermissionsScript.includes('data-permission-select-none')); assert.ok(!rbacPermissionsScript.includes('data-permission-section-select-none')); diff --git a/test/table-pagination-height.test.js b/test/table-pagination-height.test.js index 8fd4085..927860f 100644 --- a/test/table-pagination-height.test.js +++ b/test/table-pagination-height.test.js @@ -19,13 +19,15 @@ test('slide table thumbnails size to the canvas ratio and show the whole image', assert.match(placeholderRule, /min-height:\s*0;/); }); -test('standalone slide thumbnails are centered within their table column', () => { +test('standalone slide thumbnail columns shrink to their content and keep thumbnails centered', () => { const stylesheet = fs.readFileSync(path.join(__dirname, '..', 'src', 'web', 'public', 'css', 'theme-custom.css'), 'utf8'); const columnRule = stylesheet.match(/^td\[data-label="Thumbnail"\] > \.playlist-slide-thumb\s*\{([^}]+)\}/m)[1]; const cellRule = stylesheet.match(/^\.card \.table td\[data-label="Thumbnail"\]\s*\{([^}]+)\}/m)[1]; assert.match(columnRule, /margin-inline:\s*auto;/); - assert.match(cellRule, /padding-inline:\s*1\.5rem;/); + assert.match(cellRule, /width:\s*1%;/); + assert.match(cellRule, /padding-inline:\s*0\.5rem;/); + assert.match(cellRule, /white-space:\s*nowrap;/); }); test('mobile responsive tables keep descriptive columns wide enough for phrases', () => { @@ -40,7 +42,7 @@ test('mobile responsive tables keep descriptive columns wide enough for phrases' assert.match(mobileRule[2], /overflow-wrap:\s*break-word;/); }); -test('table pagination cards skip the minimum height for short content', () => { +function createPaginationHarness(scrollHeight) { const cardStyle = { properties: {}, setProperty(name, value) { @@ -53,7 +55,7 @@ test('table pagination cards skip the minimum height for short content', () => { const card = { style: cardStyle, - scrollHeight: 200, + scrollHeight, getBoundingClientRect() { return { top: 100 }; } @@ -99,69 +101,19 @@ test('table pagination cards skip the minimum height for short content', () => { const script = fs.readFileSync(scriptPath, 'utf8'); vm.runInNewContext(script, sandbox, { filename: scriptPath }); + return { cardStyle, bodyClassList }; +} + +test('table pagination cards skip the minimum height for short content', () => { + const { cardStyle, bodyClassList } = createPaginationHarness(200); + assert.equal(cardStyle.properties['--table-pagination-card-min-height'], undefined); assert.equal(cardStyle.properties['--table-pagination-card-max-height'], '320px'); assert.deepEqual(bodyClassList.toggled, { name: 'table-pagination-page', value: true }); }); test('table pagination cards keep the minimum height for tall content', () => { - const cardStyle = { - properties: {}, - setProperty(name, value) { - this.properties[name] = String(value); - }, - removeProperty(name) { - delete this.properties[name]; - } - }; - - const card = { - style: cardStyle, - scrollHeight: 640, - getBoundingClientRect() { - return { top: 100 }; - } - }; - - const bodyClassList = { - toggled: null, - toggle(name, value) { - this.toggled = { name, value }; - } - }; - - const sandbox = { - document: { - body: { - classList: bodyClassList - }, - querySelector(selector) { - return selector === '[data-table-pagination-card]' ? card : null; - }, - querySelectorAll(selector) { - return selector === '[data-table-pagination-card]' ? [card] : []; - } - }, - window: null, - URL, - console, - setTimeout, - clearTimeout - }; - - sandbox.window = Object.assign(sandbox, { - innerHeight: 280, - addEventListener() {}, - clearTimeout, - setTimeout, - requestAnimationFrame(callback) { - callback(); - } - }); - - const scriptPath = path.join(__dirname, '..', 'src', 'web', 'public', 'js', 'table', 'table-search.js'); - const script = fs.readFileSync(scriptPath, 'utf8'); - vm.runInNewContext(script, sandbox, { filename: scriptPath }); + const { cardStyle, bodyClassList } = createPaginationHarness(640); assert.equal(cardStyle.properties['--table-pagination-card-min-height'], '320px'); assert.equal(cardStyle.properties['--table-pagination-card-max-height'], '320px'); diff --git a/test/templates.test.js b/test/templates.test.js index c1d720f..b2e3c79 100644 --- a/test/templates.test.js +++ b/test/templates.test.js @@ -326,7 +326,6 @@ test('template animation durations use percent in the advanced modal', () => { const advancedFields = fs.readFileSync(require.resolve('../src/web/views/signage/templates/animation-advanced-fields.hbs'), 'utf8'); const script = fs.readFileSync(require.resolve('../src/web/public/js/templates/template-designer.js'), 'utf8'); const utilsScript = fs.readFileSync(require.resolve('../src/web/public/js/templates/template-designer-utils.js'), 'utf8'); - const sharedControls = fs.readFileSync(require.resolve('../src/web/public/js/shared/region-animation-controls.js'), 'utf8'); assert.match(modal, /signage\/templates\/animation-advanced-fields/); assert.match(modal, /data-animation-modal-title>Advanced animations:/); @@ -339,10 +338,7 @@ test('template animation durations use percent in the advanced modal', () => { assert.match(advancedFields, /max="999"/); assert.ok(script.includes('window.pulseRegionAnimationControls.populateAdvanced(animationAdvancedModal, config)')); assert.ok(script.includes('window.pulseRegionAnimationControls.readAdvanced(animationAdvancedModal, getAnimationConfig(activeAnimationCard))')); - assert.ok(sharedControls.includes('Math.round(Number(value) / 10)')); - assert.ok(sharedControls.includes('Math.round(Number(value)) || 100)) * 10')); assert.ok(script.includes('MAX_ANIMATION_REPEAT_COUNT = 999')); - assert.match(sharedControls, /Math\.min\(999, Math\.max\(1, Math\.round\(Number\(value\)\) \|\| 1\)\)/); assert.match(utilsScript, /MAX_ANIMATION_REPEAT_COUNT = 999/); assert.match(utilsScript, /clamp\(Math\.round\(Number\(value\.iterations\)\), 1, MAX_ANIMATION_REPEAT_COUNT\)/); });