const assert = require('assert');
const th = require('../../lib/template-helper');
-const lint = require('html-minifier-lint').lint; // eslint-disable-line node/no-unpublished-require
const stubLogger = require('../stub-logger');
-function lintHtml(html) {
- const result = lint(html);
- stubLogger.debug('validHtml', '', { result, html });
- assert(!result);
-}
+const { makeHtmlLint } = require('../lint-html');
+const { HtmlValidate } = require('html-validate');
+const htmlValidate = new HtmlValidate();
+const htmlLint = makeHtmlLint(stubLogger, htmlValidate);
describe('Template Helper', function () {
let ctx, options, pagePathLevel;
options = {};
});
+ describe('initContext', function () {
+ it('covers', function () {
+ th.initContext(ctx);
+ assert(ctx.errors);
+ assert(ctx.notifications);
+ assert(Array.isArray(ctx.errors));
+ assert(Array.isArray(ctx.notifications));
+ });
+ }); // initContext
+
describe('dateOrNot', function () {
let date, otherwise;
beforeEach(function () {
});
}); // dateOrNot
+ describe('dateFormat', function () {
+ it('renders otherwise', function () {
+ const expected = 'otherwise';
+ const result = th.dateFormat(undefined, undefined, undefined, expected);
+ assert.strictEqual(result, expected);
+ });
+ it('handles invalid date', function () {
+ const expected = 'otherwise';
+ const result = th.dateFormat(new Date('bad date'), undefined, undefined, expected);
+ assert.strictEqual(result, expected);
+ });
+ it('renders Infinity', function () {
+ const expected = 'end of time';
+ const result = th.dateFormat(Infinity, expected);
+ assert.strictEqual(result, expected);
+ });
+ it('renders -Infinity', function () {
+ const expected = 'beginning of time';
+ const result = th.dateFormat(-Infinity, undefined, expected);
+ assert.strictEqual(result, expected);
+ });
+ it('renders a Date', function () {
+ const expected = 'Mar 27, 2022, 3:28:05 PM PDT';
+ const result = th.dateFormat(new Date('2022-03-27T22:28:05.049Z'));
+ assert.strictEqual(result, expected);
+ });
+ it('renders a timestamp', function () {
+ const expected = 'Mar 27, 2022, 3:28:05 PM PDT';
+ const result = th.dateFormat(1648420085049);
+ assert.strictEqual(result, expected);
+ });
+ }); // dateFormat
+
+ describe('timeElement', function () {
+ it('renders a date', function () {
+ const when = new Date('2022-09-11T21:17:56.872Z');
+ const expected = '<time datetime="2022-09-11T21:17:56.872Z">Sep 11, 2022, 2:17:56 PM PDT</time>';
+ const result = th.timeElement(when);
+ assert.strictEqual(result, expected);
+ });
+ it('covers title', function () {
+ const when = new Date('2022-09-11T21:17:56.872Z');
+ const expected = '<time title="a date" datetime="2022-09-11T21:17:56.872Z">Sep 11, 2022, 2:17:56 PM PDT</time>';
+ const result = th.timeElement(when, { title: 'a date' });
+ assert.strictEqual(result, expected);
+ });
+ it('covers other', function () {
+ const expected = '<time>Mar 27, 2022, 3:28:05 PM PDT</time>';
+ const result = th.timeElement(1648420085049);
+ assert.strictEqual(result, expected);
+ });
+ }); // timeElement
+
describe('secondsToPeriod', function () {
it('covers seconds', function () {
const result = th.secondsToPeriod(45);
});
}); // renderNavLink
+ describe('elementAttributes', function () {
+ it('covers', function () {
+ const attributes = {
+ class: 'foo bar',
+ disabled: '',
+ };
+ const result = th.elementAttributes(attributes);
+ assert.strictEqual(result, ' class="foo bar" disabled');
+ });
+ }); // elementAttributes
+
describe('OL', function () {
it('covers', function () {
const result = th.OL(['item', 'another item'], 1, { class: 'class' }, (item) => ({ class: `${item}-class` }));
});
}); // LI
+ describe('indented', function () {
+ it('covers', function () {
+ const result = th.indented(2, ['foo', 'bar']);
+ result.forEach((r) => assert(r.startsWith('\t\t')));
+ });
+ }); // indented
+
describe('htmlBody', function () {
it('covers no main', function () {
const result = th.htmlBody(pagePathLevel, ctx, options);
describe('htmlPage', function () {
let main;
beforeEach(function () {
- main = [];
+ th.initContext(ctx);
+ ctx.errors.push('an error');
+ ctx.notifications.push('a notice');
+ options.headElements = ['<link rel="author" href="https://example.com/">'];
+ options.pageTitle = 'Test Page';
+ main = [
+ th.UL(['an item', 'another item']),
+ th.timeElement(new Date(), { title: 'now' }),
+ ];
});
- it('covers', function () {
+ it('covers', async function () {
+ this.slow(1000); // First invocation of htmlLint takes some time.
const result = th.htmlPage(pagePathLevel, ctx, options, main);
- lintHtml(result);
+ await htmlLint(result);
assert(result);
});
- it('covers defaults', function () {
+ it('covers defaults', async function () {
const result = th.htmlPage(pagePathLevel, ctx, options, main);
- lintHtml(result);
+ await htmlLint(result);
assert(result);
});
- it('covers user', function () {
+ it('covers user', async function () {
ctx.session = {
authenticatedProfile: 'https://user.example.com/',
};
const result = th.htmlPage(pagePathLevel, ctx, options, main);
- lintHtml(result);
+ await htmlLint(result);
assert(result);
});
- it('covers user at root path', function () {
+ it('covers user at root path', async function () {
ctx.session = {
authenticatedIdentifier: 'user',
};
pagePathLevel = 0;
const result = th.htmlPage(pagePathLevel, ctx, options, main);
- lintHtml(result);
+ await htmlLint(result);
assert(result);
});
- it('covers logout redirect', function () {
+ it('covers logout redirect', async function () {
ctx.session = {
authenticatedIdentifier: 'user',
};
ctx.url = 'https://app.example.com/this_page';
const result = th.htmlPage(pagePathLevel, ctx, options, main);
- lintHtml(result);
+ await htmlLint(result);
assert(result);
});
- it('covers existing navLinks', function () {
+ it('covers existing navLinks', async function () {
ctx.session = {
authenticatedIdentifier: 'user',
};
href: 'link',
}];
const result = th.htmlPage(pagePathLevel, ctx, options);
- lintHtml(result);
+ await htmlLint(result);
assert(result);
});
}); // htmlPage