koa-views
Version:
Template rendering middleware for koa
432 lines (370 loc) • 10.2 kB
JavaScript
const request = require('supertest')
const views = require('../src')
const path = require('path')
const Koa = require('koa')
const should = require('should')
describe('koa-views', () => {
it('have a render method', done => {
const app = new Koa().use(views()).use(ctx => {
should(ctx.render).be.ok()
should(ctx.render).be.a.Function()
should(ctx.response.render).be.equal(ctx.render)
})
request(app.listen())
.get('/')
.expect(404, done)
})
it('have a render method by app.context', done => {
const app = new Koa()
const render = views()()
app.context.render = render
app.response.render = render
app.use(ctx => {
should(ctx.render).be.ok()
should(ctx.render).be.a.Function()
should(ctx.response.render).be.equal(ctx.render)
})
request(app.listen())
.get('/')
.expect(404, done)
})
it('default to html', done => {
const app = new Koa().use(views(__dirname)).use(ctx => {
return ctx.render('./fixtures/basic')
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/basic:html/)
.expect(200, done)
})
it('default to html', done => {
const app = new Koa()
const render = views(__dirname)()
app.context.render = render
app.response.render = render
app.use(ctx => {
return ctx.render('./fixtures/basic')
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/basic:html/)
.expect(200, done)
})
it('autoRender is false', done => {
const app = new Koa().use(views(__dirname, { autoRender: false, extension: 'ejs' })).use(async (ctx) => {
const res = await ctx.render('./fixtures/basic')
ctx.body = res
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/basic:ejs/)
.expect(200, done)
})
it('autoRender is false by app.context', done => {
const app = new Koa()
const render = views(__dirname, { autoRender: false, extension: 'ejs' })()
app.context.render = render
app.response.render = render
app.use(async (ctx) => {
const res = await ctx.render('./fixtures/basic')
ctx.body = res
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/basic:ejs/)
.expect(200, done)
})
it('default to [ext] if a default engine is set', done => {
const app = new Koa()
.use(views(__dirname, { extension: 'pug' }))
.use(ctx => {
return ctx.render('./fixtures/basic')
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/basic:jade/)
.expect(200, done)
})
it('set and render state', done => {
const app = new Koa()
.use(views(__dirname, { extension: 'pug' }))
.use(ctx => {
ctx.state.engine = 'pug'
return ctx.render('./fixtures/global-state')
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/basic:pug/)
.expect(200, done)
})
// #25
it('works with circular references in state', done => {
const app = new Koa()
.use(views(__dirname, { extension: 'pug' }))
.use(function (ctx) {
ctx.state = {
a: {},
app
}
ctx.state.a.a = ctx.state.a
return ctx.render('./fixtures/global-state', {
app,
b: this.state,
engine: 'pug'
})
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/basic:pug/)
.expect(200, done)
})
// #138
it('works with bigint in state', done => {
const app = new Koa()
.use(views(__dirname, { extension: 'pug' }))
.use(function (ctx) {
ctx.state = {
a: { x: 132n },
app
}
return ctx.render('./fixtures/global-state', {
app,
b: this.state,
engine: 'pug'
})
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/basic:pug/)
.expect(200, done)
})
it('`map` given `engine` to given file `ext`', done => {
const app = new Koa()
.use(views(__dirname, { map: { html: 'underscore' } }))
.use(ctx => {
ctx.state.engine = 'underscore'
return ctx.render('./fixtures/underscore')
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/basic:underscore/)
.expect(200, done)
})
it('merges global and local state ', done => {
const app = new Koa()
.use(views(__dirname, { extension: 'pug' }))
.use(ctx => {
ctx.state.engine = 'pug'
return ctx.render('./fixtures/state', {
type: 'basic'
})
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/basic:pug/)
.expect(200, done)
})
it('call to the next middleware if this.render is already defined', done => {
const app = new Koa()
.use((ctx, next) => {
ctx.render = true
return next()
})
.use(views())
.use(ctx => {
ctx.body = 'hello'
})
request(app.listen())
.get('/')
.expect('hello')
.expect(200, done)
})
it('allows view options to be passed in', done => {
const app = new Koa()
.use(
views(__dirname, {
map: { hbs: 'handlebars' },
options: {
helpers: {
uppercase: str => str.toUpperCase()
},
partials: {
subTitle: './view-options-partial'
}
}
})
)
.use(ctx => {
ctx.state = { title: 'my title', author: 'queckezz' }
return ctx.render('./fixtures/view-options.hbs')
})
const server = request(app.listen())
server
.get('/')
.expect(/MY TITLE/)
.expect(200, () => {
server
.get('/')
.expect(/MY TITLE/)
.expect(200, done)
})
})
// #23 && #27
it('given a directory it should try to require index.[ext]', done => {
const app = new Koa().use(views(__dirname)).use(ctx => {
return ctx.render('./fixtures')
})
request(app.listen())
.get('/')
.expect(/defaults-to-index/)
.expect(200, done)
})
// #43
it('it should not overwrite an extension when given one', done => {
const app = new Koa().use(views(__dirname)).use(ctx => {
return ctx.render('./fixtures/basic.ejs')
})
request(app.listen())
.get('/')
.expect(/basic:ejs/)
.expect(200, done)
})
it('it should use an engineSource other than @ladjs/consolidate when provided', done => {
const app = new Koa()
.use(
views(__dirname, {
engineSource: {
foo: () => Promise.resolve('hello')
}
})
)
.use(ctx => {
return ctx.render('./fixtures/basic.foo')
})
request(app.listen())
.get('/')
.expect(/hello/)
.expect(200, done)
})
// #82
describe('extension is ejs, frist visit basic.html then visit basic should render basic.ejs', () => {
const app = new Koa()
.use(
views(__dirname, {
extension: 'ejs'
})
)
.use((ctx, next) => {
if (ctx.path === '/html') {
return ctx.render('./fixtures/basic.html')
}
return next()
})
.use((ctx, next) => {
if (ctx.path === '/ejs') {
return ctx.render('./fixtures/basic')
}
return next()
})
const server = request(app.listen())
it('first visit html', done => {
server
.get('/html')
.expect(/basic:html/)
.expect(200, done)
})
it('then visit ejs should render basic basic.ejs', done => {
server
.get('/ejs')
.expect(/basic:ejs/)
.expect(200, done)
})
})
// #87
it('name with dot', done => {
const app = new Koa().use(views(__dirname)).use(ctx => {
return ctx.render('./fixtures/basic.test')
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/basic:html/)
.expect(200, done)
})
// #94
it('nunjucks with nunjucksEnv', done => {
const nunjucks = require('nunjucks')
const env = new nunjucks.Environment(
new nunjucks.FileSystemLoader(path.join(__dirname, 'fixtures'))
)
env.addFilter('shorten', (str, count) => {
return str.slice(0, count || 5)
})
const app = new Koa()
.use(
views(path.join(__dirname, 'fixtures'), {
options: {
nunjucksEnv: env
},
map: { html: 'nunjucks' }
})
)
.use(ctx => {
return ctx.render('nunjucks-filter', {
message: 'this is a long message'
})
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/this </)
.expect(200, done)
})
it('nunjucks with nunjucksEnv by app.context', done => {
const nunjucks = require('nunjucks')
const env = new nunjucks.Environment(
new nunjucks.FileSystemLoader(path.join(__dirname, 'fixtures'))
)
env.addFilter('shorten', (str, count) => {
return str.slice(0, count || 5)
})
const app = new Koa()
const render = views(path.join(__dirname, 'fixtures'), {
options: {
nunjucksEnv: env
},
map: { html: 'nunjucks' }
})()
app.context.render = render
app.response.render = render
app.use(ctx => {
return ctx.render('nunjucks-filter', {
message: 'this is a long message'
})
})
request(app.listen())
.get('/')
.expect('Content-Type', /html/)
.expect(/this </)
.expect(200, done)
})
// #142
it('rendering outside root should be forbidden', done => {
const app = new Koa().use(views(__dirname)).use(ctx => {
return ctx.render('../test-outside/fixtures/basic.ejs')
})
request(app.listen())
.get('/')
.expect(403, done)
})
})