Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
fastify
GitHub Repository: fastify/point-of-view
Path: blob/main/test/handlebars.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 { join } = require('node:path')
7
8
require('./helper').handleBarsHtmlMinifierTests(true)
9
require('./helper').handleBarsHtmlMinifierTests(false)
10
11
test('fastify.view with handlebars engine', (t, end) => {
12
t.plan(2)
13
const fastify = Fastify()
14
const handlebars = require('handlebars')
15
const data = { text: 'text' }
16
17
fastify.register(require('../index'), {
18
engine: {
19
handlebars
20
}
21
})
22
23
fastify.ready(err => {
24
t.assert.ifError(err)
25
26
fastify.view('./templates/index.html', data).then(compiled => {
27
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), compiled)
28
fastify.close()
29
end()
30
})
31
})
32
})
33
34
test('fastify.view for handlebars without data-parameter but defaultContext', (t, end) => {
35
t.plan(2)
36
const fastify = Fastify()
37
const handlebars = require('handlebars')
38
const data = { text: 'text' }
39
40
fastify.register(require('../index'), {
41
engine: {
42
handlebars
43
},
44
defaultContext: data
45
})
46
47
fastify.ready(err => {
48
t.assert.ifError(err)
49
50
fastify.view('./templates/index.html').then(compiled => {
51
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), compiled)
52
fastify.close()
53
end()
54
})
55
})
56
})
57
58
test('fastify.view for handlebars without data-parameter and without defaultContext', (t, end) => {
59
t.plan(2)
60
const fastify = Fastify()
61
const handlebars = require('handlebars')
62
63
fastify.register(require('../index'), {
64
engine: {
65
handlebars
66
}
67
})
68
69
fastify.ready(err => {
70
t.assert.ifError(err)
71
72
fastify.view('./templates/index.html').then(compiled => {
73
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(), compiled)
74
fastify.close()
75
end()
76
})
77
})
78
})
79
80
test('fastify.view with handlebars engine and defaultContext', (t, end) => {
81
t.plan(2)
82
const fastify = Fastify()
83
const handlebars = require('handlebars')
84
85
const data = { text: 'text' }
86
87
fastify.register(require('../index'), {
88
engine: {
89
handlebars
90
},
91
defaultContext: data
92
})
93
94
fastify.ready(err => {
95
t.assert.ifError(err)
96
97
fastify.view('./templates/index.html', {}).then(compiled => {
98
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), compiled)
99
fastify.close()
100
end()
101
})
102
})
103
})
104
105
test('reply.view for handlebars engine without data-parameter and defaultContext but with reply.locals', async t => {
106
t.plan(4)
107
const fastify = Fastify()
108
const handlebars = require('handlebars')
109
const localsData = { text: 'text from locals' }
110
111
fastify.register(require('../index'), {
112
engine: {
113
handlebars
114
}
115
})
116
117
fastify.addHook('preHandler', function (_request, reply, done) {
118
reply.locals = localsData
119
done()
120
})
121
122
fastify.get('/', (_req, reply) => {
123
reply.view('./templates/index.html')
124
})
125
126
await fastify.listen({ port: 0 })
127
128
const result = await fetch('http://localhost:' + fastify.server.address().port)
129
130
const responseContent = await result.text()
131
132
t.assert.strictEqual(result.status, 200)
133
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
134
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
135
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(localsData), responseContent)
136
137
await fastify.close()
138
})
139
140
test('reply.view for handlebars engine without defaultContext but with reply.locals and data-parameter', async t => {
141
t.plan(4)
142
const fastify = Fastify()
143
const handlebars = require('handlebars')
144
const localsData = { text: 'text from locals' }
145
const data = { text: 'text' }
146
147
fastify.register(require('../index'), {
148
engine: {
149
handlebars
150
}
151
})
152
153
fastify.addHook('preHandler', function (_request, reply, done) {
154
reply.locals = localsData
155
done()
156
})
157
158
fastify.get('/', (_req, reply) => {
159
reply.view('./templates/index.html', data)
160
})
161
162
await fastify.listen({ port: 0 })
163
164
const result = await fetch('http://localhost:' + fastify.server.address().port)
165
166
const responseContent = await result.text()
167
168
t.assert.strictEqual(result.status, 200)
169
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
170
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
171
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), responseContent)
172
173
await fastify.close()
174
})
175
176
test('reply.view for handlebars engine without data-parameter but with reply.locals and defaultContext', async t => {
177
t.plan(4)
178
const fastify = Fastify()
179
const handlebars = require('handlebars')
180
const localsData = { text: 'text from locals' }
181
const contextData = { text: 'text from context' }
182
183
fastify.register(require('../index'), {
184
engine: {
185
handlebars
186
},
187
defaultContext: contextData
188
})
189
190
fastify.addHook('preHandler', function (_request, reply, done) {
191
reply.locals = localsData
192
done()
193
})
194
195
fastify.get('/', (_req, reply) => {
196
reply.view('./templates/index.html')
197
})
198
199
await fastify.listen({ port: 0 })
200
201
const result = await fetch('http://localhost:' + fastify.server.address().port)
202
203
const responseContent = await result.text()
204
205
t.assert.strictEqual(result.status, 200)
206
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
207
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
208
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(localsData), responseContent)
209
210
await fastify.close()
211
})
212
213
test('reply.view for handlebars engine with data-parameter and reply.locals and defaultContext', async t => {
214
t.plan(4)
215
const fastify = Fastify()
216
const handlebars = require('handlebars')
217
const localsData = { text: 'text from locals' }
218
const contextData = { text: 'text from context' }
219
const data = { text: 'text' }
220
221
fastify.register(require('../index'), {
222
engine: {
223
handlebars
224
},
225
defaultContext: contextData
226
})
227
228
fastify.addHook('preHandler', function (_request, reply, done) {
229
reply.locals = localsData
230
done()
231
})
232
233
fastify.get('/', (_req, reply) => {
234
reply.view('./templates/index.html', data)
235
})
236
237
await fastify.listen({ port: 0 })
238
239
const result = await fetch('http://localhost:' + fastify.server.address().port)
240
241
const responseContent = await result.text()
242
243
t.assert.strictEqual(result.status, 200)
244
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
245
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
246
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), responseContent)
247
248
await fastify.close()
249
})
250
251
test('fastify.view with handlebars engine and callback', (t, end) => {
252
t.plan(3)
253
const fastify = Fastify()
254
const handlebars = require('handlebars')
255
const data = { text: 'text' }
256
257
fastify.register(require('../index'), {
258
engine: {
259
handlebars
260
}
261
})
262
263
fastify.ready(err => {
264
t.assert.ifError(err)
265
266
fastify.view('./templates/index.html', data, (err, compiled) => {
267
t.assert.ifError(err)
268
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), compiled)
269
fastify.close()
270
end()
271
})
272
})
273
})
274
275
test('fastify.view with handlebars engine with layout option', (t, end) => {
276
t.plan(3)
277
278
const fastify = Fastify()
279
const handlebars = require('handlebars')
280
const data = { text: 'it works!' }
281
282
fastify.register(require('../index'), {
283
engine: {
284
handlebars
285
},
286
layout: './templates/layout.hbs'
287
})
288
289
fastify.ready(err => {
290
t.assert.ifError(err)
291
292
fastify.view('./templates/index-for-layout.hbs', data, (err, compiled) => {
293
t.assert.ifError(err)
294
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.hbs', 'utf8'))(data), compiled)
295
fastify.close()
296
end()
297
})
298
})
299
})
300
301
test('fastify.view with handlebars engine with layout option on render', (t, end) => {
302
t.plan(3)
303
304
const fastify = Fastify()
305
const handlebars = require('handlebars')
306
const data = { text: 'it works!' }
307
308
fastify.register(require('../index'), {
309
engine: {
310
handlebars
311
}
312
})
313
314
fastify.ready(err => {
315
t.assert.ifError(err)
316
317
fastify.view('./templates/index-for-layout.hbs', data, { layout: './templates/layout.hbs' }, (err, compiled) => {
318
t.assert.ifError(err)
319
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.hbs', 'utf8'))(data), compiled)
320
fastify.close()
321
end()
322
})
323
})
324
})
325
326
test('fastify.view with handlebars engine with invalid layout option on render should throw', (t, end) => {
327
t.plan(5)
328
329
const fastify = Fastify()
330
const handlebars = require('handlebars')
331
const data = { text: 'it works!' }
332
333
fastify.register(require('../index'), {
334
engine: {
335
handlebars
336
}
337
})
338
339
fastify.ready(err => {
340
t.assert.ifError(err)
341
fastify.view('./templates/index-for-layout.hbs', data, { layout: './templates/invalid-layout.hbs' }, (err) => {
342
t.assert.ok(err instanceof Error)
343
t.assert.strictEqual(err.message, 'unable to access template "./templates/invalid-layout.hbs"')
344
})
345
// repeated for test coverage of layout access check lru
346
fastify.view('./templates/index-for-layout.hbs', data, { layout: './templates/invalid-layout.hbs' }, (err) => {
347
t.assert.ok(err instanceof Error)
348
t.assert.strictEqual(err.message, 'unable to access template "./templates/invalid-layout.hbs"')
349
end()
350
})
351
})
352
})
353
354
test('reply.view with handlebars engine', async t => {
355
t.plan(4)
356
const fastify = Fastify()
357
const handlebars = require('handlebars')
358
const data = { text: 'text' }
359
360
fastify.register(require('../index'), {
361
engine: {
362
handlebars
363
}
364
})
365
366
fastify.get('/', (_req, reply) => {
367
reply.view('./templates/index.html', data)
368
})
369
370
await fastify.listen({ port: 0 })
371
372
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
373
const responseContent = await result.text()
374
375
t.assert.strictEqual(result.status, 200)
376
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
377
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
378
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), responseContent)
379
380
await fastify.close()
381
})
382
383
test('reply.view with handlebars engine catches render error', async t => {
384
t.plan(2)
385
const fastify = Fastify()
386
const handlebars = require('handlebars')
387
388
handlebars.registerHelper('badHelper', () => { throw new Error('kaboom') })
389
390
fastify.register(require('../index'), {
391
engine: {
392
handlebars
393
}
394
})
395
396
fastify.get('/', (_req, reply) => {
397
reply.view('./templates/error.hbs')
398
})
399
400
const result = await fastify.inject({
401
method: 'GET',
402
url: '/'
403
})
404
405
t.assert.strictEqual(result.json().message, 'kaboom')
406
t.assert.strictEqual(result.statusCode, 500)
407
})
408
409
test('reply.view with handlebars engine and layout catches render error', async t => {
410
t.plan(2)
411
const fastify = Fastify()
412
const handlebars = require('handlebars')
413
414
handlebars.registerHelper('badHelper', () => { throw new Error('kaboom') })
415
416
fastify.register(require('../index'), {
417
engine: {
418
handlebars
419
},
420
layout: './templates/layout.hbs'
421
})
422
423
fastify.get('/', (_req, reply) => {
424
reply.view('./templates/error.hbs')
425
})
426
427
const result = await fastify.inject({
428
method: 'GET',
429
url: '/'
430
})
431
432
t.assert.strictEqual(result.json().message, 'kaboom')
433
t.assert.strictEqual(result.statusCode, 500)
434
})
435
436
test('reply.view with handlebars engine and defaultContext', async t => {
437
t.plan(4)
438
const fastify = Fastify()
439
const handlebars = require('handlebars')
440
const data = { text: 'text' }
441
442
fastify.register(require('../index'), {
443
engine: {
444
handlebars
445
},
446
defaultContext: data
447
})
448
449
fastify.get('/', (_req, reply) => {
450
reply.view('./templates/index.html', {})
451
})
452
453
await fastify.listen({ port: 0 })
454
455
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
456
const responseContent = await result.text()
457
458
t.assert.strictEqual(result.status, 200)
459
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
460
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
461
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), responseContent)
462
463
await fastify.close()
464
})
465
466
test('reply.view with handlebars engine and includeViewExtension property as true', async t => {
467
t.plan(4)
468
const fastify = Fastify()
469
const handlebars = require('handlebars')
470
const data = { text: 'text' }
471
472
fastify.register(require('../index'), {
473
engine: {
474
handlebars
475
},
476
includeViewExtension: true
477
})
478
479
fastify.get('/', (_req, reply) => {
480
reply.view('./templates/index', data)
481
})
482
483
await fastify.listen({ port: 0 })
484
485
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
486
const responseContent = await result.text()
487
488
t.assert.strictEqual(result.status, 200)
489
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
490
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
491
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.hbs', 'utf8'))(data), responseContent)
492
493
await fastify.close()
494
})
495
496
test('fastify.view with handlebars engine and callback in production mode', (t, end) => {
497
t.plan(6)
498
const fastify = Fastify()
499
const handlebars = require('handlebars')
500
const data = { text: 'text' }
501
502
fastify.register(require('../index'), {
503
engine: {
504
handlebars
505
},
506
production: true
507
})
508
509
fastify.ready(err => {
510
t.assert.ifError(err)
511
512
fastify.view('./templates/index.html', data, (err, compiled) => {
513
t.assert.ifError(err)
514
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), compiled)
515
516
fastify.ready(err => {
517
t.assert.ifError(err)
518
519
fastify.view('./templates/index.html', data, (err, compiled) => {
520
t.assert.ifError(err)
521
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), compiled)
522
fastify.close()
523
end()
524
})
525
})
526
})
527
})
528
})
529
530
test('reply.view with handlebars engine with partials', async t => {
531
t.plan(4)
532
const fastify = Fastify()
533
const handlebars = require('handlebars')
534
const data = { text: 'text' }
535
536
fastify.register(require('../index'), {
537
engine: {
538
handlebars
539
},
540
options: {
541
partials: { body: './templates/body.hbs' }
542
}
543
})
544
545
fastify.get('/', (_req, reply) => {
546
reply.view('./templates/index-with-partials.hbs', data)
547
})
548
549
await fastify.listen({ port: 0 })
550
551
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
552
const responseContent = await result.text()
553
554
t.assert.strictEqual(result.status, 200)
555
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
556
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
557
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index-with-partials.hbs', 'utf8'))(data), responseContent)
558
559
await fastify.close()
560
})
561
562
test('reply.view with handlebars engine with missing partials path', async t => {
563
t.plan(3)
564
const fastify = Fastify()
565
const handlebars = require('handlebars')
566
const data = { text: 'text' }
567
568
fastify.register(require('../index'), {
569
engine: {
570
handlebars
571
},
572
options: {
573
partials: { body: './non-existent' }
574
}
575
})
576
577
fastify.get('/', (_req, reply) => {
578
reply.view('./templates/index-with-partials.hbs', data)
579
})
580
581
await fastify.listen({ port: 0 })
582
583
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
584
const responseContent = await result.text()
585
586
t.assert.strictEqual(result.status, 500)
587
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
588
t.assert.strictEqual(result.headers.get('content-type'), 'application/json; charset=utf-8')
589
590
await fastify.close()
591
})
592
593
test('reply.view with handlebars engine with partials in production mode should use cache', async t => {
594
t.plan(3)
595
const fastify = Fastify()
596
const handlebars = require('handlebars')
597
const POV = require('..')
598
fastify.decorate(POV.fastifyViewCache, {
599
get: (key) => {
600
t.assert.strictEqual(key, 'view|handlebars|body:./templates/body.hbs|null-Partials')
601
},
602
set: (key, value) => {
603
t.assert.strictEqual(key, 'view|handlebars|body:./templates/body.hbs|null-Partials')
604
t.assert.deepStrictEqual(value, { body: fs.readFileSync('./templates/body.hbs', 'utf8') })
605
}
606
})
607
608
fastify.register(POV, {
609
engine: {
610
handlebars
611
},
612
options: {
613
partials: { body: './templates/body.hbs' }
614
},
615
production: true
616
})
617
618
await fastify.ready()
619
await fastify.close()
620
})
621
622
test('fastify.view with handlebars engine with missing partials path in production mode does not start', async t => {
623
t.plan(1)
624
const fastify = Fastify()
625
const handlebars = require('handlebars')
626
627
fastify.register(require('../index'), {
628
engine: {
629
handlebars
630
},
631
options: {
632
partials: { body: './non-existent' }
633
},
634
production: true
635
})
636
637
await t.assert.rejects(fastify.ready(), undefined, `ENOENT: no such file or directory, open '${join(__dirname, '../non-existent')}'`)
638
})
639
640
test('reply.view with handlebars engine with compile options', async t => {
641
t.plan(4)
642
const fastify = Fastify()
643
const handlebars = require('handlebars').create()
644
const compileOptions = { preventIndent: true, strict: true }
645
const data = { text: 'hello\nworld' }
646
647
fastify.register(require('../index'), {
648
engine: {
649
handlebars
650
},
651
options: {
652
compileOptions,
653
partials: { body: './templates/body.hbs' }
654
}
655
})
656
657
fastify.get('/', (_req, reply) => {
658
reply.view('./templates/index-with-partials.hbs', data)
659
})
660
661
await fastify.listen({ port: 0 })
662
663
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
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(handlebars.compile(fs.readFileSync('./templates/index-with-partials.hbs', 'utf8'), compileOptions)(data), responseContent)
670
671
await fastify.close()
672
})
673
674
test('reply.view with handlebars engine with useDataVariables', async t => {
675
t.plan(4)
676
const fastify = Fastify()
677
const handlebars = require('handlebars').create()
678
const compileOptions = { strict: true }
679
const data = { text: 'text' }
680
681
fastify.register(require('../index'), {
682
engine: {
683
handlebars
684
},
685
options: {
686
compileOptions,
687
useDataVariables: true,
688
partials: { body: './templates/body-data.hbs' }
689
}
690
})
691
692
fastify.get('/', (_req, reply) => {
693
reply.locals = data
694
reply.view('./templates/index-with-partials.hbs', null)
695
})
696
697
await fastify.listen({ port: 0 })
698
699
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
700
const responseContent = await result.text()
701
702
t.assert.strictEqual(result.status, 200)
703
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
704
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
705
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index-with-partials.hbs', 'utf8'), compileOptions)(null, { data }), responseContent)
706
707
await fastify.close()
708
})
709
710
test('reply.view with handlebars engine with useDataVariables and global Ctx', async t => {
711
t.plan(4)
712
const fastify = Fastify()
713
const handlebars = require('handlebars').create()
714
const compileOptions = { strict: true }
715
const data = { text: 'text' }
716
717
fastify.register(require('../index'), {
718
engine: {
719
handlebars
720
},
721
options: {
722
compileOptions,
723
useDataVariables: true,
724
partials: { body: './templates/body-data.hbs' }
725
},
726
defaultContext: data
727
})
728
729
fastify.get('/', (_req, reply) => {
730
reply.view('./templates/index-with-partials.hbs', null)
731
})
732
733
await fastify.listen({ port: 0 })
734
735
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
736
const responseContent = await result.text()
737
738
t.assert.strictEqual(result.status, 200)
739
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
740
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
741
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index-with-partials.hbs', 'utf8'), compileOptions)(null, { data }), responseContent)
742
743
await fastify.close()
744
})
745
746
test('reply.view with handlebars engine with layout option', async t => {
747
t.plan(4)
748
const fastify = Fastify()
749
const handlebars = require('handlebars')
750
751
fastify.register(require('../index'), {
752
engine: {
753
handlebars
754
},
755
layout: './templates/layout.hbs'
756
})
757
758
fastify.get('/', (_req, reply) => {
759
reply.view('./templates/index-for-layout.hbs')
760
})
761
762
await fastify.listen({ port: 0 })
763
764
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
765
const responseContent = await result.text()
766
767
t.assert.strictEqual(result.status, 200)
768
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
769
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
770
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.hbs', 'utf8'))(), responseContent)
771
772
await fastify.close()
773
})
774
775
test('reply.view with handlebars engine with layout option on render', async t => {
776
t.plan(4)
777
const fastify = Fastify()
778
const handlebars = require('handlebars')
779
780
fastify.register(require('../index'), {
781
engine: {
782
handlebars
783
}
784
})
785
786
fastify.get('/', (_req, reply) => {
787
reply.view('./templates/index-for-layout.hbs', {}, { layout: './templates/layout.hbs' })
788
})
789
790
await fastify.listen({ port: 0 })
791
792
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
793
const responseContent = await result.text()
794
795
t.assert.strictEqual(result.status, 200)
796
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
797
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
798
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.hbs', 'utf8'))(), responseContent)
799
800
await fastify.close()
801
})
802
803
test('reply.view should return 500 if layout is missing on render', async t => {
804
t.plan(1)
805
const fastify = Fastify()
806
const handlebars = require('handlebars')
807
808
fastify.register(require('../index'), {
809
engine: {
810
handlebars
811
}
812
})
813
814
fastify.get('/', (_req, reply) => {
815
reply.view('./templates/index-for-layout.hbs', {}, { layout: './templates/missing-layout.hbs' })
816
})
817
818
await fastify.listen({ port: 0 })
819
820
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
821
822
t.assert.strictEqual(result.status, 500)
823
824
await fastify.close()
825
})
826
827
test('fastify.view with handlebars engine, missing template file', (t, end) => {
828
t.plan(3)
829
const fastify = Fastify()
830
const handlebars = require('handlebars')
831
832
fastify.register(require('../index'), {
833
engine: {
834
handlebars
835
}
836
})
837
838
fastify.ready(err => {
839
t.assert.ifError(err)
840
841
fastify.view('./missing.html', {}, err => {
842
t.assert.ok(err instanceof Error)
843
t.assert.strictEqual(err.message, `ENOENT: no such file or directory, open '${join(__dirname, '../missing.html')}'`)
844
fastify.close()
845
end()
846
})
847
})
848
})
849
850
test('fastify.view with handlebars engine should throw page missing', (t, end) => {
851
t.plan(3)
852
const fastify = Fastify()
853
const handlebars = require('handlebars')
854
855
fastify.register(require('../index'), {
856
engine: {
857
handlebars
858
}
859
})
860
861
fastify.ready(err => {
862
t.assert.ifError(err)
863
864
fastify.view(null, {}, err => {
865
t.assert.ok(err instanceof Error)
866
t.assert.strictEqual(err.message, 'Missing page')
867
fastify.close()
868
end()
869
})
870
})
871
})
872
873
test('reply.view with handlebars engine should return 500 if template fails in production mode', async t => {
874
t.plan(2)
875
const fastify = Fastify()
876
const handlebars = require('handlebars')
877
const POV = require('..')
878
fastify.decorate(POV.fastifyViewCache, {
879
get: () => {
880
return () => { throw Error('Template Error') }
881
},
882
set: () => { }
883
})
884
885
fastify.register(POV, {
886
engine: {
887
handlebars
888
},
889
layout: './templates/layout.hbs',
890
production: true
891
})
892
893
fastify.get('/', (_req, reply) => {
894
reply.view('./templates/index-for-layout.hbs')
895
})
896
897
await fastify.listen({ port: 0 })
898
899
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
900
901
const responseContent = await result.text()
902
903
t.assert.strictEqual(result.status, 500)
904
t.assert.strictEqual(JSON.parse(responseContent).message, 'Template Error')
905
906
await fastify.close()
907
})
908
909
test('reply.view with handlebars engine and raw template', async t => {
910
t.plan(4)
911
const fastify = Fastify()
912
const handlebars = require('handlebars')
913
const data = { text: 'text' }
914
915
fastify.register(require('../index'), {
916
engine: {
917
handlebars
918
}
919
})
920
921
fastify.get('/', (_req, reply) => {
922
reply.header('Content-Type', 'text/html').view({ raw: fs.readFileSync('./templates/index.html', 'utf8') }, data)
923
})
924
925
await fastify.listen({ port: 0 })
926
927
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
928
const responseContent = await result.text()
929
930
t.assert.strictEqual(result.status, 200)
931
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
932
t.assert.strictEqual(result.headers.get('content-type'), 'text/html')
933
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), responseContent)
934
935
await fastify.close()
936
})
937
938
test('reply.view with handlebars engine and function template', async t => {
939
t.plan(4)
940
const fastify = Fastify()
941
const handlebars = require('handlebars')
942
const data = { text: 'text' }
943
944
fastify.register(require('../index'), {
945
engine: {
946
handlebars
947
}
948
})
949
950
fastify.get('/', (_req, reply) => {
951
reply.view(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8')), data)
952
})
953
954
await fastify.listen({ port: 0 })
955
956
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
957
const responseContent = await result.text()
958
959
t.assert.strictEqual(result.status, 200)
960
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
961
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
962
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), responseContent)
963
964
await fastify.close()
965
})
966
967
test('reply.view with handlebars engine and empty template', async t => {
968
t.plan(1)
969
const fastify = Fastify()
970
const handlebars = require('handlebars')
971
const data = { text: 'text' }
972
973
fastify.register(require('../index'), {
974
engine: {
975
handlebars
976
}
977
})
978
979
fastify.get('/', (_req, reply) => {
980
reply.view(null, data)
981
})
982
983
await fastify.listen({ port: 0 })
984
985
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
986
987
t.assert.strictEqual(result.status, 500)
988
989
await fastify.close()
990
})
991
992
test('fastify.view with handlebars engine and callback in production mode and header', async t => {
993
t.plan(4)
994
const fastify = Fastify()
995
const handlebars = require('handlebars')
996
997
fastify.register(require('../index'), {
998
engine: {
999
handlebars
1000
},
1001
production: true,
1002
layout: './templates/layout.hbs'
1003
})
1004
1005
fastify.get('/', (_req, reply) => {
1006
reply.header('Content-Type', 'text/html').view('./templates/index-for-layout.hbs', null)
1007
})
1008
1009
await fastify.listen({ port: 0 })
1010
1011
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
1012
const responseContent = await result.text()
1013
1014
t.assert.strictEqual(result.status, 200)
1015
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
1016
t.assert.strictEqual(result.headers.get('content-type'), 'text/html')
1017
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.hbs', 'utf8'))(), responseContent)
1018
1019
await fastify.close()
1020
})
1021
1022
test('reply.view with multiple handlebars instances in production mode', async t => {
1023
t.plan(8)
1024
const fastify = Fastify()
1025
const handlebars = require('handlebars')
1026
1027
const view = require('../index')
1028
for (const name of ['foo', 'bar']) {
1029
fastify.register(view, {
1030
propertyName: name,
1031
engine: {
1032
handlebars: handlebars.create(),
1033
},
1034
root: `./templates/root-${name}`,
1035
options: {
1036
partials: { body: 'body.hbs' },
1037
},
1038
production: true,
1039
})
1040
1041
fastify.get(`/${name}`, (_req, reply) => {
1042
reply.header('Content-Type', 'text/plain')[name]('index.hbs', null)
1043
})
1044
}
1045
1046
await fastify.listen({ port: 0 })
1047
t.after(() => fastify.close())
1048
1049
for (const name of ['foo', 'bar']) {
1050
const result = await fetch(`http://127.0.0.1:${fastify.server.address().port}/${name}`)
1051
const responseContent = await result.text()
1052
1053
t.assert.strictEqual(result.status, 200)
1054
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
1055
t.assert.strictEqual(result.headers.get('content-type'), 'text/plain')
1056
t.assert.strictEqual(responseContent, `Index ${name} body ${name}\n\n`)
1057
}
1058
})
1059
1060
test('fastify.view with handlebars engine and both layout', async t => {
1061
t.plan(1)
1062
const fastify = Fastify()
1063
const handlebars = require('handlebars')
1064
const data = { text: 'text' }
1065
1066
fastify.register(require('../index'), {
1067
engine: {
1068
handlebars
1069
},
1070
layout: './templates/layout.hbs'
1071
})
1072
1073
fastify.get('/', (_req, reply) => {
1074
reply.header('Content-Type', 'text/html').view('./templates/index.hbs', data, { layout: './templates/layout.hbs' })
1075
})
1076
1077
await fastify.listen({ port: 0 })
1078
1079
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
1080
1081
t.assert.strictEqual(result.status, 500)
1082
1083
await fastify.close()
1084
})
1085
1086
test('reply.viewAsync for handlebars engine without defaultContext but with reply.locals and data-parameter, with async fastify hooks', async t => {
1087
t.plan(4)
1088
const fastify = Fastify()
1089
const handlebars = require('handlebars')
1090
const localsData = { text: 'text from locals' }
1091
const data = { text: 'text' }
1092
1093
fastify.register(require('../index'), {
1094
engine: {
1095
handlebars
1096
}
1097
})
1098
1099
fastify.addHook('preHandler', async function (_request, reply) {
1100
reply.locals = localsData
1101
})
1102
1103
fastify.get('/', async (_req, reply) => {
1104
return reply.viewAsync('./templates/index.html', data)
1105
})
1106
1107
await fastify.listen({ port: 0 })
1108
1109
const result = await fetch('http://localhost:' + fastify.server.address().port)
1110
1111
const responseContent = await result.text()
1112
1113
t.assert.strictEqual(result.status, 200)
1114
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
1115
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
1116
t.assert.strictEqual(handlebars.compile(fs.readFileSync('./templates/index.html', 'utf8'))(data), responseContent)
1117
1118
await fastify.close()
1119
})
1120
1121