4 const assert
= require('assert');
5 const th
= require('../../lib/template-helper');
6 const lint
= require('html-minifier-lint').lint
; // eslint-disable-line node/no-unpublished-require
7 const stubLogger
= require('../stub-logger');
9 function lintHtml(html
) {
10 const result
= lint(html
);
11 stubLogger
.debug('validHtml', '', { result
, html
});
15 describe('Template Helper', function () {
16 let ctx
, options
, pagePathLevel
;
18 beforeEach(function () {
24 describe('dateOrNot', function () {
26 beforeEach(function () {
28 otherwise
= 'otherwise';
30 it('covers', function () {
31 const result
= th
.dateOrNot(date
, otherwise
);
32 assert
.strictEqual(result
, date
.toString());
34 it('covers no date', function () {
36 const result
= th
.dateOrNot(date
, otherwise
);
37 assert
.strictEqual(result
, otherwise
);
39 it('covers ms', function () {
40 const result
= th
.dateOrNot(date
.getTime(), otherwise
);
41 assert
.strictEqual(result
, date
.toString());
43 it('covers naught', function () {
44 const result
= th
.dateOrNot(0, otherwise
);
45 assert
.strictEqual(result
, otherwise
);
47 it('covers the infinite', function () {
48 const result
= th
.dateOrNot(-Infinity
, otherwise
);
49 assert
.strictEqual(result
, otherwise
);
53 describe('dateFormat', function () {
54 it('renders otherwise', function () {
55 const expected
= 'otherwise';
56 const result
= th
.dateFormat(undefined, undefined, undefined, expected
);
57 assert
.strictEqual(result
, expected
);
59 it('handles invalid date', function () {
60 const expected
= 'otherwise';
61 const result
= th
.dateFormat(new Date('bad date'), undefined, undefined, expected
);
62 assert
.strictEqual(result
, expected
);
64 it('renders Infinity', function () {
65 const expected
= 'end of time';
66 const result
= th
.dateFormat(Infinity
, expected
);
67 assert
.strictEqual(result
, expected
);
69 it('renders -Infinity', function () {
70 const expected
= 'beginning of time';
71 const result
= th
.dateFormat(-Infinity
, undefined, expected
);
72 assert
.strictEqual(result
, expected
);
74 it('renders a Date', function () {
75 const expected
= 'Mar 27, 2022, 3:28:05 PM PDT';
76 const result
= th
.dateFormat(new Date('2022-03-27T22:28:05.049Z'));
77 assert
.strictEqual(result
, expected
);
79 it('renders a timestamp', function () {
80 const expected
= 'Mar 27, 2022, 3:28:05 PM PDT';
81 const result
= th
.dateFormat(1648420085049);
82 assert
.strictEqual(result
, expected
);
86 describe('timeElement', function () {
87 it('renders a date', function () {
88 const when
= new Date('2022-09-11T21:17:56.872Z');
89 const expected
= '<time datetime="2022-09-11T21:17:56.872Z">Sep 11, 2022, 2:17:56 PM PDT</time>';
90 const result
= th
.timeElement(when
);
91 assert
.strictEqual(result
, expected
);
93 it('covers title', function () {
94 const when
= new Date('2022-09-11T21:17:56.872Z');
95 const expected
= '<time title="a date" datetime="2022-09-11T21:17:56.872Z">Sep 11, 2022, 2:17:56 PM PDT</time>';
96 const result
= th
.timeElement(when
, { title: 'a date' });
97 assert
.strictEqual(result
, expected
);
99 it('covers other', function () {
100 const expected
= '<time>Mar 27, 2022, 3:28:05 PM PDT</time>';
101 const result
= th
.timeElement(1648420085049);
102 assert
.strictEqual(result
, expected
);
106 describe('secondsToPeriod', function () {
107 it('covers seconds', function () {
108 const result
= th
.secondsToPeriod(45);
109 assert
.strictEqual(result
, '45 seconds');
111 it('covers minutes', function () {
112 const result
= th
.secondsToPeriod(105);
113 assert
.strictEqual(result
, '1 minute 45 seconds');
115 it('covers hours', function () {
116 const result
= th
.secondsToPeriod(3705);
117 assert
.strictEqual(result
, '1 hour 1 minute 45 seconds');
119 it('covers days', function () {
120 const result
= th
.secondsToPeriod(90105);
121 assert
.strictEqual(result
, '1 day 1 hour 1 minute 45 seconds');
123 it('covers months', function () {
124 const result
= th
.secondsToPeriod(5274105);
125 assert
.strictEqual(result
, '2 months 1 day 1 hour 1 minute 45 seconds');
127 }); // secondsToPeriod
129 describe('htmlHead', function () {
130 it('covers', function () {
131 const result
= th
.htmlHead(pagePathLevel
, ctx
, options
);
134 it('covers elements', function () {
135 options
.headElements
= [ '<div>foop</div>', '<div>poof</div>' ];
136 const result
= th
.htmlHead(pagePathLevel
, ctx
, options
);
139 it('covers onLoad', function () {
140 options
.onload
= 'onLoadFn';
141 const result
= th
.htmlHead(pagePathLevel
, ctx
, options
);
146 describe('renderNavLink', function () {
148 beforeEach(function () {
150 href: 'https://example.com/',
154 it('covers no class', function () {
155 const result
= th
.renderNavLink(nav
);
158 it('covers class', function () {
159 nav
.class = 'foo bar';
160 const result
= th
.renderNavLink(nav
);
165 describe('OL', function () {
166 it('covers', function () {
167 const result
= th
.OL(['item', 'another item'], 1, { class: 'class' }, (item
) => ({ class: `${item}-class` }));
170 it('covers defaults', function () {
171 const result
= th
.OL([]);
176 describe('UL', function () {
177 it('covers', function () {
178 const result
= th
.UL(['item', 'another item'], 1, { class: 'class' }, (item
) => ({ class: `${item}-class` }));
181 it('covers defaults', function () {
182 const result
= th
.UL([]);
187 describe('LI', function () {
188 it('covers defaults', function () {
189 const result
= th
.LI('item');
194 describe('indented', function () {
195 it('covers', function () {
196 const result
= th
.indented(2, ['foo', 'bar']);
197 result
.forEach((r
) => assert(r
.startsWith('\t\t')));
201 describe('htmlBody', function () {
202 it('covers no main', function () {
203 const result
= th
.htmlBody(pagePathLevel
, ctx
, options
);
208 describe('htmlHeader', function () {
209 it('covers no links', function () {
210 const result
= th
.htmlHeader(pagePathLevel
, ctx
, options
);
213 it('covers links and logo', function () {
216 href: 'https://exmaple.com/',
220 options
.logoUrl
= '/static/logo.svg';
221 const result
= th
.htmlHeader(pagePathLevel
, ctx
, options
);
226 describe('htmlFooter', function () {
227 it('covers', function () {
228 options
.footerEntries
= [
232 const result
= th
.htmlFooter(ctx
, options
);
235 it('covers default', function () {
236 const result
= th
.htmlFooter(ctx
, options
);
241 describe('htmlMessages', function () {
242 it('covers', function () {
243 ctx
.errors
= ['an error'];
244 ctx
.notifications
= ['a notification'];
245 options
.errorHeading
= 'Errors';
246 options
.notificationHeading
= 'Notices';
247 options
.errorContent
= ['<p>Message about errors.</p>'];
248 options
.notificationContent
= ['<p>Message about notifications.</p>'];
249 const result
= th
.htmlMessages(ctx
, options
);
254 describe('htmlPage', function () {
256 beforeEach(function () {
259 it('covers', function () {
260 const result
= th
.htmlPage(pagePathLevel
, ctx
, options
, main
);
264 it('covers defaults', function () {
265 const result
= th
.htmlPage(pagePathLevel
, ctx
, options
, main
);
269 it('covers user', function () {
271 authenticatedProfile: 'https://user.example.com/',
273 const result
= th
.htmlPage(pagePathLevel
, ctx
, options
, main
);
277 it('covers user at root path', function () {
279 authenticatedIdentifier: 'user',
282 const result
= th
.htmlPage(pagePathLevel
, ctx
, options
, main
);
286 it('covers logout redirect', function () {
288 authenticatedIdentifier: 'user',
290 ctx
.url
= 'https://app.example.com/this_page';
291 const result
= th
.htmlPage(pagePathLevel
, ctx
, options
, main
);
295 it('covers existing navLinks', function () {
297 authenticatedIdentifier: 'user',
299 options
.navLinks
= [{
303 const result
= th
.htmlPage(pagePathLevel
, ctx
, options
);