Release 2.7.3
Publish Docker Image / build-and-push (./build/Dockerfile, git.lzstealth.com/lzstealth/pulse-signage-web, web) (push) Successful in 1m15s
Publish Docker Image / build-and-push (./build/Dockerfile.player, git.lzstealth.com/lzstealth/pulse-signage-player, player) (push) Successful in 32s
Publish Docker Image / build-and-push (./build/Dockerfile, git.lzstealth.com/lzstealth/pulse-signage-web, web) (push) Successful in 1m15s
Publish Docker Image / build-and-push (./build/Dockerfile.player, git.lzstealth.com/lzstealth/pulse-signage-player, player) (push) Successful in 32s
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
|
||||
const {
|
||||
buildFontFamilyFormats,
|
||||
buildFontStylesheet,
|
||||
collectFontLibrarySyncOperations
|
||||
} = require('../src/web/lib/media/font-library');
|
||||
|
||||
test('buildFontFamilyFormats quotes multi-word font families for TinyMCE previews', () => {
|
||||
const formats = buildFontFamilyFormats([
|
||||
{ family: 'Old London', enabled: true },
|
||||
{ family: 'My Custom Font', enabled: true }
|
||||
]);
|
||||
|
||||
assert.match(formats, /Old London='Old London'/);
|
||||
assert.match(formats, /My Custom Font='My Custom Font'/);
|
||||
assert.match(formats, /Times New Roman='Times New Roman',Times,serif/);
|
||||
assert.match(formats, /Lucida Sans Unicode='Lucida Sans Unicode','Lucida Grande',sans-serif/);
|
||||
});
|
||||
|
||||
test('buildFontStylesheet keeps disabled fonts available for rendering', () => {
|
||||
const stylesheet = buildFontStylesheet([
|
||||
{ family: 'Enabled Font', fileName: 'enabled-font.ttf', format: 'truetype', enabled: true },
|
||||
{ family: 'Disabled Font', fileName: 'disabled-font.ttf', format: 'truetype', enabled: false }
|
||||
]);
|
||||
|
||||
assert.match(stylesheet, /Enabled Font/);
|
||||
assert.match(stylesheet, /Disabled Font/);
|
||||
});
|
||||
|
||||
test('collectFontLibrarySyncOperations keeps disabled fonts as puts', async () => {
|
||||
const tempRoot = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'pulse-font-library-'));
|
||||
const fontDir = path.join(tempRoot, 'fonts');
|
||||
await fs.promises.mkdir(fontDir, { recursive: true });
|
||||
await fs.promises.writeFile(path.join(fontDir, 'fonts.json'), JSON.stringify([
|
||||
{ family: 'Enabled Font', fileName: 'enabled-font.ttf', enabled: true },
|
||||
{ family: 'Disabled Font', fileName: 'disabled-font.ttf', enabled: false }
|
||||
], null, 2));
|
||||
|
||||
const operations = collectFontLibrarySyncOperations(tempRoot);
|
||||
const fontOps = operations.filter(function (operation) {
|
||||
return String(operation.uploadPath || '').indexOf('/media/fonts/') === 0 && /\.ttf$/.test(String(operation.uploadPath || ''));
|
||||
});
|
||||
|
||||
assert.deepEqual(fontOps.map(function (operation) {
|
||||
return operation.type;
|
||||
}), ['put', 'put']);
|
||||
});
|
||||
@@ -0,0 +1,226 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
|
||||
require('../src/common');
|
||||
|
||||
const fontLibrary = require('../src/web/lib/media/font-library');
|
||||
const registerFontRoutes = require('../src/web/routes/settings/fonts');
|
||||
const renderFontsPage = require('../src/web/routes/settings/fonts/list');
|
||||
|
||||
function createHandlers() {
|
||||
const handlers = {};
|
||||
const app = {
|
||||
get(path, ...routeHandlers) {
|
||||
handlers[`GET ${path}`] = routeHandlers;
|
||||
},
|
||||
post(path, ...routeHandlers) {
|
||||
handlers[`POST ${path}`] = routeHandlers;
|
||||
}
|
||||
};
|
||||
|
||||
return { app, handlers };
|
||||
}
|
||||
|
||||
test('fonts route filters and paginates managed fonts', async () => {
|
||||
const originalLoadFontLibrary = fontLibrary.loadFontLibrary;
|
||||
const { app, handlers } = createHandlers();
|
||||
|
||||
fontLibrary.loadFontLibrary = function () {
|
||||
return {
|
||||
fonts: [
|
||||
{ id: 'alpha', family: 'Alpha Sans', fileName: 'alpha.woff2', format: 'woff2', enabled: true },
|
||||
{ id: 'beta', family: 'Beta Sans', fileName: 'beta.woff2', format: 'woff2', enabled: false },
|
||||
{ id: 'gamma', family: 'Gamma Sans', fileName: 'gamma.woff2', format: 'woff2', enabled: true }
|
||||
],
|
||||
stylesheetHref: '/media/fonts/fonts.css'
|
||||
};
|
||||
};
|
||||
|
||||
try {
|
||||
registerFontRoutes(app, {
|
||||
pool: {
|
||||
async query() {
|
||||
return [[{ match_count: 0 }]];
|
||||
}
|
||||
},
|
||||
common: {
|
||||
getSearchQuery() {
|
||||
return 'beta';
|
||||
}
|
||||
},
|
||||
pages: {
|
||||
renderFontsPage(data) {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
},
|
||||
upload: {
|
||||
single() {
|
||||
return function (_req, _res, next) {
|
||||
next();
|
||||
};
|
||||
}
|
||||
},
|
||||
uploadDir: 'e:/Projects Git/pulse-signage/media',
|
||||
backgroundTaskQueue: null,
|
||||
setAuthMessageCookie() {}
|
||||
});
|
||||
|
||||
const response = {
|
||||
statusCode: 200,
|
||||
body: null,
|
||||
send(value) {
|
||||
this.body = value;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
await handlers['GET /settings/fonts'][1]({
|
||||
query: {
|
||||
page: '2'
|
||||
},
|
||||
currentUser: {
|
||||
id: 1,
|
||||
permissions: ['fonts.read']
|
||||
}
|
||||
}, response, function () {});
|
||||
|
||||
const rendered = JSON.parse(response.body);
|
||||
assert.equal(rendered.fonts.length, 1);
|
||||
assert.equal(rendered.fonts[0].id, 'beta');
|
||||
assert.equal(rendered.pagination.currentPage, 1);
|
||||
assert.equal(rendered.pagination.totalItems, 1);
|
||||
} finally {
|
||||
fontLibrary.loadFontLibrary = originalLoadFontLibrary;
|
||||
}
|
||||
});
|
||||
|
||||
test('fonts route sorts by format and status', async () => {
|
||||
const originalLoadFontLibrary = fontLibrary.loadFontLibrary;
|
||||
const { app, handlers } = createHandlers();
|
||||
|
||||
fontLibrary.loadFontLibrary = function () {
|
||||
return {
|
||||
fonts: [
|
||||
{ id: 'alpha', family: 'Alpha Sans', fileName: 'alpha.woff2', format: 'woff2', enabled: true },
|
||||
{ id: 'beta', family: 'Beta Sans', fileName: 'beta.otf', format: 'opentype', enabled: false },
|
||||
{ id: 'gamma', family: 'Gamma Sans', fileName: 'gamma.ttf', format: 'truetype', enabled: true }
|
||||
],
|
||||
stylesheetHref: '/media/fonts/fonts.css'
|
||||
};
|
||||
};
|
||||
|
||||
try {
|
||||
registerFontRoutes(app, {
|
||||
pool: {
|
||||
async query() {
|
||||
return [[{ match_count: 0 }]];
|
||||
}
|
||||
},
|
||||
common: {
|
||||
getSearchQuery() {
|
||||
return '';
|
||||
},
|
||||
getSortQuery(req) {
|
||||
return req.query.sort;
|
||||
},
|
||||
getSortDirectionQuery(req) {
|
||||
return req.query.direction;
|
||||
}
|
||||
},
|
||||
pages: {
|
||||
renderFontsPage(data) {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
},
|
||||
upload: {
|
||||
single() {
|
||||
return function (_req, _res, next) {
|
||||
next();
|
||||
};
|
||||
}
|
||||
},
|
||||
uploadDir: 'e:/Projects Git/pulse-signage/media',
|
||||
backgroundTaskQueue: null,
|
||||
setAuthMessageCookie() {}
|
||||
});
|
||||
|
||||
const response = {
|
||||
statusCode: 200,
|
||||
body: null,
|
||||
send(value) {
|
||||
this.body = value;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
await handlers['GET /settings/fonts'][1]({
|
||||
query: {
|
||||
sort: 'format',
|
||||
direction: 'asc'
|
||||
},
|
||||
currentUser: {
|
||||
id: 1,
|
||||
permissions: ['fonts.read']
|
||||
}
|
||||
}, response, function () {});
|
||||
|
||||
let rendered = JSON.parse(response.body);
|
||||
assert.deepEqual(rendered.fonts.map(function (font) { return font.id; }), ['beta', 'gamma', 'alpha']);
|
||||
|
||||
await handlers['GET /settings/fonts'][1]({
|
||||
query: {
|
||||
sort: 'status',
|
||||
direction: 'asc'
|
||||
},
|
||||
currentUser: {
|
||||
id: 1,
|
||||
permissions: ['fonts.read']
|
||||
}
|
||||
}, response, function () {});
|
||||
|
||||
rendered = JSON.parse(response.body);
|
||||
assert.deepEqual(rendered.fonts.map(function (font) { return font.id; }), ['beta', 'alpha', 'gamma']);
|
||||
} finally {
|
||||
fontLibrary.loadFontLibrary = originalLoadFontLibrary;
|
||||
}
|
||||
});
|
||||
|
||||
test('fonts page renders the upload card above the table card', () => {
|
||||
const html = renderFontsPage({
|
||||
fonts: [
|
||||
{
|
||||
id: 'alpha',
|
||||
family: 'Alpha Sans',
|
||||
fileName: 'alpha.woff2',
|
||||
format: 'woff2',
|
||||
enabled: true,
|
||||
inUse: false
|
||||
}
|
||||
],
|
||||
pagination: {
|
||||
hasMultiplePages: true,
|
||||
startItem: 1,
|
||||
endItem: 1,
|
||||
totalItems: 1,
|
||||
itemLabel: 'fonts',
|
||||
ariaLabel: 'Font pages',
|
||||
hasPrevious: false,
|
||||
hasNext: true,
|
||||
previousUrl: '',
|
||||
nextUrl: '?page=2',
|
||||
pages: [{ number: 1, active: true, url: '' }]
|
||||
},
|
||||
stylesheetHref: ''
|
||||
}, '', { id: 1 });
|
||||
|
||||
assert.ok(html.indexOf('Upload font') < html.indexOf('Managed fonts'));
|
||||
assert.match(html, /data-table-search-container/);
|
||||
assert.match(html, /table-pagination/);
|
||||
assert.match(html, /data-async-command/);
|
||||
assert.match(html, /data-font-toggle-row/);
|
||||
assert.match(html, /data-font-status-badge/);
|
||||
assert.match(html, /data-table-sort-key="family"/);
|
||||
assert.match(html, /data-table-sort-key="file"/);
|
||||
assert.match(html, /data-table-sort-key="format"/);
|
||||
assert.match(html, /data-table-sort-key="status"/);
|
||||
});
|
||||
Reference in New Issue
Block a user