Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
fastify
GitHub Repository: fastify/point-of-view
Path: blob/main/test/ejs.test.js
107 views
1
'use strict'
2
3
const { test } = require('node:test')
4
const Fastify = require('fastify')
5
const fs = require('node:fs')
6
const path = require('node:path')
7
const minifier = require('html-minifier-terser')
8
const minifierOpts = {
9
removeComments: true,
10
removeCommentsFromCDATA: true,
11
collapseWhitespace: true,
12
collapseBooleanAttributes: true,
13
removeAttributeQuotes: true,
14
removeEmptyAttributes: true
15
}
16
17
test('reply.view with ejs engine and custom templates folder', async t => {
18
t.plan(4)
19
const fastify = Fastify()
20
const ejs = require('ejs')
21
const data = { text: 'text' }
22
23
fastify.register(require('../index'), {
24
engine: {
25
ejs
26
},
27
templates: 'templates'
28
})
29
30
fastify.get('/', (_req, reply) => {
31
reply.view('index.ejs', data)
32
})
33
34
await fastify.listen({ port: 0 })
35
36
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
37
38
const responseContent = await result.text()
39
40
t.assert.strictEqual(result.status, 200)
41
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
42
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
43
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
44
45
await fastify.close()
46
})
47
48
test('reply.view with ejs engine with layout option', async t => {
49
t.plan(4)
50
const fastify = Fastify()
51
const ejs = require('ejs')
52
const data = { text: 'text' }
53
54
fastify.register(require('../index'), {
55
engine: {
56
ejs
57
},
58
root: path.join(__dirname, '../templates'),
59
layout: 'layout.html'
60
})
61
62
fastify.get('/', (_req, reply) => {
63
reply.view('index-for-layout.ejs', data)
64
})
65
66
await fastify.listen({ port: 0 })
67
68
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
69
70
const responseContent = await result.text()
71
72
t.assert.strictEqual(result.status, 200)
73
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
74
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
75
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
76
77
await fastify.close()
78
})
79
80
test('reply.view with ejs engine with layout option on render', async t => {
81
t.plan(4)
82
const fastify = Fastify()
83
const ejs = require('ejs')
84
const data = { text: 'text' }
85
86
fastify.register(require('../index'), {
87
engine: {
88
ejs
89
},
90
root: path.join(__dirname, '../templates')
91
})
92
93
fastify.get('/', (_req, reply) => {
94
reply.view('index-for-layout.ejs', data, { layout: 'layout.html' })
95
})
96
97
await fastify.listen({ port: 0 })
98
99
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
100
101
const responseContent = await result.text()
102
103
t.assert.strictEqual(result.status, 200)
104
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
105
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
106
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
107
108
await fastify.close()
109
})
110
111
test('reply.view should return 500 if layout is missing on render', async t => {
112
t.plan(1)
113
const fastify = Fastify()
114
const ejs = require('ejs')
115
const data = { text: 'text' }
116
fastify.register(require('../index'), {
117
engine: {
118
ejs
119
},
120
root: path.join(__dirname, '../templates')
121
})
122
123
fastify.get('/', (_req, reply) => {
124
reply.view('index-for-layout.ejs', data, { layout: 'non-existing-layout.html' })
125
})
126
127
await fastify.listen({ port: 0 })
128
129
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
130
131
t.assert.strictEqual(result.status, 500)
132
133
await fastify.close()
134
})
135
136
test('reply.view with ejs engine and custom ext', async t => {
137
t.plan(4)
138
const fastify = Fastify()
139
const ejs = require('ejs')
140
const data = { text: 'text' }
141
142
fastify.register(require('../index'), {
143
engine: {
144
ejs
145
},
146
templates: 'templates',
147
viewExt: 'ejs'
148
})
149
150
fastify.get('/', (_req, reply) => {
151
reply.view('index', data)
152
})
153
154
await fastify.listen({ port: 0 })
155
156
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
157
158
const responseContent = await result.text()
159
160
t.assert.strictEqual(result.status, 200)
161
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
162
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
163
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
164
165
await fastify.close()
166
})
167
168
test('reply.view for ejs without data-parameter but defaultContext', async t => {
169
t.plan(4)
170
const fastify = Fastify()
171
const ejs = require('ejs')
172
const data = { text: 'text' }
173
174
fastify.register(require('../index'), {
175
engine: {
176
ejs
177
},
178
defaultContext: data,
179
templates: 'templates'
180
})
181
182
fastify.get('/', (_req, reply) => {
183
reply.view('index.ejs')
184
})
185
186
await fastify.listen({ port: 0 })
187
188
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
189
190
const responseContent = await result.text()
191
192
t.assert.strictEqual(result.status, 200)
193
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
194
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
195
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
196
197
await fastify.close()
198
})
199
200
test('reply.view for ejs without data-parameter but defaultContext', async t => {
201
t.plan(4)
202
const fastify = Fastify()
203
const ejs = require('ejs')
204
const data = { text: 'text' }
205
206
fastify.register(require('../index'), {
207
engine: {
208
ejs
209
},
210
defaultContext: data,
211
templates: 'templates'
212
})
213
214
fastify.get('/', (_req, reply) => {
215
reply.view('index.ejs')
216
})
217
218
await fastify.listen({ port: 0 })
219
220
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
221
222
const responseContent = await result.text()
223
224
t.assert.strictEqual(result.status, 200)
225
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
226
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
227
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
228
229
await fastify.close()
230
})
231
232
test('reply.view for ejs without data-parameter and without defaultContext', async t => {
233
t.plan(4)
234
const fastify = Fastify()
235
const ejs = require('ejs')
236
237
fastify.register(require('../index'), {
238
engine: {
239
ejs
240
},
241
templates: 'templates'
242
})
243
244
fastify.get('/', (_req, reply) => {
245
reply.view('index-bare.html')
246
})
247
248
await fastify.listen({ port: 0 })
249
250
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
251
252
const responseContent = await result.text()
253
254
t.assert.strictEqual(result.status, 200)
255
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
256
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
257
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index-bare.html', 'utf8')), responseContent)
258
259
await fastify.close()
260
})
261
262
test('reply.view for ejs engine without data-parameter and defaultContext but with reply.locals', async t => {
263
t.plan(4)
264
const fastify = Fastify()
265
const ejs = require('ejs')
266
const localsData = { text: 'text from locals' }
267
268
fastify.register(require('../index'), {
269
engine: {
270
ejs
271
}
272
})
273
274
fastify.addHook('preHandler', function (_request, reply, done) {
275
reply.locals = localsData
276
done()
277
})
278
279
fastify.get('/', (_req, reply) => {
280
reply.view('./templates/index-bare.html')
281
})
282
283
await fastify.listen({ port: 0 })
284
285
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
286
287
const responseContent = await result.text()
288
289
t.assert.strictEqual(result.status, 200)
290
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
291
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
292
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index-bare.html', 'utf8'), localsData), responseContent)
293
294
await fastify.close()
295
})
296
297
test('reply.view for ejs engine without defaultContext but with reply.locals and data-parameter', async t => {
298
t.plan(4)
299
const fastify = Fastify()
300
const ejs = require('ejs')
301
const localsData = { text: 'text from locals' }
302
const data = { text: 'text' }
303
304
fastify.register(require('../index'), {
305
engine: {
306
ejs
307
}
308
})
309
310
fastify.addHook('preHandler', function (_request, reply, done) {
311
reply.locals = localsData
312
done()
313
})
314
315
fastify.get('/', (_req, reply) => {
316
reply.view('./templates/index-bare.html', data)
317
})
318
319
await fastify.listen({ port: 0 })
320
321
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
322
323
const responseContent = await result.text()
324
325
t.assert.strictEqual(result.status, 200)
326
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
327
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
328
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index-bare.html', 'utf8'), data), responseContent)
329
330
await fastify.close()
331
})
332
333
test('reply.view for ejs engine without data-parameter but with reply.locals and defaultContext', async t => {
334
t.plan(4)
335
const fastify = Fastify()
336
const ejs = require('ejs')
337
const localsData = { text: 'text from locals' }
338
const contextData = { text: 'text from context' }
339
340
fastify.register(require('../index'), {
341
engine: {
342
ejs
343
},
344
defaultContext: contextData
345
})
346
347
fastify.addHook('preHandler', function (_request, reply, done) {
348
reply.locals = localsData
349
done()
350
})
351
352
fastify.get('/', (_req, reply) => {
353
reply.view('./templates/index-bare.html')
354
})
355
356
await fastify.listen({ port: 0 })
357
358
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
359
360
const responseContent = await result.text()
361
362
t.assert.strictEqual(result.status, 200)
363
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
364
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
365
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index-bare.html', 'utf8'), contextData), responseContent)
366
367
await fastify.close()
368
})
369
370
test('reply.view for ejs engine with data-parameter and reply.locals and defaultContext', async t => {
371
t.plan(4)
372
const fastify = Fastify()
373
const ejs = require('ejs')
374
const localsData = { text: 'text from locals' }
375
const contextData = { text: 'text from context' }
376
const data = { text: 'text' }
377
378
fastify.register(require('../index'), {
379
engine: {
380
ejs
381
},
382
defaultContext: contextData
383
})
384
385
fastify.addHook('preHandler', function (_request, reply, done) {
386
reply.locals = localsData
387
done()
388
})
389
390
fastify.get('/', (_req, reply) => {
391
reply.view('./templates/index-bare.html', data)
392
})
393
394
await fastify.listen({ port: 0 })
395
396
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
397
398
const responseContent = await result.text()
399
400
t.assert.strictEqual(result.status, 200)
401
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
402
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
403
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index-bare.html', 'utf8'), data), responseContent)
404
405
await fastify.close()
406
})
407
408
test('reply.view with ejs engine and full path templates folder', async t => {
409
t.plan(4)
410
const fastify = Fastify()
411
const ejs = require('ejs')
412
const data = { text: 'text' }
413
414
fastify.register(require('../index'), {
415
engine: {
416
ejs
417
},
418
templates: path.join(__dirname, '../templates')
419
})
420
421
fastify.get('/', (_req, reply) => {
422
reply.view('index.ejs', data)
423
})
424
425
await fastify.listen({ port: 0 })
426
427
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
428
429
const responseContent = await result.text()
430
431
t.assert.strictEqual(result.status, 200)
432
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
433
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
434
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
435
436
await fastify.close()
437
})
438
439
test('reply.view with ejs engine', async t => {
440
t.plan(4)
441
const fastify = Fastify()
442
const ejs = require('ejs')
443
const data = { text: 'text' }
444
445
fastify.register(require('../index'), {
446
engine: {
447
ejs
448
}
449
})
450
451
fastify.get('/', (_req, reply) => {
452
reply.view('templates/index.ejs', data)
453
})
454
455
await fastify.listen({ port: 0 })
456
457
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
458
459
const responseContent = await result.text()
460
461
t.assert.strictEqual(result.status, 200)
462
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
463
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
464
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
465
466
await fastify.close()
467
})
468
469
test('reply.view with ejs engine and defaultContext', async t => {
470
t.plan(4)
471
const fastify = Fastify()
472
const ejs = require('ejs')
473
const data = { text: 'text' }
474
475
fastify.register(require('../index'), {
476
engine: {
477
ejs
478
},
479
defaultContext: data
480
})
481
482
fastify.get('/', (_req, reply) => {
483
reply.view('templates/index.ejs', {})
484
})
485
486
await fastify.listen({ port: 0 })
487
488
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
489
490
const responseContent = await result.text()
491
492
t.assert.strictEqual(result.status, 200)
493
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
494
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
495
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
496
497
await fastify.close()
498
})
499
500
test('reply.view with ejs engine and html-minifier-terser', async t => {
501
t.plan(4)
502
const fastify = Fastify()
503
const ejs = require('ejs')
504
const data = { text: 'text' }
505
506
fastify.register(require('../index'), {
507
engine: {
508
ejs
509
},
510
options: {
511
useHtmlMinifier: minifier,
512
htmlMinifierOptions: minifierOpts
513
}
514
})
515
516
fastify.get('/', (_req, reply) => {
517
reply.view('templates/index.ejs', data)
518
})
519
520
await fastify.listen({ port: 0 })
521
522
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
523
524
const responseContent = await result.text()
525
526
t.assert.strictEqual(result.status, 200)
527
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
528
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
529
t.assert.strictEqual(await minifier.minify(await ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), minifierOpts), responseContent)
530
531
await fastify.close()
532
})
533
534
test('reply.view with ejs engine and paths excluded from html-minifier-terser', async t => {
535
t.plan(4)
536
const fastify = Fastify()
537
const ejs = require('ejs')
538
const data = { text: 'text' }
539
540
fastify.register(require('../index'), {
541
engine: {
542
ejs
543
},
544
options: {
545
useHtmlMinifier: minifier,
546
htmlMinifierOptions: minifierOpts,
547
pathsToExcludeHtmlMinifier: ['/test']
548
}
549
})
550
551
fastify.get('/test', (_req, reply) => {
552
reply.view('templates/index.ejs', data)
553
})
554
555
await fastify.listen({ port: 0 })
556
557
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port + '/test')
558
559
const responseContent = await result.text()
560
561
t.assert.strictEqual(result.status, 200)
562
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
563
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
564
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
565
566
await fastify.close()
567
})
568
test('reply.view with ejs engine and html-minifier-terser in production mode', async t => {
569
const numTests = 5
570
t.plan(numTests * 4)
571
const fastify = Fastify()
572
const ejs = require('ejs')
573
const data = { text: 'text' }
574
575
fastify.register(require('../index'), {
576
engine: { ejs },
577
production: true,
578
options: {
579
useHtmlMinifier: minifier,
580
htmlMinifierOptions: minifierOpts
581
}
582
})
583
584
fastify.get('/', (_req, reply) => {
585
reply.view('templates/index.ejs', data)
586
})
587
588
await fastify.listen({ port: 0 })
589
590
for (let i = 0; i < numTests; i++) {
591
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
592
593
const responseContent = await result.text()
594
595
t.assert.strictEqual(result.status, 200)
596
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
597
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
598
t.assert.strictEqual(await minifier.minify(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), minifierOpts), responseContent)
599
600
if (i === numTests - 1) fastify.close()
601
}
602
})
603
604
test('reply.view with ejs engine and includeViewExtension property as true', async t => {
605
t.plan(4)
606
const fastify = Fastify()
607
const ejs = require('ejs')
608
const data = { text: 'text' }
609
610
fastify.register(require('../index'), {
611
engine: {
612
ejs
613
},
614
includeViewExtension: true
615
})
616
617
fastify.get('/', (_req, reply) => {
618
reply.view('templates/index', data)
619
})
620
621
await fastify.listen({ port: 0 })
622
623
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
624
625
const responseContent = await result.text()
626
627
t.assert.strictEqual(result.status, 200)
628
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
629
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
630
t.assert.strictEqual(await ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
631
632
await fastify.close()
633
})
634
635
test('*** reply.view with ejs engine with layout option, includeViewExtension property as true ***', async t => {
636
t.plan(4)
637
const fastify = Fastify()
638
const ejs = require('ejs')
639
const data = { text: 'text' }
640
const header = ''
641
const footer = ''
642
643
fastify.register(require('../index'), {
644
engine: {
645
ejs
646
},
647
defaultContext: {
648
header,
649
footer
650
},
651
includeViewExtension: true,
652
root: path.join(__dirname, '../templates'),
653
layout: 'layout-with-includes'
654
})
655
656
fastify.get('/', (_req, reply) => {
657
reply.view('index-for-layout.ejs', data)
658
})
659
660
await fastify.listen({ port: 0 })
661
662
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
663
664
const responseContent = await result.text()
665
666
t.assert.strictEqual(result.status, 200)
667
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
668
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
669
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), {
670
...data,
671
header,
672
footer
673
}), responseContent)
674
675
await fastify.close()
676
})
677
678
test('*** reply.view with ejs engine with layout option on render, includeViewExtension property as true ***', async t => {
679
t.plan(4)
680
const fastify = Fastify()
681
const ejs = require('ejs')
682
const data = { text: 'text' }
683
const header = ''
684
const footer = ''
685
686
fastify.register(require('../index'), {
687
engine: {
688
ejs
689
},
690
defaultContext: {
691
header,
692
footer
693
},
694
includeViewExtension: true,
695
root: path.join(__dirname, '../templates')
696
})
697
698
fastify.get('/', (_req, reply) => {
699
reply.view('index-for-layout.ejs', data, { layout: 'layout-with-includes' })
700
})
701
702
await fastify.listen({ port: 0 })
703
704
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
705
706
const responseContent = await result.text()
707
708
t.assert.strictEqual(result.status, 200)
709
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
710
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
711
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), {
712
...data,
713
header,
714
footer
715
}), responseContent)
716
717
await fastify.close()
718
})
719
720
test('reply.view with ejs engine, template folder specified, include files (ejs and html) used in template, includeViewExtension property as true', async t => {
721
t.plan(5)
722
const fastify = Fastify()
723
const ejs = require('ejs')
724
const resolve = require('node:path').resolve
725
const templatesFolder = 'templates'
726
const options = {
727
filename: resolve(templatesFolder), // needed for include files to be resolved in include directive ...
728
views: [__dirname] // must be put to make tests (with include files) working ...
729
}
730
const data = { text: 'text' }
731
732
fastify.register(require('../index'), {
733
engine: {
734
ejs
735
},
736
includeViewExtension: true,
737
templates: templatesFolder
738
// Options not necessary now
739
})
740
741
fastify.get('/', (_req, reply) => {
742
reply.type('text/html; charset=utf-8').view('index-linking-other-pages', data) // sample for specifying with type
743
// reply.view('index-with-includes', data)
744
})
745
746
await fastify.listen({ port: 0 })
747
748
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
749
750
const responseContent = await result.text()
751
752
t.assert.strictEqual(result.status, 200)
753
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
754
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
755
756
await new Promise((resolve) => {
757
ejs.renderFile(templatesFolder + '/index-linking-other-pages.ejs', data, options, function (err, str) {
758
t.assert.ifError(err)
759
t.assert.strictEqual(str.length, responseContent.length)
760
resolve()
761
})
762
})
763
764
await fastify.close()
765
})
766
767
test('reply.view with ejs engine, templates with folder specified, include files and attributes; home', async t => {
768
t.plan(5)
769
const fastify = Fastify()
770
const ejs = require('ejs')
771
const resolve = require('node:path').resolve
772
const templatesFolder = 'templates'
773
const options = {
774
filename: resolve(templatesFolder),
775
views: [__dirname]
776
}
777
const data = { text: 'Hello from EJS Templates' }
778
779
fastify.register(require('../index'), {
780
engine: {
781
ejs
782
},
783
includeViewExtension: true,
784
templates: templatesFolder,
785
options
786
})
787
788
fastify.get('/', (_req, reply) => {
789
reply.type('text/html; charset=utf-8').view('index', data)
790
})
791
792
await fastify.listen({ port: 0 })
793
794
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
795
796
const responseContent = await result.text()
797
798
t.assert.strictEqual(result.status, 200)
799
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
800
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
801
802
await new Promise((resolve) => {
803
ejs.renderFile(templatesFolder + '/index.ejs', data, options, function (err, str) {
804
t.assert.ifError(err)
805
t.assert.strictEqual(str.length, responseContent.length)
806
resolve()
807
})
808
})
809
810
await fastify.close()
811
})
812
813
test('reply.view with ejs engine, templates with folder specified, include files and attributes; page with no data', async t => {
814
t.plan(5)
815
const fastify = Fastify()
816
const ejs = require('ejs')
817
const resolve = require('node:path').resolve
818
const templatesFolder = 'templates'
819
const options = {
820
filename: resolve(templatesFolder),
821
views: [__dirname]
822
}
823
824
fastify.register(require('../index'), {
825
engine: {
826
ejs
827
},
828
includeViewExtension: true,
829
templates: templatesFolder,
830
options
831
})
832
833
fastify.get('/no-data-test', (_req, reply) => {
834
reply.type('text/html; charset=utf-8').view('index-with-no-data')
835
})
836
837
await fastify.listen({ port: 0 })
838
839
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port + '/no-data-test')
840
841
const responseContent = await result.text()
842
843
t.assert.strictEqual(result.status, 200)
844
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
845
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
846
847
await new Promise((resolve) => {
848
ejs.renderFile(templatesFolder + '/index-with-no-data.ejs', null, options, function (err, str) {
849
t.assert.ifError(err)
850
t.assert.strictEqual(str.length, responseContent.length)
851
resolve()
852
})
853
})
854
855
await fastify.close()
856
})
857
858
test('reply.view with ejs engine, templates with folder specified, include files and attributes; page with includes', async t => {
859
t.plan(5)
860
const fastify = Fastify()
861
const ejs = require('ejs')
862
const resolve = require('node:path').resolve
863
const templatesFolder = 'templates'
864
const options = {
865
filename: resolve(templatesFolder),
866
views: [path.join(__dirname, '..')]
867
}
868
869
const data = { text: 'Hello from EJS Templates' }
870
871
fastify.register(require('../index'), {
872
engine: {
873
ejs
874
},
875
includeViewExtension: true,
876
templates: templatesFolder,
877
options
878
})
879
880
fastify.get('/include-test', (_req, reply) => {
881
reply.type('text/html; charset=utf-8').view('index-with-includes', data)
882
})
883
884
await fastify.listen({ port: 0 })
885
886
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port + '/include-test')
887
888
const responseContent = await result.text()
889
890
t.assert.strictEqual(result.status, 200)
891
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
892
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
893
894
await new Promise((resolve) => {
895
ejs.renderFile(templatesFolder + '/index-with-includes.ejs', data, options, function (err, str) {
896
t.assert.ifError(err)
897
t.assert.strictEqual(str.length, responseContent.length)
898
resolve()
899
})
900
})
901
902
await fastify.close()
903
})
904
905
test('reply.view with ejs engine, templates with folder specified, include files and attributes; page with one include missing', async t => {
906
t.plan(5)
907
const fastify = Fastify()
908
const ejs = require('ejs')
909
const resolve = require('node:path').resolve
910
const templatesFolder = 'templates'
911
const options = {
912
filename: resolve(templatesFolder),
913
views: [__dirname]
914
}
915
const data = { text: 'Hello from EJS Templates' }
916
917
fastify.register(require('../index'), {
918
engine: {
919
ejs
920
},
921
includeViewExtension: true,
922
templates: templatesFolder,
923
options
924
})
925
926
fastify.get('/include-one-include-missing-test', (_req, reply) => {
927
reply.type('text/html; charset=utf-8').view('index-with-includes-one-missing', data)
928
})
929
930
await fastify.listen({ port: 0 })
931
932
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port + '/include-one-include-missing-test')
933
934
const responseContent = await result.text()
935
936
t.assert.strictEqual(result.status, 500)
937
t.assert.strictEqual(result.headers.get('content-type'), 'application/json; charset=utf-8')
938
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
939
940
await new Promise((resolve) => {
941
ejs.renderFile(templatesFolder + '/index-with-includes-one-missing.ejs', data, options, function (err, str) {
942
t.assert.ok(err)
943
t.assert.strictEqual(str, undefined)
944
resolve()
945
})
946
})
947
948
await fastify.close()
949
})
950
951
test('reply.view with ejs engine, templates with folder specified, include files and attributes; page with one attribute missing', async t => {
952
t.plan(5)
953
const fastify = Fastify()
954
const ejs = require('ejs')
955
const resolve = require('node:path').resolve
956
const templatesFolder = 'templates'
957
const options = {
958
filename: resolve(templatesFolder),
959
views: [__dirname]
960
}
961
const data = { text: 'Hello from EJS Templates' }
962
963
fastify.register(require('../index'), {
964
engine: {
965
ejs
966
},
967
includeViewExtension: true,
968
templates: templatesFolder,
969
options
970
})
971
972
fastify.get('/include-one-attribute-missing-test', (_req, reply) => {
973
reply.type('text/html; charset=utf-8').view('index-with-includes-and-attribute-missing', data)
974
})
975
976
await fastify.listen({ port: 0 })
977
978
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port + '/include-one-attribute-missing-test')
979
980
const responseContent = await result.text()
981
982
t.assert.strictEqual(result.status, 500)
983
t.assert.strictEqual(result.headers.get('content-type'), 'application/json; charset=utf-8')
984
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
985
986
await new Promise((resolve) => {
987
ejs.renderFile(templatesFolder + '/index-with-includes-and-attribute-missing.ejs', data, options, function (err, str) {
988
t.assert.ok(err)
989
t.assert.strictEqual(str, undefined)
990
resolve()
991
})
992
})
993
994
await fastify.close()
995
})
996
997
test('fastify.view with ejs engine, missing template file', (t, done) => {
998
t.plan(3)
999
const fastify = Fastify()
1000
const ejs = require('ejs')
1001
1002
fastify.register(require('../index'), {
1003
engine: {
1004
ejs
1005
}
1006
})
1007
1008
fastify.ready(err => {
1009
t.assert.ifError(err)
1010
1011
fastify.view('./missing.html', {}, err => {
1012
t.assert.ok(err instanceof Error)
1013
t.assert.strictEqual(err.message, `ENOENT: no such file or directory, open '${path.join(__dirname, '../missing.html')}'`)
1014
fastify.close()
1015
done()
1016
})
1017
})
1018
})
1019
1020
test('fastify.view with ejs engine and callback in production mode', (t, done) => {
1021
t.plan(6)
1022
const fastify = Fastify()
1023
const ejs = require('ejs')
1024
const data = { text: 'text' }
1025
1026
fastify.register(require('../index'), {
1027
engine: {
1028
ejs
1029
},
1030
production: true
1031
})
1032
1033
fastify.ready(err => {
1034
t.assert.ifError(err)
1035
1036
fastify.view('templates/index.ejs', data, (err, compiled) => {
1037
t.assert.ifError(err)
1038
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), compiled)
1039
1040
fastify.ready(err => {
1041
t.assert.ifError(err)
1042
1043
fastify.view('templates/index.ejs', data, (err, compiled) => {
1044
t.assert.ifError(err)
1045
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), compiled)
1046
fastify.close()
1047
done()
1048
})
1049
})
1050
})
1051
})
1052
})
1053
1054
test('reply.view with ejs engine and raw template', async t => {
1055
t.plan(4)
1056
const fastify = Fastify()
1057
const ejs = require('ejs')
1058
const data = { text: 'text' }
1059
1060
fastify.register(require('../index'), {
1061
engine: {
1062
ejs
1063
}
1064
})
1065
1066
fastify.get('/', (_req, reply) => {
1067
reply.view({ raw: fs.readFileSync('./templates/index.ejs', 'utf8') }, data)
1068
})
1069
1070
await fastify.listen({ port: 0 })
1071
1072
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
1073
1074
const responseContent = await result.text()
1075
1076
t.assert.strictEqual(result.status, 200)
1077
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
1078
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
1079
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
1080
1081
await fastify.close()
1082
})
1083
1084
test('reply.view with ejs engine and function template', async t => {
1085
t.plan(4)
1086
const fastify = Fastify()
1087
const ejs = require('ejs')
1088
const data = { text: 'text' }
1089
1090
fastify.register(require('../index'), {
1091
engine: {
1092
ejs
1093
}
1094
})
1095
1096
fastify.get('/', (_req, reply) => {
1097
reply.view(ejs.compile(fs.readFileSync('./templates/index.ejs', 'utf8')), data)
1098
})
1099
1100
await fastify.listen({ port: 0 })
1101
1102
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
1103
1104
const responseContent = await result.text()
1105
1106
t.assert.strictEqual(result.status, 200)
1107
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
1108
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
1109
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
1110
1111
await fastify.close()
1112
})
1113
1114
test('reply.view with ejs engine and failed call to render when onError hook defined', async t => {
1115
t.plan(3)
1116
const fastify = Fastify()
1117
const ejs = require('ejs')
1118
1119
fastify.register(require('../index'), {
1120
engine: {
1121
ejs
1122
}
1123
})
1124
1125
fastify.get('/invalid', (_req, reply) => {
1126
// Note the mistake in the ternary statement -- the second `?` should be a `:`
1127
reply.view({
1128
raw: '<p><%= true ? "text" ? "text2" %></p>'
1129
})
1130
})
1131
1132
fastify.get('/valid', (_req, reply) => {
1133
reply.view({
1134
raw: '<%= true ? "text" : "text2" %>'
1135
})
1136
})
1137
1138
// when onError hook is defined, certain errors (such as calls to reply.send inside the `onError` hook) are uncaught
1139
fastify.addHook('onError', async () => {})
1140
1141
await fastify.listen({ port: 0 })
1142
1143
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port + '/invalid')
1144
1145
t.assert.strictEqual(result.status, 500)
1146
1147
const result2 = await fetch('http://127.0.0.1:' + fastify.server.address().port + '/valid')
1148
1149
t.assert.strictEqual(await result2.text(), 'text')
1150
t.assert.strictEqual(result2.status, 200)
1151
1152
await fastify.close()
1153
})
1154
1155
test('reply.viewAsync with ejs engine - sync handler', async t => {
1156
t.plan(4)
1157
const fastify = Fastify()
1158
const ejs = require('ejs')
1159
const data = { text: 'text' }
1160
1161
fastify.register(require('../index'), {
1162
engine: {
1163
ejs
1164
}
1165
})
1166
1167
fastify.get('/', async (_req, reply) => {
1168
return reply.viewAsync('templates/index.ejs', data)
1169
})
1170
1171
await fastify.listen({ port: 0 })
1172
1173
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
1174
1175
const responseContent = await result.text()
1176
1177
t.assert.strictEqual(result.status, 200)
1178
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
1179
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
1180
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
1181
1182
await fastify.close()
1183
})
1184
1185
test('reply.viewAsync with ejs engine - async handler', async t => {
1186
t.plan(4)
1187
const fastify = Fastify()
1188
const ejs = require('ejs')
1189
const data = { text: 'text' }
1190
1191
fastify.register(require('../index'), {
1192
engine: {
1193
ejs
1194
}
1195
})
1196
1197
fastify.get('/', (_req, reply) => {
1198
return reply.viewAsync('templates/index.ejs', data)
1199
})
1200
1201
await fastify.listen({ port: 0 })
1202
1203
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
1204
1205
const responseContent = await result.text()
1206
1207
t.assert.strictEqual(result.status, 200)
1208
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
1209
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
1210
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
1211
1212
await fastify.close()
1213
})
1214
1215
test('reply.viewAsync should return 500 if layout is missing on render', async t => {
1216
t.plan(1)
1217
const fastify = Fastify()
1218
const ejs = require('ejs')
1219
const data = { text: 'text' }
1220
fastify.register(require('../index'), {
1221
engine: {
1222
ejs
1223
},
1224
root: path.join(__dirname, '../templates')
1225
})
1226
1227
fastify.get('/', (_req, reply) => {
1228
return reply.viewAsync('index-for-layout.ejs', data, { layout: 'non-existing-layout.html' })
1229
})
1230
1231
await fastify.listen({ port: 0 })
1232
1233
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
1234
1235
t.assert.strictEqual(result.status, 500)
1236
1237
await fastify.close()
1238
})
1239
1240
test('reply.viewAsync should allow errors to be handled by custom error handler', async t => {
1241
t.plan(5)
1242
const fastify = Fastify()
1243
const ejs = require('ejs')
1244
const data = { text: 'text' }
1245
fastify.register(require('../index'), {
1246
engine: {
1247
ejs
1248
},
1249
root: path.join(__dirname, '../templates')
1250
})
1251
1252
fastify.get('/', (_req, reply) => {
1253
return reply.viewAsync('index-for-layout.ejs', data, { layout: 'non-existing-layout.html' })
1254
})
1255
1256
fastify.setErrorHandler((err, _request, reply) => {
1257
t.assert.ok(err instanceof Error)
1258
t.assert.strictEqual(reply.getHeader('Content-Type'), undefined)
1259
return 'something went wrong'
1260
})
1261
1262
await fastify.listen({ port: 0 })
1263
1264
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
1265
1266
t.assert.strictEqual(result.headers.get('content-type'), 'text/plain; charset=utf-8')
1267
t.assert.strictEqual(result.status, 200)
1268
t.assert.strictEqual(await result.text(), 'something went wrong')
1269
1270
await fastify.close()
1271
})
1272
1273
test('reply.viewAsync with ejs engine and custom propertyName', async t => {
1274
t.plan(4)
1275
const fastify = Fastify()
1276
const ejs = require('ejs')
1277
const data = { text: 'text' }
1278
1279
fastify.register(require('../index'), {
1280
engine: {
1281
ejs
1282
},
1283
propertyName: 'render'
1284
})
1285
1286
fastify.get('/', async (_req, reply) => {
1287
return reply.renderAsync('templates/index.ejs', data)
1288
})
1289
1290
await fastify.listen({ port: 0 })
1291
1292
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
1293
1294
const responseContent = await result.text()
1295
1296
t.assert.strictEqual(result.status, 200)
1297
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
1298
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
1299
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
1300
1301
await fastify.close()
1302
})
1303
1304
test('reply.viewAsync with ejs engine and custom asyncPropertyName', async t => {
1305
t.plan(4)
1306
const fastify = Fastify()
1307
const ejs = require('ejs')
1308
const data = { text: 'text' }
1309
1310
fastify.register(require('../index'), {
1311
engine: {
1312
ejs
1313
},
1314
asyncPropertyName: 'viewAsPromise'
1315
})
1316
1317
fastify.get('/', async (_req, reply) => {
1318
return reply.viewAsPromise('templates/index.ejs', data)
1319
})
1320
1321
await fastify.listen({ port: 0 })
1322
1323
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
1324
1325
const responseContent = await result.text()
1326
1327
t.assert.strictEqual(result.status, 200)
1328
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
1329
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
1330
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
1331
1332
await fastify.close()
1333
})
1334
1335
test('reply.viewAsync with ejs engine and custom asyncPropertyName and custom propertyName', async t => {
1336
t.plan(8)
1337
const fastify = Fastify()
1338
const ejs = require('ejs')
1339
const data = { text: 'text' }
1340
1341
fastify.register(require('../index'), {
1342
engine: {
1343
ejs
1344
},
1345
asyncPropertyName: 'renderPromise',
1346
propertyName: 'oldRenderSend'
1347
})
1348
1349
fastify.get('/asyncPropertyName', async (_req, reply) => {
1350
return reply.renderPromise('templates/index.ejs', data)
1351
})
1352
1353
fastify.get('/propertyName', (_req, reply) => {
1354
reply.oldRenderSend('templates/index.ejs', data)
1355
})
1356
1357
await fastify.listen({ port: 0 })
1358
1359
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port + '/asyncPropertyName')
1360
1361
const responseContent = await result.text()
1362
1363
t.assert.strictEqual(result.status, 200)
1364
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
1365
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
1366
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
1367
1368
const result2 = await fetch('http://127.0.0.1:' + fastify.server.address().port + '/propertyName')
1369
1370
const responseContent2 = await result2.text()
1371
1372
t.assert.strictEqual(result2.status, 200)
1373
t.assert.strictEqual(result2.headers.get('content-length'), '' + responseContent.length)
1374
t.assert.strictEqual(result2.headers.get('content-type'), 'text/html; charset=utf-8')
1375
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent2)
1376
1377
await fastify.close()
1378
})
1379
1380
test('reply.viewAsync with ejs engine and conflicting propertyName/asyncPropertyName', async t => {
1381
t.plan(1)
1382
const fastify = Fastify()
1383
const ejs = require('ejs')
1384
1385
fastify.register(require('../index'), {
1386
engine: {
1387
ejs
1388
},
1389
propertyName: 'render',
1390
asyncPropertyName: 'render'
1391
})
1392
1393
await t.assert.rejects(fastify.listen({ port: 0 }))
1394
})
1395
1396