Publish Docker Image / build-and-push (./build/Dockerfile, git.lzstealth.com/lzstealth/pulse-signage-web, web) (push) Successful in 1m18s
Publish Docker Image / build-and-push (./build/Dockerfile.player, git.lzstealth.com/lzstealth/pulse-signage-player, player) (push) Successful in 33s
100 lines
3.4 KiB
JavaScript
100 lines
3.4 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
|
|
const { buildSlidePayload } = require('../src/data/slides');
|
|
|
|
test('buildSlidePayload normalizes timetable region fields', async () => {
|
|
const pool = {
|
|
async query(sql) {
|
|
if (sql.includes('FROM c_templates st')) {
|
|
return [[{ id: 9, name: 'Template 9', canvas_size_id: 1, canvas_size_width: 1920, canvas_size_height: 1080 }]];
|
|
}
|
|
|
|
if (sql.includes('FROM c_template_regions')) {
|
|
return [[{ id: 47, template_id: 9, region_key: 'timetable', region_type: 'timetable', label: 'Timetable' }]];
|
|
}
|
|
|
|
return [[]];
|
|
}
|
|
};
|
|
|
|
const payload = await buildSlidePayload(pool, {
|
|
body: {
|
|
title: 'Timetable slide',
|
|
template_id: '9',
|
|
region_text_47: '<p>{{title}}</p>',
|
|
region_timetable_group_id_47: '1',
|
|
region_timetable_display_mode_47: 'current',
|
|
region_timetable_max_items_47: '7'
|
|
},
|
|
files: []
|
|
}, null);
|
|
|
|
const content = JSON.parse(payload.contentJson);
|
|
assert.equal(content.timetable.type, 'timetable');
|
|
assert.equal(content.timetable.text, '<p>{{title}}</p>');
|
|
assert.equal(content.timetable.value, '<p>{{title}}</p>');
|
|
assert.equal(content.timetable.timetable_group_id, '1');
|
|
assert.equal(content.timetable.display_mode, 'current');
|
|
assert.equal(content.timetable.max_items, '7');
|
|
assert.equal(Object.prototype.hasOwnProperty.call(content.timetable, 'timetable_display_mode'), false);
|
|
assert.equal(Object.prototype.hasOwnProperty.call(content.timetable, 'timetable_max_items'), false);
|
|
});
|
|
|
|
test('buildSlidePayload preserves safe image markup in text regions', async () => {
|
|
const pool = {
|
|
async query(sql) {
|
|
if (sql.includes('FROM c_templates st')) {
|
|
return [[{ id: 9, name: 'Template 9', canvas_size_id: 1, canvas_size_width: 1920, canvas_size_height: 1080 }]];
|
|
}
|
|
|
|
if (sql.includes('FROM c_template_regions')) {
|
|
return [[{ id: 47, template_id: 9, region_key: 'body', region_type: 'text', label: 'Body' }]];
|
|
}
|
|
|
|
return [[]];
|
|
}
|
|
};
|
|
|
|
const payload = await buildSlidePayload(pool, {
|
|
body: {
|
|
title: 'Text slide',
|
|
template_id: '9',
|
|
region_text_47: '<p><img src="/media/uploads/photo.png" alt="Photo" onerror="alert(1)"></p>'
|
|
},
|
|
files: []
|
|
}, null);
|
|
|
|
const content = JSON.parse(payload.contentJson);
|
|
assert.equal(content.body.type, 'text');
|
|
assert.equal(content.body.value, '<p><img src="/media/uploads/photo.png" alt="Photo"></p>');
|
|
});
|
|
|
|
test('buildSlidePayload preserves safe color spans in text regions', async () => {
|
|
const pool = {
|
|
async query(sql) {
|
|
if (sql.includes('FROM c_templates st')) {
|
|
return [[{ id: 9, name: 'Template 9', canvas_size_id: 1, canvas_size_width: 1920, canvas_size_height: 1080 }]];
|
|
}
|
|
|
|
if (sql.includes('FROM c_template_regions')) {
|
|
return [[{ id: 47, template_id: 9, region_key: 'body', region_type: 'text', label: 'Body' }]];
|
|
}
|
|
|
|
return [[]];
|
|
}
|
|
};
|
|
|
|
const payload = await buildSlidePayload(pool, {
|
|
body: {
|
|
title: 'Text slide',
|
|
template_id: '9',
|
|
region_text_47: '<p><span style="color:#ff0000" class="text-emphasis">Hello</span></p>'
|
|
},
|
|
files: []
|
|
}, null);
|
|
|
|
const content = JSON.parse(payload.contentJson);
|
|
assert.equal(content.body.type, 'text');
|
|
assert.equal(content.body.value, '<p><span style="color:#ff0000" class="text-emphasis">Hello</span></p>');
|
|
}); |