Files
menu/test/render.test.ts
T
tanshu 9cb4021229 Serve the customer-facing menus
Landing page, Section pages and archived sets rendered per request from the
store, with the approved design: hand-written CSS, self-hosted Archivo, a
copper pour line in the Section rail, an admin-only Thumbnail and a text page
index. Media is keyed by Page id so URLs survive publishing, and a Draft's
media needs a session. Includes the scrypt admin auth and the login throttle
the media rule needs.
2026-09-22 21:18:49 +05:30

48 lines
1.6 KiB
TypeScript

import { strict as assert } from 'node:assert';
import { describe, it } from 'node:test';
import { parseEnvFile } from '../src/env.ts';
import { Html, escapeHtml, html, join } from '../src/render/html.ts';
describe('parseEnvFile', () => {
it('reads keys, skips comments and blanks, and strips quotes', () => {
const values = parseEnvFile(
[
'# a comment',
'',
'ADMIN_PASSWORD_HASH=scrypt$1$2$3$abc$def',
'export SESSION_SECRET="quoted value"',
"OTHER='single quoted'",
'not a pair',
'EMPTY=',
].join('\n'),
);
assert.deepEqual(values, {
ADMIN_PASSWORD_HASH: 'scrypt$1$2$3$abc$def',
SESSION_SECRET: 'quoted value',
OTHER: 'single quoted',
EMPTY: '',
});
});
});
describe('the html builder', () => {
it('escapes interpolated values', () => {
const rendered = html`<p title="${'a"b'}">${'<script>'}</p>`;
assert.equal(rendered.value, '<p title="a&quot;b">&lt;script&gt;</p>');
assert.equal(escapeHtml('&<>"\''), '&amp;&lt;&gt;&quot;&#39;');
});
it('leaves Html values alone, so composition is opt-in', () => {
const inner = html`<em>${'safe & sound'}</em>`;
const outer = html`<div>${inner}</div>`;
assert.equal(outer.value, '<div><em>safe &amp; sound</em></div>');
assert.equal(Html.raw('<b>raw</b>').value, '<b>raw</b>');
});
it('joins arrays and drops null, undefined and booleans', () => {
const rendered = html`${[html`<li>a</li>`, html`<li>b</li>`]}${null}${undefined}${false}${0}`;
assert.equal(rendered.value, '<li>a</li><li>b</li>0');
assert.equal(join([1, 2, 3], '-').value, '1-2-3');
});
});