Release 2.8.2
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile, web, pulse-signage-web) (push) Successful in 1m12s
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile.player, player, pulse-signage-player) (push) Successful in 34s

This commit is contained in:
2026-08-16 22:41:39 +01:00
parent a5bf8e6f7f
commit ea72747822
31 changed files with 379 additions and 31 deletions
@@ -1,6 +1,8 @@
const test = require('node:test');
const assert = require('node:assert/strict');
require('../src/common');
const registerAccountRoutes = require('../src/web/routes/admin/account');
const { validatePasswordStrength } = require('../src/auth');
@@ -1,6 +1,8 @@
const test = require('node:test');
const assert = require('node:assert/strict');
require('../src/common');
const registerUsersRoutes = require('../src/web/routes/admin/users');
test('user create route allows users without roles', async () => {
@@ -1,6 +1,8 @@
const test = require('node:test');
const assert = require('node:assert/strict');
require('../src/common');
const registerUsersRoutes = require('../src/web/routes/admin/users');
test('user edit save and new goes to the blank create page', async () => {
+2
View File
@@ -1,6 +1,8 @@
const test = require('node:test');
const assert = require('node:assert/strict');
require('../src/common');
const registerUsersRoutes = require('../src/web/routes/admin/users');
const { validatePasswordStrength } = require('../src/auth');
+33 -1
View File
@@ -24,7 +24,26 @@ test('audit log uses its own read permission and shared pagination partial', asy
category: 'authentication',
event_type: 'login.success',
target_label: 'newer',
details_json: null
details_json: JSON.stringify({
changes: {
content: {
from: { title: 'Same', body: { color: 'red', keep: 'same' } },
to: { title: 'Same', body: { color: 'blue', keep: 'same' } }
},
permissions: {
from: ['dashboard.read', 'screens.read'],
to: ['screens.read', 'playlists.read']
},
backgroundColor: {
from: null,
to: '#111111'
},
logoPath: {
from: '',
to: '/media/logo.png'
}
}
})
},
{
id: 2,
@@ -60,10 +79,23 @@ test('audit log uses its own read permission and shared pagination partial', asy
throw error;
});
assert.match(response.body, /Audit log/);
assert.ok(response.body.indexOf('>All categories</option>') < response.body.indexOf('>announcements</option>'));
assert.ok(response.body.indexOf('>announcements</option>') < response.body.indexOf('>api-sources</option>'));
assert.ok(response.body.indexOf('>api-sources</option>') < response.body.indexOf('>canvas-sizes</option>'));
assert.match(response.body, /table-pagination/);
assert.match(response.body, /data-local-datetime/);
assert.match(response.body, /audit-event-type-options/);
assert.match(response.body, /login\.success/);
assert.match(response.body, /content\.body\.color/);
assert.match(response.body, />red</);
assert.match(response.body, />blue</);
assert.doesNotMatch(response.body, /content\.body\.keep/);
assert.match(response.body, /permissions removed/);
assert.match(response.body, /permissions added/);
assert.match(response.body, /dashboard\.read/);
assert.match(response.body, /playlists\.read/);
assert.match(response.body, /backgroundColor added/);
assert.match(response.body, /logoPath added/);
assert.ok(response.body.indexOf('login.success') < response.body.indexOf('login.failed'));
assert.match(response.body, />Export</);
assert.ok(handlers['/settings/audit-log/export']);
+16 -1
View File
@@ -3,7 +3,7 @@ const assert = require('node:assert/strict');
require('../src/common');
const { recordRequestAuditEvent } = require('../src/data/audit-log');
const { buildAuditChanges, recordRequestAuditEvent } = require('../src/data/audit-log');
function createPool(settings) {
const inserts = [];
@@ -44,4 +44,19 @@ test('audit writer omits request metadata when disabled', async () => {
assert.equal(pool.inserts.length, 1);
assert.equal(pool.inserts[0][6], null);
assert.equal(pool.inserts[0][7], null);
});
test('audit changes include only fields with different from and to values', () => {
assert.deepEqual(buildAuditChanges({
name: 'Old name',
playlistId: 4,
roleIds: [1, 2]
}, {
name: 'New name',
playlistId: 4,
roleIds: [2, 3]
}), {
name: { from: 'Old name', to: 'New name' },
roleIds: { from: [1, 2], to: [2, 3] }
});
});
+2
View File
@@ -1,6 +1,8 @@
const test = require('node:test');
const assert = require('node:assert/strict');
require('../src/common');
const registerPlaylistRoutes = require('../src/web/routes/admin/playlists');
function createAppAndHandlers() {
+2
View File
@@ -3,6 +3,8 @@ const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
require('../src/common');
const {
buildDuplicateTimetableGroupName,
buildDuplicateTimetableGroup,
+2
View File
@@ -1,6 +1,8 @@
const test = require('node:test');
const assert = require('node:assert/strict');
require('../src/common');
const registerUsersRoutes = require('../src/web/routes/admin/users');
test('user duplicate route pre-fills the add form', async () => {
+2
View File
@@ -1,6 +1,8 @@
const test = require('node:test');
const assert = require('node:assert/strict');
require('../src/common');
const registerManageRoutes = require('../src/web/routes/admin/manage');
test('screen update keeps the existing slug on edit', async () => {