Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
fastify
GitHub Repository: fastify/point-of-view
Path: blob/main/test/index.test.js
107 views
1
'use strict'
2
3
const os = require('node:os')
4
const { test } = require('node:test')
5
const path = require('node:path')
6
const fs = require('node:fs')
7
const Fastify = require('fastify')
8
9
test('fastify.view exist', async t => {
10
t.plan(1)
11
const fastify = Fastify()
12
13
fastify.register(require('../index'), {
14
engine: {
15
ejs: require('ejs')
16
}
17
})
18
19
await fastify.ready()
20
21
t.assert.ok(fastify.view)
22
23
await fastify.close()
24
})
25
26
test('fastify.view.clearCache exist', async t => {
27
t.plan(1)
28
const fastify = Fastify()
29
30
fastify.register(require('../index'), {
31
engine: {
32
ejs: require('ejs')
33
}
34
})
35
36
await fastify.ready()
37
38
t.assert.ok(fastify.view.clearCache)
39
40
await fastify.close()
41
})
42
43
test('fastify.view.clearCache clears cache', async t => {
44
t.plan(9)
45
const templatesFolder = path.join(os.tmpdir(), 'fastify')
46
try {
47
fs.mkdirSync(templatesFolder)
48
} catch {}
49
fs.writeFileSync(path.join(templatesFolder, 'cache_clear_test.ejs'), '<html><body><span>123</span></body></<html>', { mode: 0o600 })
50
const fastify = Fastify()
51
52
fastify.register(require('../index'), {
53
engine: {
54
ejs: require('ejs')
55
},
56
includeViewExtension: true,
57
templates: templatesFolder,
58
production: true
59
})
60
61
fastify.get('/view-cache-test', (_req, reply) => {
62
reply.type('text/html; charset=utf-8').view('cache_clear_test')
63
})
64
65
await fastify.listen({ port: 0 })
66
67
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port + '/view-cache-test')
68
69
const responseContent = await result.text()
70
71
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
72
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
73
fs.writeFileSync(path.join(templatesFolder, 'cache_clear_test.ejs'), '<html><body><span>456</span></body></<html>', { mode: 0o600 })
74
75
const result2 = await fetch('http://127.0.0.1:' + fastify.server.address().port + '/view-cache-test')
76
77
const responseContent2 = await result2.text()
78
79
t.assert.strictEqual(result2.headers.get('content-length'), '' + responseContent2.length)
80
t.assert.strictEqual(result2.headers.get('content-type'), 'text/html; charset=utf-8')
81
t.assert.strictEqual(responseContent, responseContent2)
82
83
fastify.view.clearCache()
84
85
const result3 = await fetch('http://127.0.0.1:' + fastify.server.address().port + '/view-cache-test')
86
87
const responseContent3 = await result3.text()
88
89
t.assert.strictEqual(result3.headers.get('content-length'), '' + responseContent3.length)
90
t.assert.strictEqual(result3.headers.get('content-type'), 'text/html; charset=utf-8')
91
92
t.assert.notStrictEqual(responseContent, responseContent3)
93
t.assert.ok(responseContent3.includes('456'))
94
95
await fastify.close()
96
})
97
98
test('reply.view exist', async t => {
99
t.plan(4)
100
const fastify = Fastify()
101
102
fastify.register(require('../index'), {
103
engine: {
104
ejs: require('ejs')
105
}
106
})
107
108
fastify.get('/', (_req, reply) => {
109
t.assert.ok(reply.view)
110
reply.send({ hello: 'world' })
111
})
112
113
await fastify.listen({ port: 0 })
114
115
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
116
const responseContent = await result.text()
117
118
t.assert.strictEqual(result.status, 200)
119
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
120
t.assert.deepStrictEqual(JSON.parse(responseContent), { hello: 'world' })
121
122
await fastify.close()
123
})
124
125
test('reply.locals exist', async t => {
126
t.plan(4)
127
const fastify = Fastify()
128
129
fastify.register(require('../index'), {
130
engine: {
131
ejs: require('ejs')
132
}
133
})
134
135
fastify.get('/', (_req, reply) => {
136
t.assert.ok(reply.locals)
137
reply.send({ hello: 'world' })
138
})
139
140
await fastify.listen({ port: 0 })
141
142
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
143
const responseContent = await result.text()
144
145
t.assert.strictEqual(result.status, 200)
146
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
147
t.assert.deepStrictEqual(JSON.parse(responseContent), { hello: 'world' })
148
149
await fastify.close()
150
})
151
152
test('reply.view can be returned from async function to indicate response processing finished', async t => {
153
t.plan(4)
154
const fastify = Fastify()
155
const ejs = require('ejs')
156
const data = { text: 'text' }
157
158
fastify.register(require('../index'), {
159
engine: {
160
ejs
161
},
162
root: path.join(__dirname, '../templates'),
163
layout: 'layout.html'
164
})
165
166
fastify.get('/', async (_req, reply) => {
167
return reply.view('index-for-layout.ejs', data)
168
})
169
170
await fastify.listen({ port: 0 })
171
172
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
173
const responseContent = await result.text()
174
175
t.assert.strictEqual(result.status, 200)
176
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
177
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
178
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), data), responseContent)
179
180
await fastify.close()
181
})
182
183
test('Possibility to access res.locals variable across all views', async t => {
184
t.plan(4)
185
const fastify = Fastify()
186
187
fastify.register(require('../index'), {
188
engine: {
189
ejs: require('ejs')
190
},
191
root: path.join(__dirname, '../templates'),
192
layout: 'index-layout-body',
193
viewExt: 'ejs'
194
})
195
196
fastify.addHook('preHandler', async function (_req, reply) {
197
reply.locals = {
198
content: 'ok'
199
}
200
})
201
202
fastify.get('/', async (_req, reply) => {
203
return reply.view('index-layout-content')
204
})
205
206
await fastify.listen({ port: 0 })
207
208
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
209
const responseContent = await result.text()
210
211
t.assert.strictEqual(result.status, 200)
212
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
213
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
214
t.assert.strictEqual('ok', responseContent.trim())
215
216
await fastify.close()
217
})
218
219
test('Default extension for ejs', async t => {
220
t.plan(4)
221
const fastify = Fastify()
222
223
fastify.register(require('../index'), {
224
engine: {
225
ejs: require('ejs')
226
},
227
root: path.join(__dirname, '../templates'),
228
viewExt: 'html'
229
})
230
231
fastify.get('/', async (_req, reply) => {
232
return reply.view('index-with-includes-without-ext')
233
})
234
235
await fastify.listen({ port: 0 })
236
237
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
238
const responseContent = await result.text()
239
240
t.assert.strictEqual(result.status, 200)
241
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
242
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
243
t.assert.strictEqual('ok', responseContent.trim())
244
245
await fastify.close()
246
})
247
248
test('reply.view with ejs engine and custom propertyName', async t => {
249
t.plan(8)
250
const fastify = Fastify()
251
const ejs = require('ejs')
252
253
fastify.register(require('../index'), {
254
engine: {
255
ejs
256
},
257
root: path.join(__dirname, '../templates'),
258
layout: 'layout.html',
259
propertyName: 'mobile'
260
})
261
fastify.register(require('../index'), {
262
engine: {
263
ejs
264
},
265
root: path.join(__dirname, '../templates'),
266
layout: 'layout.html',
267
propertyName: 'desktop'
268
})
269
270
fastify.get('/', async (req, reply) => {
271
const text = req.headers['user-agent']
272
return reply[text]('index-for-layout.ejs', { text })
273
})
274
275
await fastify.listen({ port: 0 })
276
277
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port, {
278
headers: {
279
'user-agent': 'mobile'
280
}
281
})
282
const responseContent = await result.text()
283
284
t.assert.strictEqual(result.status, 200)
285
t.assert.strictEqual(result.headers.get('content-length'), '' + responseContent.length)
286
t.assert.strictEqual(result.headers.get('content-type'), 'text/html; charset=utf-8')
287
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), { text: 'mobile' }), responseContent)
288
289
const result2 = await fetch('http://127.0.0.1:' + fastify.server.address().port, {
290
headers: {
291
'user-agent': 'desktop'
292
}
293
})
294
const responseContent2 = await result2.text()
295
296
t.assert.strictEqual(result2.status, 200)
297
t.assert.strictEqual(result2.headers.get('content-length'), '' + responseContent2.length)
298
t.assert.strictEqual(result2.headers.get('content-type'), 'text/html; charset=utf-8')
299
t.assert.strictEqual(ejs.render(fs.readFileSync('./templates/index.ejs', 'utf8'), { text: 'desktop' }), responseContent2)
300
301
await fastify.close()
302
})
303
304
test('reply.view should return 500 if page is missing', async t => {
305
t.plan(1)
306
const fastify = Fastify()
307
308
fastify.register(require('../index'), {
309
engine: {
310
ejs: require('ejs')
311
}
312
})
313
314
fastify.get('/', (_req, reply) => {
315
reply.view()
316
})
317
318
await fastify.listen({ port: 0 })
319
320
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
321
322
t.assert.strictEqual(result.status, 500)
323
324
await fastify.close()
325
})
326
327
test('reply.view should return 500 if layout is set globally and provided on render', async t => {
328
t.plan(1)
329
const fastify = Fastify()
330
const data = { text: 'text' }
331
fastify.register(require('../index'), {
332
engine: {
333
ejs: require('ejs'),
334
layout: 'layout.html'
335
}
336
})
337
338
fastify.get('/', (_req, reply) => {
339
reply.view('index-for-layout.ejs', data, { layout: 'layout.html' })
340
})
341
342
await fastify.listen({ port: 0 })
343
344
const result = await fetch('http://127.0.0.1:' + fastify.server.address().port)
345
346
t.assert.strictEqual(result.status, 500)
347
348
await fastify.close()
349
})
350
351
test('register callback should throw if the engine is missing', async t => {
352
t.plan(1)
353
const fastify = Fastify()
354
355
fastify.register(require('../index'))
356
357
await t.assert.rejects(fastify.ready(), undefined, 'Missing engine')
358
})
359
360
test('register callback should throw if the engine is not supported', async t => {
361
t.plan(1)
362
const fastify = Fastify()
363
364
const register = fastify.register(require('../index'), {
365
engine: {
366
notSupported: null
367
}
368
})
369
370
await t.assert.rejects(register.ready(), undefined, '\'notSupported\' not yet supported, PR? :)')
371
})
372
373
test('register callback with handlebars engine should throw if layout file does not exist', async t => {
374
t.plan(1)
375
const fastify = Fastify()
376
377
const register = fastify.register(require('../index'), {
378
engine: {
379
handlebars: require('handlebars')
380
},
381
layout: './templates/does-not-exist.hbs'
382
})
383
384
await t.assert.rejects(register.ready(), undefined, 'unable to access template "./templates/does-not-exist.hbs"')
385
})
386
387
test('register callback should throw if layout option provided with wrong engine', async t => {
388
t.plan(1)
389
const fastify = Fastify()
390
391
const register = fastify.register(require('../index'), {
392
engine: {
393
pug: require('pug')
394
},
395
layout: 'template'
396
})
397
398
await t.assert.rejects(register.ready(), undefined, 'Only Dot, Handlebars, EJS, and Eta support the "layout" option')
399
})
400
401
test('register callback should throw if templates option provided as array with wrong engine', async t => {
402
t.plan(1)
403
const fastify = Fastify()
404
405
const register = fastify.register(require('../index'), {
406
engine: {
407
pug: require('pug')
408
},
409
templates: ['layouts', 'pages']
410
})
411
412
await t.assert.rejects(register.ready(), undefined, 'Only Nunjucks supports the "templates" option as an array')
413
})
414
415
test('plugin is registered with "point-of-view" name', async t => {
416
t.plan(1)
417
const fastify = Fastify()
418
419
fastify.register(require('../index'), {
420
engine: {
421
ejs: require('ejs')
422
}
423
})
424
425
await fastify.ready()
426
427
const kRegistedPlugins = Symbol.for('registered-plugin')
428
const registeredPlugins = fastify[kRegistedPlugins]
429
t.assert.ok(registeredPlugins.find(name => name === '@fastify/view'))
430
431
await fastify.close()
432
})
433
434