ec7ab5da605315edb2cee3647c938b696944c8f7
4 const assert
= require('assert');
5 const th
= require('../../lib/template-helper');
6 const stubLogger
= require('../stub-logger');
8 const { makeHtmlLint
} = require('../lint-html');
9 const { HtmlValidate
} = require('html-validate');
10 const htmlValidate
= new HtmlValidate();
11 const htmlLint
= makeHtmlLint(stubLogger
, htmlValidate
);
13 describe('Template Helper', function () {
14 let ctx
, options
, pagePathLevel
;
16 beforeEach(function () {
20 pageTitle: 'Test Page',
24 describe('initContext', function () {
25 it('covers', function () {
28 assert(ctx
.notifications
);
29 assert(Array
.isArray(ctx
.errors
));
30 assert(Array
.isArray(ctx
.notifications
));
34 describe('dateOrNot', function () {
36 beforeEach(function () {
38 otherwise
= 'otherwise';
40 it('covers', function () {
41 const result
= th
.dateOrNot(date
, otherwise
);
42 assert
.strictEqual(result
, date
.toString());
44 it('covers no date', function () {
46 const result
= th
.dateOrNot(date
, otherwise
);
47 assert
.strictEqual(result
, otherwise
);
49 it('covers ms', function () {
50 const result
= th
.dateOrNot(date
.getTime(), otherwise
);
51 assert
.strictEqual(result
, date
.toString());
53 it('covers naught', function () {
54 const result
= th
.dateOrNot(0, otherwise
);
55 assert
.strictEqual(result
, otherwise
);
57 it('covers the infinite', function () {
58 const result
= th
.dateOrNot(-Infinity
, otherwise
);
59 assert
.strictEqual(result
, otherwise
);
63 describe('dateFormat', function () {
64 it('renders otherwise', function () {
65 const expected
= 'otherwise';
66 const result
= th
.dateFormat(undefined, undefined, undefined, expected
);
67 assert
.strictEqual(result
, expected
);
69 it('handles invalid date', function () {
70 const expected
= 'otherwise';
71 const result
= th
.dateFormat(new Date('bad date'), undefined, undefined, expected
);
72 assert
.strictEqual(result
, expected
);
74 it('renders Infinity', function () {
75 const expected
= 'end of time';
76 const result
= th
.dateFormat(Infinity
, expected
);
77 assert
.strictEqual(result
, expected
);
79 it('renders -Infinity', function () {
80 const expected
= 'beginning of time';
81 const result
= th
.dateFormat(-Infinity
, undefined, expected
);
82 assert
.strictEqual(result
, expected
);
84 it('renders a Date', function () {
85 const expected
= 'Mar 27, 2022, 3:28:05 PM PDT';
86 const result
= th
.dateFormat(new Date('2022-03-27T22:28:05.049Z'));
87 assert
.strictEqual(result
, expected
);
89 it('renders a timestamp', function () {
90 const expected
= 'Mar 27, 2022, 3:28:05 PM PDT';
91 const result
= th
.dateFormat(1648420085049);
92 assert
.strictEqual(result
, expected
);
96 describe('timeElement', function () {
97 it('renders a date', function () {
98 const when
= new Date('2022-09-11T21:17:56.872Z');
99 const expected
= '<time datetime="2022-09-11T21:17:56.872Z">Sep 11, 2022, 2:17:56 PM PDT</time>';
100 const result
= th
.timeElement(when
);
101 assert
.strictEqual(result
, expected
);
103 it('covers title', function () {
104 const when
= new Date('2022-09-11T21:17:56.872Z');
105 const expected
= '<time title="a date" datetime="2022-09-11T21:17:56.872Z">Sep 11, 2022, 2:17:56 PM PDT</time>';
106 const result
= th
.timeElement(when
, { title: 'a date' });
107 assert
.strictEqual(result
, expected
);
109 it('covers other', function () {
110 const expected
= '<time>Mar 27, 2022, 3:28:05 PM PDT</time>';
111 const result
= th
.timeElement(1648420085049);
112 assert
.strictEqual(result
, expected
);
116 describe('secondsToPeriod', function () {
117 it('covers seconds', function () {
118 const result
= th
.secondsToPeriod(45);
119 assert
.strictEqual(result
, '45 seconds');
121 it('covers minutes', function () {
122 const result
= th
.secondsToPeriod(105);
123 assert
.strictEqual(result
, '1 minute 45 seconds');
125 it('covers hours', function () {
126 const result
= th
.secondsToPeriod(3705);
127 assert
.strictEqual(result
, '1 hour 1 minute 45 seconds');
129 it('covers days', function () {
130 const result
= th
.secondsToPeriod(90105);
131 assert
.strictEqual(result
, '1 day 1 hour 1 minute 45 seconds');
133 it('covers months', function () {
134 const result
= th
.secondsToPeriod(5274105);
135 assert
.strictEqual(result
, '2 months 1 day 1 hour 1 minute 45 seconds');
137 }); // secondsToPeriod
139 describe('htmlHead', function () {
140 it('covers', function () {
141 const result
= th
.htmlHead(pagePathLevel
, ctx
, options
);
144 it('covers elements', function () {
145 options
.headElements
= [ '<div>foop</div>', '<div>poof</div>' ];
146 const result
= th
.htmlHead(pagePathLevel
, ctx
, options
);
149 it('covers onLoad', function () {
150 options
.onload
= 'onLoadFn';
151 const result
= th
.htmlHead(pagePathLevel
, ctx
, options
);
156 describe('renderNavLink', function () {
158 beforeEach(function () {
160 href: 'https://example.com/',
164 it('covers no class', function () {
165 const result
= th
.renderNavLink(nav
);
168 it('covers class', function () {
169 nav
.class = 'foo bar';
170 const result
= th
.renderNavLink(nav
);
175 describe('OL', function () {
176 it('covers', function () {
177 const result
= th
.OL(['item', 'another item'], 1, { class: 'class' }, (item
) => ({ class: `${item}-class` }));
180 it('covers defaults', function () {
181 const result
= th
.OL([]);
186 describe('UL', function () {
187 it('covers', function () {
188 const result
= th
.UL(['item', 'another item'], 1, { class: 'class' }, (item
) => ({ class: `${item}-class` }));
191 it('covers defaults', function () {
192 const result
= th
.UL([]);
197 describe('LI', function () {
198 it('covers defaults', function () {
199 const result
= th
.LI('item');
204 describe('indented', function () {
205 it('covers', function () {
206 const result
= th
.indented(2, ['foo', 'bar']);
207 result
.forEach((r
) => assert(r
.startsWith('\t\t')));
211 describe('htmlBody', function () {
212 it('covers no main', function () {
213 const result
= th
.htmlBody(pagePathLevel
, ctx
, options
);
218 describe('htmlHeader', function () {
219 it('covers no links', function () {
220 const result
= th
.htmlHeader(pagePathLevel
, ctx
, options
);
223 it('covers links and logo', function () {
226 href: 'https://exmaple.com/',
230 options
.logoUrl
= '/static/logo.svg';
231 const result
= th
.htmlHeader(pagePathLevel
, ctx
, options
);
236 describe('htmlFooter', function () {
237 it('covers', function () {
238 options
.footerEntries
= [
242 const result
= th
.htmlFooter(ctx
, options
);
245 it('covers default', function () {
246 const result
= th
.htmlFooter(ctx
, options
);
251 describe('htmlMessages', function () {
252 it('covers', function () {
253 ctx
.errors
= ['an error'];
254 ctx
.notifications
= ['a notification'];
255 options
.errorHeading
= 'Errors';
256 options
.notificationHeading
= 'Notices';
257 options
.errorContent
= ['<p>Message about errors.</p>'];
258 options
.notificationContent
= ['<p>Message about notifications.</p>'];
259 const result
= th
.htmlMessages(ctx
, options
);
264 describe('htmlPage', function () {
266 beforeEach(function () {
269 it('covers', async
function () {
270 const result
= th
.htmlPage(pagePathLevel
, ctx
, options
, main
);
271 await
htmlLint(result
);
274 it('covers defaults', async
function () {
275 const result
= th
.htmlPage(pagePathLevel
, ctx
, options
, main
);
276 await
htmlLint(result
);
279 it('covers user', async
function () {
281 authenticatedProfile: 'https://user.example.com/',
283 const result
= th
.htmlPage(pagePathLevel
, ctx
, options
, main
);
284 await
htmlLint(result
);
287 it('covers user at root path', async
function () {
289 authenticatedIdentifier: 'user',
292 const result
= th
.htmlPage(pagePathLevel
, ctx
, options
, main
);
293 await
htmlLint(result
);
296 it('covers logout redirect', async
function () {
298 authenticatedIdentifier: 'user',
300 ctx
.url
= 'https://app.example.com/this_page';
301 const result
= th
.htmlPage(pagePathLevel
, ctx
, options
, main
);
302 await
htmlLint(result
);
305 it('covers existing navLinks', async
function () {
307 authenticatedIdentifier: 'user',
309 options
.navLinks
= [{
313 const result
= th
.htmlPage(pagePathLevel
, ctx
, options
);
314 await
htmlLint(result
);