From 2c00744a6ade4c3b3fc990359c727c8eca14a0ef Mon Sep 17 00:00:00 2001 From: orthagonal Date: Fri, 24 Nov 2017 02:04:16 -0600 Subject: [PATCH 01/13] pprops --- .travis.yml | 1 - package.json | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 255e5d6..56774f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,5 @@ language: node_js node_js: - 8 - - 6 script: npm run test-travis diff --git a/package.json b/package.json index 253913b..9e2cb73 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "boom": "^6.0.0", "hoek": "^5.0.0", "js-yaml": "^3.10.0", + "p-props": "^1.1.0", "str2fn": "2.0.0", "varson": "^2.0.2", "wreck": "^12.5.0" From 95e2f7b76254c7f75da7b33801f5adb955a2bed1 Mon Sep 17 00:00:00 2001 From: orthagonal Date: Fri, 24 Nov 2017 23:29:25 -0600 Subject: [PATCH 02/13] hapi 17 deps and test --- index.js | 30 ++-- lib/handler.js | 24 +-- package.json | 8 +- test/test.api.js | 215 ++++++++++++------------ test/test.cache.js | 249 ++++++++++++---------------- test/test.errors.js | 99 +++++------ test/test.globals.js | 87 +++++----- test/test.inject.js | 210 +++++++++++------------- test/test.methods.js | 343 +++++++++++++++++---------------------- test/test.onError.js | 156 ++++++++---------- test/test.pre.js | 109 +++++-------- test/test.routeConfig.js | 67 +++----- test/test.yaml.js | 84 +++++----- 13 files changed, 737 insertions(+), 944 deletions(-) diff --git a/index.js b/index.js index 05da94f..5e0424e 100644 --- a/index.js +++ b/index.js @@ -14,7 +14,7 @@ const defaults = { views: {} }; -exports.register = function(server, options, next) { +const register = async (server, options) => { options = hoek.applyToDefaults(defaults, options); serverMethods.forEach((methodName) => { // todo: add caching options: @@ -50,20 +50,22 @@ exports.register = function(server, options, next) { // register the fetch method: server.method('views.fetch', require('./methods/views/fetch.js'), {}); //routes - async.forEachOfSeries(options.views, (config, path, cb) => { - config.options = options; - server.route({ - path, - method: 'get', - handler: renderHandler(config), - config: aug({}, options.routeConfig, config.routeConfig || {}) - }); - - cb(); - }, next); + await new Promise((resolve, reject) => { + async.forEachOfSeries(options.views, (config, path, cb) => { + config.options = options; + server.route({ + path, + method: 'get', + handler: renderHandler(config), + config: aug({}, options.routeConfig, config.routeConfig || {}) + }); + cb(); + }, resolve); + }); }; -exports.register.attributes = { - name: 'views', +exports.plugin = { + register, + once: true, pkg: require('./package.json') }; diff --git a/lib/handler.js b/lib/handler.js index dc1e8ed..c8b336b 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -4,11 +4,11 @@ const str2fn = require('str2fn'); const Boom = require('boom'); const aug = require('aug'); -module.exports = (viewConfig) => (request, reply) => { +module.exports = (viewConfig) => (request, h) => { async.autoInject({ preProcess: done => { if (viewConfig.preProcess) { - return str2fn(request.server.methods, viewConfig.preProcess)(request, viewConfig.options, reply, done); + return str2fn(request.server.methods, viewConfig.preProcess)(request, viewConfig.options, h, done); } return done(); }, @@ -30,22 +30,22 @@ module.exports = (viewConfig) => (request, reply) => { }, (err, data) => { if (err) { if (typeof viewConfig.options.onError === 'function') { - return viewConfig.options.onError(err, reply); + return viewConfig.options.onError(err, h); } if (typeof viewConfig.onError === 'function') { - return viewConfig.onError(err, reply); + return viewConfig.onError(err, h); } if (typeof viewConfig.options.onError === 'string') { - return str2fn(request.server.methods, viewConfig.options.onError)(err, reply); + return str2fn(request.server.methods, viewConfig.options.onError)(err, h); } if (typeof viewConfig.onError === 'string') { - return str2fn(request.server.methods, viewConfig.onError)(err, reply); + return str2fn(request.server.methods, viewConfig.onError)(err, h); } // boom errs can be handed back directly: if (err.isBoom) { - return reply(err); + throw err; } - return reply(Boom.boomify(err)); + throw Boom.boomify(err); } // Returned early in preProcess if (!data.globals && !data.locals) { @@ -60,15 +60,15 @@ module.exports = (viewConfig) => (request, reply) => { }); } if (viewConfig.options.allowDebugQuery && (request.query.json === '1' || request.query.debug === '1')) { - return reply(combinedData).type('application/json'); + return combinedData.type('application/json'); } if (viewConfig.preResponse) { - return str2fn(request.server.methods, viewConfig.preResponse)(request, viewConfig.options, combinedData, reply, () => { - reply.view(viewConfig.view, combinedData); + return str2fn(request.server.methods, viewConfig.preResponse)(request, viewConfig.options, combinedData, h, () => { + h.view(viewConfig.view, combinedData); }); } const viewName = typeof viewConfig.view === 'function' ? viewConfig.view(combinedData) : viewConfig.view; - return reply.view(viewName, combinedData); + return h.view(viewName, combinedData); }); }; diff --git a/package.json b/package.json index 9e2cb73..32d83d1 100644 --- a/package.json +++ b/package.json @@ -35,14 +35,14 @@ "wreck": "^12.5.0" }, "devDependencies": { - "code": "^4.0.0", + "code": "^5.1.2", "coveralls": "^2.11.8", "eslint": "^4.9.0", "eslint-config-firstandthird": "^4.0.1", "eslint-plugin-import": "^2.8.0", "handlebars": "^4.0.11", - "hapi": "^16.6.2", - "lab": "^12.1.0", - "vision": "^4.0.1" + "hapi": "^17.0.1", + "lab": "^15.1.2", + "vision": "^5.2.0" } } diff --git a/test/test.api.js b/test/test.api.js index 419dac3..105df7b 100644 --- a/test/test.api.js +++ b/test/test.api.js @@ -7,17 +7,19 @@ const expect = require('code').expect; const Hapi = require('hapi'); const boom = require('boom'); -lab.experiment('api', () => { - const server = new Hapi.Server({ - debug: { request: '*', log: 'hapi-views' } - }); - server.connection({ port: 9991 }); - lab.before(start => { +let server; +lab.experiment('api', async () => { + lab.before( async () => { // start server - server.register([ + server = new Hapi.Server({ + debug: { request: '*', log: 'hapi-views' }, + port: 9991 + }); + + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { //debug: true, dataPath: `${process.cwd()}/test/yaml`, @@ -63,130 +65,119 @@ lab.experiment('api', () => { }, } } - }], error => { - Hoek.assert(!error, error); - - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - server.route({ - method: 'GET', - path: '/timeout', - handler(request, reply) { - setTimeout(() => reply({}), 6000); - } - }); - server.route({ - method: 'GET', - path: '/checkHeader', - handler(request, reply) { - expect(request.headers['x-api-key']).to.equal('1234'); - return reply({ test: true }); - } - }); - - server.route({ - method: 'GET', - path: '/api', - handler(request, reply) { - expect(request.info.referrer).to.equal('refererWithTwoRs'); - expect(request.headers).to.include('user-agent'); - reply({ test: true }); - } - }); + }]); - server.route({ - method: 'GET', - path: '/apiError', - handler(request, reply) { - reply(boom.locked('uh uh no')); - } - }); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); - server.start((err) => { - Hoek.assert(!err, err); - start(); - }); + server.route({ + method: 'GET', + path: '/timeout', + handler: async(request, h) => { + const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); + await wait(6000); + return {}; + } + }); + server.route({ + method: 'GET', + path: '/checkHeader', + handler(request, h) { + expect(request.headers['x-api-key']).to.equal('1234'); + return { test: true }; + } + }); + server.route({ + method: 'GET', + path: '/api', + handler(request, h) { + expect(request.info.referrer).to.equal('refererWithTwoRs'); + expect(request.headers).to.include('user-agent'); + return { test: true }; + } + }); + server.route({ + method: 'GET', + path: '/apiError', + handler(request, h) { + throw boom.locked('uh uh no'); + } }); + await server.start(); }); - lab.after(end => { - server.stop(end); + + lab.after(async() => { + await server.stop(); }); + // tests - lab.test('api with headers', done => { - server.inject({ + lab.test('api with headers', async () => { + const response = await server.inject({ method: 'GET', url: '/apiHeader/' - }, response => { - const context = response.request.response.source.context; - expect(context.api.var1.test).to.equal(true); - server.inject({ - method: 'GET', - url: '/apiHeader2/' - }, response2 => { - const context2 = response2.request.response.source.context; - expect(context2.api.value1[0].id).to.equal(2); - expect(context2.api.value2.test).to.equal(true); - done(); - }); }); + const context = response.request.response.source.context; + expect(context.api.var1.test).to.equal(true); + const response2 = await server.inject({ + method: 'GET', + url: '/apiHeader2/' + }); + const context2 = response2.request.response.source.context; + expect(context2.api.value1[0].id).to.equal(2); + expect(context2.api.value2.test).to.equal(true); }); - lab.test('api', done => { - server.inject({ + + + lab.test('api', async () => { + const response = await server.inject({ url: '/apitest' - }, response => { - const context = response.request.response.source.context; - expect(context).to.equal({ yaml: {}, - method: {}, - inject: {}, - api: { - key1: [{ userId: 1, - id: 1, - title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', - body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } - ] - } - }); - done(); + }); + const context = response.request.response.source.context; + expect(context).to.equal({ yaml: {}, + method: {}, + inject: {}, + api: { + key1: [{ userId: 1, + id: 1, + title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', + body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } + ] + } }); }); - lab.test('api with timeout', { timeout: 10000 }, done => { - server.inject({ + lab.test('api with timeout', { timeout: 10000 }, async () => { + const response = await server.inject({ url: '/apitimeout' - }, response => { - expect(response.statusCode).to.equal(504); - done(); }); + expect(response.statusCode).to.equal(504); }); - lab.test('api with variables', done => { - server.inject({ + + lab.test('api with variables', async () => { + const response = await server.inject({ url: '/apivar/1' - }, response => { - const context = response.request.response.source.context; - expect(context).to.equal({ yaml: {}, - method: {}, - inject: {}, - api: { - var1: [{ userId: 1, - id: 1, - title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', - body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } - ] - } - }); - done(); + }); + const context = response.request.response.source.context; + expect(context).to.equal({ yaml: {}, + method: {}, + inject: {}, + api: { + var1: [{ userId: 1, + id: 1, + title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', + body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } + ] + } }); }); - lab.test('api friendly boom errors', done => { - server.inject({ + lab.test('api friendly boom errors', async () => { + const response = await server.inject({ url: '/apierror' - }, response => { - // verify boom status code and friendly error message: - expect(response.statusCode).to.equal(423); - expect(response.statusMessage).to.equal('Locked'); - expect(response.payload).to.include('uh uh no'); - done(); }); + // verify boom status code and friendly error message: + expect(response.statusCode).to.equal(423); + expect(response.statusMessage).to.equal('Locked'); + expect(response.payload).to.include('uh uh no'); }); }); diff --git a/test/test.cache.js b/test/test.cache.js index 15a1a74..b0d3c21 100644 --- a/test/test.cache.js +++ b/test/test.cache.js @@ -7,19 +7,20 @@ const expect = require('code').expect; const Hapi = require('hapi'); const Boom = require('boom'); +let server; lab.experiment('api', () => { - const server = new Hapi.Server({ - debug: { request: '*', log: 'hapi-views' } + server = new Hapi.Server({ + debug: { request: '*', log: 'hapi-views' }, + port: 9991 }); - server.connection({ port: 9991 }); let callCount = 0; - lab.before(start => { + lab.before( async () => { // start server - server.register([ + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { //debug: true, enableCache: true, @@ -68,239 +69,203 @@ lab.experiment('api', () => { }, } } - }], error => { - Hoek.assert(!error, error); - - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - - server.start((err) => { - Hoek.assert(!err, err); - start(); - }); + }]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); + await server.start(); }); - lab.after(end => { - server.stop(end); + lab.after(async () => { + await server.stop(); }); - lab.test('api', done => { + lab.test('api', async () => { let callCount = 0; server.route({ method: 'GET', path: '/testRoute', - handler(request, reply) { + handler(request, h) { callCount ++; - reply({ test: true }); + return { test: true }; } }); server.route({ method: 'GET', path: '/testRoute2', - handler(request, reply) { - reply({ test2: '1' }); + handler(request, h) { + return { test2: '1' }; } }); - server.inject({ + const response = await server.inject({ url: '/apitest' - }, response => { - const context = response.request.response.source.context; - expect(context.api.key1).to.equal({ test: true }); - server.inject({ - url: '/apitest' - }, response2 => { - const context2 = response.request.response.source.context; - expect(context2.api.key1).to.equal({ test: true }); - expect(context2.api.key2).to.equal({ test2: '1' }); - expect(callCount).to.equal(1); - done(); - }); }); + const context = response.request.response.source.context; + expect(context.api.key1).to.equal({ test: true }); + const response2 = await server.inject({ + url: '/apitest' + }); + const context2 = response.request.response.source.context; + expect(context2.api.key1).to.equal({ test: true }); + expect(context2.api.key2).to.equal({ test2: '1' }); + expect(callCount).to.equal(1); }); - lab.test('api with route params', done => { + lab.test('api with route params', async () => { callCount = 0; const ids = []; server.route({ method: 'GET', path: '/checkUrl/{requestId}', - handler(request, reply) { + handler(request, h) { callCount ++; ids.push(request.params.requestId); - reply({ test: true }); + return { test: true }; } }); - server.inject({ + const response = await server.inject({ url: '/apiParams/' }); + const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); await wait(1000); + const response2 = await server.inject({ url: '/apiParams/' - }, response => { - setTimeout(() => { - server.inject({ - url: '/apiParams/' - }, response2 => { - expect(callCount).to.equal(2); - expect(ids[0]).to.not.equal(ids[1]); - done(); - }); - }, 1000); }); + expect(callCount).to.equal(2); + expect(ids[0]).to.not.equal(ids[1]); }); - lab.test('api with cache disabled', done => { + lab.test('api with cache disabled', async () => { let callCount = 0; server.route({ method: 'GET', path: '/testRouteNoCache', - handler(request, reply) { + handler(request, h) { callCount ++; - reply({ test: true }); + return { test: true }; } }); - server.inject({ + const response = await server.inject({ url: '/apitestNocache' - }, response => { - const context = response.request.response.source.context; - expect(context.api.key1).to.equal({ test: true }); - server.inject({ - url: '/apitestNocache' - }, response2 => { - const context2 = response.request.response.source.context; - expect(context2.api.key1).to.equal({ test: true }); - expect(callCount).to.equal(2); - done(); - }); }); + const context = response.request.response.source.context; + expect(context.api.key1).to.equal({ test: true }); + const response2 = await server.inject({ + url: '/apitestNocache' + }); + const context2 = response.request.response.source.context; + expect(context2.api.key1).to.equal({ test: true }); + expect(callCount).to.equal(2); }); - lab.test('nocache=1 will bypass caching', done => { - server.inject({ + lab.test('nocache=1 will bypass caching', async() => { + const respnose = await server.inject({ + url: '/apitest?nocache=1' + }); + const context = response.request.response.source.context; + expect(context.api.key1).to.equal({ test: true }); + const response2 = await server.inject({ url: '/apitest?nocache=1' - }, response => { - const context = response.request.response.source.context; - expect(context.api.key1).to.equal({ test: true }); - server.inject({ - url: '/apitest?nocache=1' - }, response2 => { - const context2 = response.request.response.source.context; - expect(context2.api.key1).to.equal({ test: true }); - expect(context2.api.key2).to.equal({ test2: '1' }); - expect(callCount).to.equal(2); - done(); - }); }); + const context2 = response.request.response.source.context; + expect(context2.api.key1).to.equal({ test: true }); + expect(context2.api.key2).to.equal({ test2: '1' }); + expect(callCount).to.equal(2); }); - lab.test('api test with api fail', { timeout: 3500 }, done => { + lab.test('api test with api fail', { timeout: 3500 }, async () => { let firstRun = true; server.route({ method: 'GET', path: '/testFailRoute', handler(req, reply) { if (!firstRun) { - return reply(Boom.badImplementation('Random Error Message')); + throw Boom.badImplementation('Random Error Message'); } firstRun = false; - reply({ one: 'une', two: 'deu' }); + return { one: 'une', two: 'deu' }; } }); - server.inject({ + const resp = await server.inject({ method: 'GET', url: '/apitestfail' - }, resp => { - const context = resp.request.response.source.context; - expect(context.api.key1).to.equal({ one: 'une', two: 'deu' }); - setTimeout(() => { - server.inject({ - method: 'GET', - url: '/apitestfail' - }, resp2 => { - const contextDeu = resp2.request.response.source.context; - expect(contextDeu.api.key1).to.equal({ one: 'une', two: 'deu' }); - done(); - }); - }, 3000); }); + const context = resp.request.response.source.context; + expect(context.api.key1).to.equal({ one: 'une', two: 'deu' }); + const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); await wait(3000); + const resp2 = await server.inject({ + method: 'GET', + url: '/apitestfail' + }); + const contextDeu = resp2.request.response.source.context; + expect(contextDeu.api.key1).to.equal({ one: 'une', two: 'deu' }); }); - lab.test('inject', done => { + lab.test('inject', async () => { callCount = 0; server.route({ method: 'GET', path: '/injectRoute', - handler(request, reply) { + handler(request, h) { callCount ++; - reply({ test: true }); + return { test: true }; } }); - server.inject({ + const response = await server.inject({ method: 'GET', url: '/injecttest' - }, response => { - const context = response.request.response.source.context; - expect(context.inject.var1).to.equal({ test: true }); - server.inject({ - url: '/injecttest' - }, response2 => { - const context2 = response.request.response.source.context; - expect(context2.inject.var1).to.equal({ test: true }); - expect(callCount).to.equal(1); - done(); - }); }); + const context = response.request.response.source.context; + expect(context.inject.var1).to.equal({ test: true }); + const response2 = await server.inject({ + url: '/injecttest' + }); + const context2 = response.request.response.source.context; + expect(context2.inject.var1).to.equal({ test: true }); + expect(callCount).to.equal(1); }); - lab.test('inject with cache disabled', done => { + lab.test('inject with cache disabled', async () => { callCount = 0; server.route({ method: 'GET', path: '/testInjectNoCache', - handler(request, reply) { + handler(request, h) { callCount ++; - reply({ test: true }); + return { test: true }; } }); - server.inject({ + const response = await server.inject({ url: '/injecttestNocache' - }, response => { - const context = response.request.response.source.context; - expect(context.inject.key1).to.equal({ test: true }); - server.inject({ - url: '/injecttestNocache' - }, response2 => { - const context2 = response.request.response.source.context; - expect(context2.inject.key1).to.equal({ test: true }); - expect(callCount).to.equal(2); - done(); - }); }); + const context = response.request.response.source.context; + expect(context.inject.key1).to.equal({ test: true }); + const response2 = await server.inject({ + url: '/injecttestNocache' + }); + const context2 = response.request.response.source.context; + expect(context2.inject.key1).to.equal({ test: true }); + expect(callCount).to.equal(2); }); - lab.test('inject with route params', done => { + lab.test('inject with route params', async () => { callCount = 0; const ids = []; server.route({ method: 'GET', path: '/checkUrlInject/{requestId}', - handler(request, reply) { + handler(request, h) { callCount ++; ids.push(request.params.requestId); - reply({ test: true }); + return { test: true }; } }); - server.inject({ + const response = await server.inject({ + url: '/injectParams/' + }); + const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); await wait(1000); + const response2 = await server.inject({ url: '/injectParams/' - }, response => { - setTimeout(() => { - server.inject({ - url: '/injectParams/' - }, response2 => { - expect(callCount).to.equal(2); - expect(ids[0]).to.not.equal(ids[1]); - done(); - }); - }, 1000); }); + expect(callCount).to.equal(2); + expect(ids[0]).to.not.equal(ids[1]); }); }); diff --git a/test/test.errors.js b/test/test.errors.js index e859bfc..ced9297 100644 --- a/test/test.errors.js +++ b/test/test.errors.js @@ -10,16 +10,15 @@ const Boom = require('boom'); lab.experiment('errors', () => { const server = new Hapi.Server({ - debug: { log: 'hapi-views' } + debug: { log: 'hapi-views' }, + port: 9991 }); - server.connection({ port: 9991 }); - - lab.before(start => { - server.register([ + lab.before( async () => { + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { debug: true, views: { @@ -37,64 +36,48 @@ lab.experiment('errors', () => { } } } - }], (error) => { - Hoek.assert(!error, error); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - server.route({ - method: 'GET', - path: '/api/500', - handler(request, reply) { - reply(new Error('testing')); - } - }); - server.route({ - method: 'GET', - path: '/api/404', - handler(request, reply) { - reply({ status: 'not found' }).code(404); - } - }); - server.route({ - method: 'GET', - path: '/api/401', - handler(request, reply) { - reply(Boom.unauthorized('nope bud')); - } - }); - server.start((err) => { - Hoek.assert(!err, err); - start(); - }); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + server.route({ + method: 'GET', + path: '/api/500', + handler(request, h) { + throw new Error('testing'); + } }); + server.route({ + method: 'GET', + path: '/api/404', + handler(request, h) { + return h.response({ status: 'not found' }).code(404); + } + }); + server.route({ + method: 'GET', + path: '/api/401', + handler(request, h) { + throw Boom.unauthorized('nope bud'); + } + }); + await server.start(); }); - lab.test('500 errors bubble back up', (done) => { - server.inject({ - url: '/500' - }, (response) => { - expect(response.statusCode).to.equal(500); - done(); - }); + lab.test('500 errors bubble back up', async() => { + const response = await server.inject({ url: '/500' }); + expect(response.statusCode).to.equal(500); }); - lab.test('404 errors bubble back up', (done) => { - server.inject({ - url: '/404' - }, (response) => { - expect(response.statusCode).to.equal(404); - done(); - }); + lab.test('404 errors bubble back up', async() => { + const response = await server.inject({ url: '/404' }); + expect(response.statusCode).to.equal(404); }); - lab.test('boom unauthorized errors bubble back up', (done) => { - server.inject({ - url: '/401' - }, (response) => { - expect(response.statusCode).to.equal(401); - done(); - }); + lab.test('boom unauthorized errors bubble back up', async() => { + const response = await server.inject({ url: '/401' }); + expect(response.statusCode).to.equal(401); }); }); diff --git a/test/test.globals.js b/test/test.globals.js index 087b772..bbf73fc 100644 --- a/test/test.globals.js +++ b/test/test.globals.js @@ -10,13 +10,12 @@ lab.experiment('globals', () => { const server = new Hapi.Server({ debug: { request: '*', log: 'hapi-views' } }); - server.connection(); - lab.before(start => { + lab.before( async() => { // start server - server.register([ + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { dataPath: `${process.cwd()}/test/yaml`, views: { @@ -36,51 +35,45 @@ lab.experiment('globals', () => { api: { var1: 'http://jsonplaceholder.typicode.com/posts?id=1' } } } - }], error => { - Hoek.assert(!error, error); - server.method('testmethod2', function(next) { - next(null, 'test2'); - }); - server.method('testerino', function(next) { - next(null, 'test'); - }); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - server.route({ - method: 'GET', - path: '/api', - handler(request, reply) { - reply({ yaml1: { test: true } }); - } - }); - start(); + } + ]); + server.method('testmethod2', function() { + return 'test2'; + }); + server.method('testerino', function() { + return 'test'; + }); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + server.route({ + method: 'GET', + path: '/api', + handler(request, h) { + return { yaml1: { test: true } }; + } }); }); - lab.test('global api', done => { - server.inject({ - url: '/apivar/1' - }, response => { - const context = response.request.response.source.context; - // combines if they are arrays: - expect(context.method).to.equal({ - method1: 'test2', method2: 'test' - }); - expect(context.api).to.equal({ var1: [ - { userId: 3, - id: 23, - title: 'maxime id vitae nihil numquam', - body: 'veritatis unde neque eligendi\nquae quod architecto quo neque vitae\nest illo sit tempora doloremque fugit quod\net et vel beatae sequi ullam sed tenetur perspiciatis' - } - ] }); - expect(context.yaml).to.equal({ - yaml1: { - global: 'much global', - test1: 'true' - } - }); - done(); + lab.test('global api', async () => { + const response = await server.inject({ url: '/apivar/1' }); + const context = response.request.response.source.context; + // combines if they are arrays: + expect(context.method).to.equal({ + method1: 'test2', method2: 'test' + }); + expect(context.api).to.equal({ var1: [ + { userId: 3, + id: 23, + title: 'maxime id vitae nihil numquam', + body: 'veritatis unde neque eligendi\nquae quod architecto quo neque vitae\nest illo sit tempora doloremque fugit quod\net et vel beatae sequi ullam sed tenetur perspiciatis' + } + ] }); + expect(context.yaml).to.equal({ + yaml1: { + global: 'much global', + test1: 'true' + } }); }); }); diff --git a/test/test.inject.js b/test/test.inject.js index 46b5dcc..e7d2a8d 100644 --- a/test/test.inject.js +++ b/test/test.inject.js @@ -8,17 +8,17 @@ const expect = require('code').expect; const Hapi = require('hapi'); const EOL = require('os').EOL; const boom = require('boom'); + lab.experiment('injects', () => { const server = new Hapi.Server({ debug: { request: '*', log: 'hapi-views' } }); - server.connection(); - lab.before(start => { + lab.before(async () => { // start server - server.register([ + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { // debug: true, dataPath: `${process.cwd()}/test/yaml`, @@ -44,118 +44,106 @@ lab.experiment('injects', () => { }, } } - }], error => { - Hoek.assert(!error, error); - - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); - server.route({ - method: 'GET', - path: '/api', - handler(request, reply) { - expect(request.info.referrer).to.equal('refererWithTwoRs'); - expect(request.headers).to.include('user-agent'); - return reply({ test: true }); - } - }); + server.route({ + method: 'GET', + path: '/api', + handler(request, reply) { + expect(request.info.referrer).to.equal('refererWithTwoRs'); + expect(request.headers).to.include('user-agent'); + return { test: true }; + } + }); - server.method('testerino', function(next) { - next(null, 'test'); - }); + server.method('testerino', function() { + return 'test'; + }); - server.method('testmethod2', function(next) { - next(null, 'test2'); - }); + server.method('testmethod2', function() { + return 'test2'; + }); - server.method('myScope.myMethod', function(next) { - next(null, 'test3'); - }); - server.route({ - method: 'GET', - path: '/apiError', - handler(request, reply) { - reply(boom.locked('go away')); - } - }); - server.start((err) => { - Hoek.assert(!err, err); - start(); - }); + server.method('myScope.myMethod', function() { + return 'test3'; }); + server.route({ + method: 'GET', + path: '/apiError', + handler(request, h) { + throw boom.locked('go away'); + } + }); + await server.start(); }); + // tests - lab.test('inject', done => { - server.inject({ + lab.test('inject', async () => { + const response = await server.inject({ url: '/inject', headers: { referer: 'refererWithTwoRs' } - }, response => { - const context = response.request.response.source.context; - expect(context).to.equal({ - yaml: {}, - api: {}, - method: {}, - inject: { api: { test: true } } - }); - done(); + }); + const context = response.request.response.source.context; + expect(context).to.equal({ + yaml: {}, + api: {}, + method: {}, + inject: { api: { test: true } } }); }); - lab.test('injecterr', done => { - server.inject({ + lab.test('injecterr', async() => { + const response = await server.inject({ url: '/injecterr', headers: { referer: 'refererWithTwoRs' } - }, response => { - // make sure error message and friendly error passed up: - expect(response.statusCode).to.equal(423); - expect(response.result.message).to.equal('go away'); - done(); }); + // make sure error message and friendly error passed up: + expect(response.statusCode).to.equal(423); + expect(response.result.message).to.equal('go away'); }); - lab.test('injectmap', done => { - server.inject({ + lab.test('injectmap', async () => { + const response = await server.inject({ url: '/injectmap', headers: { referer: 'refererWithTwoRs' } - }, response => { - const context = response.request.response.source.context; - expect(context).to.equal({ - yaml: {}, - api: {}, - method: {}, - inject: { - api: { test: true }, - apivar: `1${EOL}` - } - }); - done(); + }); + const context = response.request.response.source.context; + expect(context).to.equal({ + yaml: {}, + api: {}, + method: {}, + inject: { + api: { test: true }, + apivar: `1${EOL}` + } }); }); - lab.test('?json=1', done => { - server.inject({ + lab.test('?json=1', async () => { + const response = await server.inject({ url: '/injectmap?json=1', headers: { referer: 'refererWithTwoRs' } - }, response => { - expect(response.headers['content-type']).to.contain('application/json'); - const context = response.result; - expect(context).to.equal({ - yaml: {}, - api: {}, - method: {}, - inject: { - api: { test: true }, - apivar: `1${EOL}` - } - }); - done(); + }); + expect(response.headers['content-type']).to.contain('application/json'); + const context = response.result; + expect(context).to.equal({ + yaml: {}, + api: {}, + method: {}, + inject: { + api: { test: true }, + apivar: `1${EOL}` + } }); }); }); @@ -164,13 +152,12 @@ lab.experiment('disable ?json=1', () => { const server = new Hapi.Server({ debug: { request: '*', log: 'hapi-views' } }); - server.connection(); - lab.before(start => { + lab.before(async () => { // start server - server.register([ + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { // debug: true, allowDebugQuery: false, @@ -193,33 +180,24 @@ lab.experiment('disable ?json=1', () => { }, } } - }], error => { - Hoek.assert(!error, error); - - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - server.route({ - method: 'GET', - path: '/api', - handler(request, reply) { - reply({ test: true }); - } - }); - server.start((err) => { - Hoek.assert(!err, err); - start(); - }); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); + server.route({ + method: 'GET', + path: '/api', + handler(request, h) { + return { test: true }; + } + }); + await server.start(); }); // tests - lab.test('inject', done => { - server.inject({ - url: '/inject?json=1' - }, response => { - expect(response.headers['content-type']).to.contain('text/html'); - done(); - }); + lab.test('inject', async () => { + const response = await server.inject({ url: '/inject?json=1' }); + expect(response.headers['content-type']).to.contain('text/html'); }); }); diff --git a/test/test.methods.js b/test/test.methods.js index 0809dba..51890b6 100644 --- a/test/test.methods.js +++ b/test/test.methods.js @@ -11,10 +11,9 @@ lab.experiment('methods', () => { const server = new Hapi.Server({ debug: { request: '*', log: 'hapi-views' } }); - server.connection(); - lab.before(start => { + lab.before(async () => { // start server - server.register([ + await server.register([ require('vision'), { register: require('../'), @@ -61,135 +60,104 @@ lab.experiment('methods', () => { } } } - }], error => { - Hoek.assert(!error, error); + } + ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - - server.route({ - method: 'GET', - path: '/api', - handler(request, reply) { - reply({ test: true }); - } - }); - - server.method('testerino', function(next) { - next(null, 'test'); - }); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); - server.method('testmethod2', function(next) { - next(null, 'test2'); - }); + server.route({ + method: 'GET', + path: '/api', + handler(request, reply) { + return { test: true }; + } + }); - server.method('myScope.myMethod', function(next) { - next(null, 'test3'); - }); + server.method('testerino', function() { + return 'test'; + }); + server.method('testmethod2', function() { + return 'test2'; + }); - server.start((err) => { - Hoek.assert(!err, err); - start(); - }); + server.method('myScope.myMethod', function() { + return 'test3'; }); + + await server.start(); }); + // tests - lab.test('api', done => { - server.inject({ - url: '/apitest' - }, response => { - const context = response.request.response.source.context; - expect(context).to.equal({ yaml: {}, - method: {}, - inject: {}, - api: { var1: [{ userId: 1, - id: 1, - title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', - body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } - ] } - }); - done(); + lab.test('api', async () => { + const response = await server.inject({ url: '/apitest' }); + const context = response.request.response.source.context; + expect(context).to.equal({ yaml: {}, + method: {}, + inject: {}, + api: { var1: [{ userId: 1, + id: 1, + title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', + body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } + ] } }); }); - lab.test('method', done => { - server.inject({ - url: '/methodtest' - }, response => { - const context = response.request.response.source.context; - expect(context).to.equal({ yaml: {}, api: {}, method: { var1: 'test' }, inject: {} }); - done(); - }); + lab.test('method', async () => { + const response = await server.inject({ url: '/methodtest' }); + const context = response.request.response.source.context; + expect(context).to.equal({ yaml: {}, api: {}, method: { var1: 'test' }, inject: {} }); }); - lab.test('data', done => { - server.inject({ - url: '/data' - }, response => { - const context = response.request.response.source.context; - expect(context).to.equal({ name: 'Jack', url: '/data', test: { ok: 'true' } }); - done(); - }); + + lab.test('data', async () => { + const response = await server.inject({ url: '/data' }); + const context = response.request.response.source.context; + expect(context).to.equal({ name: 'Jack', url: '/data', test: { ok: 'true' } }); }); - lab.test('methods', done => { - server.inject({ - url: '/methodmulti' - }, response => { - const context = response.request.response.source.context; - expect(context).to.equal({ - yaml: {}, - api: {}, - method: { - var1: 'test', - var2: 'test2', - var3: 'test3' - }, - inject: {} - }); - done(); + lab.test('methods', async () => { + const response = await server.inject({ url: '/methodmulti' }); + const context = response.request.response.source.context; + expect(context).to.equal({ + yaml: {}, + api: {}, + method: { + var1: 'test', + var2: 'test2', + var3: 'test3' + }, + inject: {} }); }); - lab.test('data', done => { - server.inject({ - url: '/data' - }, response => { - const context = response.request.response.source.context; - expect(context).to.equal({ name: 'Jack', url: '/data', test: { ok: 'true' } }); - done(); - }); + lab.test('data', async () => { + const response = await server.inject({ url: '/data' }); + const context = response.request.response.source.context; + expect(context).to.equal({ name: 'Jack', url: '/data', test: { ok: 'true' } }); }); - lab.test('data as string', done => { - server.inject({ - url: '/data-string' - }, response => { - const context = response.request.response.source.context; - expect(context).to.equal({ - yaml1: { - test1: 'true' - } - }); - done(); + lab.test('data as string', async () => { + const response = await server.inject({ url: '/data-string' }); + const context = response.request.response.source.context; + expect(context).to.equal({ + yaml1: { + test1: 'true' + } }); }); - lab.test('dataMethod call that server method for processing data', done => { - server.method('handle.data', function(results, next) { - next(null, results.yaml); + lab.test('dataMethod call that server method for processing data', async () => { + server.method('handle.data', function(results) { + return results.yaml; }); - server.inject({ - url: '/data-method' - }, response => { - const context = response.request.response.source.context; - expect(context).to.equal({ - yaml1: { - test1: 'true' - } - }); - done(); + const response = await server.inject({ url: '/data-method' }); + const context = response.request.response.source.context; + expect(context).to.equal({ + yaml1: { + test1: 'true' + } }); }); }); @@ -197,13 +165,12 @@ lab.experiment('methods', () => { lab.experiment('methods with args', () => { let server; - lab.before(start => { + lab.before(async () => { server = new Hapi.Server({ debug: { log: ['hapi-views', 'error'], request: ['error'] } }); - server.connection(); - server.register([ + await server.register([ require('vision'), { register: require('../'), @@ -249,68 +216,58 @@ lab.experiment('methods with args', () => { } } } - }], error => { - Hoek.assert(!error, error); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); + server.method('myScope.myMethod', function(arg1, arg2, arg3) { + return arg1 + arg2 + arg3; + }); + server.method('someMethod', function(name) { + return name; + }); + server.method('someOtherMethod', function(harbinger, score) { + return `${harbinger}+${score}`; + }); - server.method('myScope.myMethod', function(arg1, arg2, arg3, next) { - next(null, arg1 + arg2 + arg3); - }); - server.method('someMethod', function(name, next) { - next(null, name); - }); - server.method('someOtherMethod', function(harbinger, score, next) { - next(null, `${harbinger}+${score}`); - }); + await server.start(); - server.start((err) => { - Hoek.assert(!err, err); - start(); - }); - }); }); - lab.test('can pass args to a method', (done) => { - server.inject({ + lab.test('can pass args to a method', async() => { + const response = await server.inject({ url: '/methodWithArgs/Jack?score=56', method: 'get' - }, (response) => { - expect(response.result).to.include('trueJack56'); - done(); }); + expect(response.result).to.include('trueJack56'); }); - lab.test('can pass args to multiple methods', (done) => { - server.inject({ + lab.test('can pass args to multiple methods', async() => { + const response = await server.inject({ url: '/multiMethods/Jack/albatross?score=70', method: 'get' - }, (response) => { - expect(response.result).to.include('Jack'); - expect(response.result).to.include('albatross+70'); - done(); }); + expect(response.result).to.include('Jack'); + expect(response.result).to.include('albatross+70'); }); - lab.test('can pass args to multiple methods (obj)', (done) => { - server.inject({ + lab.test('can pass args to multiple methods (obj)', async(done) => { + const response = await server.inject({ url: '/multiMethodsObj/Jack/albatross?score=70', method: 'get' - }, (response) => { - expect(response.statusCode).to.equal(200); - const context = response.request.response.source.context; - expect(context).to.equal({ - api: {}, - method: { - someMethod: 'Jack', - someOtherMethod: 'albatross+70' - }, - inject: {}, - yaml: { } - }); - done(); + }); + expect(response.statusCode).to.equal(200); + const context = response.request.response.source.context; + expect(context).to.equal({ + api: {}, + method: { + someMethod: 'Jack', + someOtherMethod: 'albatross+70' + }, + inject: {}, + yaml: { } }); }); }); @@ -319,10 +276,9 @@ lab.experiment('method with view function', () => { const server = new Hapi.Server({ debug: { request: '*', log: 'hapi-views' } }); - server.connection(); - lab.before(start => { + lab.before(async () => { // start server - server.register([ + await server.register([ require('vision'), { register: require('../'), @@ -373,49 +329,40 @@ lab.experiment('method with view function', () => { } } } - }], error => { - Hoek.assert(!error, error); + } + ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - - server.route({ - method: 'GET', - path: '/api', - handler(request, reply) { - reply({ test: true }); - } - }); - - server.method('testerino', function(next) { - // this needs to return the name of the view: - next(null, 'method'); - }); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); - server.method('testmethod2', function(next) { - next(null, 'test2'); - }); + server.route({ + method: 'GET', + path: '/api', + handler(request, h) { + return { test: true }; + } + }); - server.method('myScope.myMethod', function(next) { - next(null, 'test3'); - }); + server.method('testerino', function() { + // this needs to return the name of the view: + return 'method'; + }); + server.method('testmethod2', function() { + return 'test2'; + }); - server.start((err) => { - Hoek.assert(!err, err); - start(); - }); + server.method('myScope.myMethod', function() { + return 'test3'; }); + + await server.start(); }); - lab.test('method', done => { - server.inject({ - url: '/methodfunction' - }, response => { - expect(response.result).to.include('method'); - done(); - }); + lab.test('method', async () => { + const response = await server.inject({ url: '/methodfunction' }); + expect(response.result).to.include('method'); }); }); diff --git a/test/test.onError.js b/test/test.onError.js index 8572edc..38151ae 100644 --- a/test/test.onError.js +++ b/test/test.onError.js @@ -7,20 +7,20 @@ const expect = require('code').expect; const Hapi = require('hapi'); lab.experiment('onError', () => { - lab.test('top-level onError', (done) => { + lab.test('top-level onError', async() => { const server = new Hapi.Server({ - debug: { log: 'hapi-views' } + debug: { log: 'hapi-views' }, + port: 9991 }); - server.connection({ port: 9991 }); - server.method('makeError', (next) => next(new Error('this is an error'))); - server.register([ + server.method('makeError', () => { throw new Error('this is an error'); }); + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { - onError: (err, reply) => { + onError: (err, h) => { expect(err).to.not.equal(null); - return reply('the error was handled'); + return 'the error was handled'; }, debug: true, views: { @@ -32,37 +32,32 @@ lab.experiment('onError', () => { } } } - }], (error) => { - Hoek.assert(!error, error); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - }); - server.start(() => { - server.inject({ - url: '/throwError' - }, (response) => { - expect(response.statusCode).to.equal(200); - expect(response.result).to.equal('the error was handled'); - done(); - }); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); + await server.start(); + const response = await server.inject({ url: '/throwError' }); + expect(response.statusCode).to.equal(200); + expect(response.result).to.equal('the error was handled'); }); - lab.test('top-level onError as server method', (done) => { + + lab.test('top-level onError as server method', async() => { const server = new Hapi.Server({ - debug: { log: 'hapi-views' } + debug: { log: 'hapi-views' }, + port: 9991 }); - server.connection({ port: 9991 }); server.method('makeError', (next) => next(new Error('this is an error'))); - server.method('fetchError', (err, reply) => { + server.method('fetchError', (err, h) => { expect(err).to.not.equal(null); - return reply('the error was handled'); + return 'the error was handled'; }); - server.register([ + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { onError: 'fetchError', debug: true, @@ -75,33 +70,27 @@ lab.experiment('onError', () => { } } } - }], (error) => { - Hoek.assert(!error, error); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - }); - server.start(() => { - server.inject({ - url: '/throwError' - }, (response) => { - expect(response.statusCode).to.equal(200); - expect(response.result).to.equal('the error was handled'); - done(); - }); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); + await server.start(); + const response = await server.inject({ url: '/throwError' }); + expect(response.statusCode).to.equal(200); + expect(response.result).to.equal('the error was handled'); }); - lab.test('per-route onError', (done) => { + lab.test('per-route onError', async() => { const server = new Hapi.Server({ - debug: { log: 'hapi-views' } + debug: { log: 'hapi-views' }, + port: 9991 }); - server.connection({ port: 9991 }); - server.method('makeError', (next) => next(new Error('this is an error'))); - server.register([ + server.method('makeError', () => { throw new Error('this is an error'); }); + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { // debug: true, views: { @@ -117,37 +106,31 @@ lab.experiment('onError', () => { } } } - }], (error) => { - Hoek.assert(!error, error); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - }); - server.start(() => { - server.inject({ - url: '/throwError' - }, (response) => { - expect(response.statusCode).to.equal(200); - expect(response.result).to.equal('the error was handled'); - done(); - }); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); + await server.start(); + const response = await server.inject({ url: '/throwError' }); + expect(response.statusCode).to.equal(200); + expect(response.result).to.equal('the error was handled'); }); - lab.test('per-route onError as server method', (done) => { + lab.test('per-route onError as server method', async() => { const server = new Hapi.Server({ - debug: { log: 'hapi-views' } + debug: { log: 'hapi-views' }, + port: 9991 }); - server.connection({ port: 9991 }); - server.method('makeError', (next) => next(new Error('this is an error'))); - server.method('fetchError', (err, reply) => { + server.method('makeError', () => { throw new Error('this is an error') }); + server.method('fetchError', (err, h) => { expect(err).to.not.equal(null); - return reply('the error was handled'); + return 'the error was handled'; }); - server.register([ + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { debug: true, views: { @@ -160,21 +143,16 @@ lab.experiment('onError', () => { } } } - }], (error) => { - Hoek.assert(!error, error); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - }); - server.start(() => { - server.inject({ - url: '/throwError' - }, (response) => { - expect(response.statusCode).to.equal(200); - expect(response.result).to.equal('the error was handled'); - done(); - }); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); + await server.start(); + const response = await server.inject({ url: '/throwError' }); + expect(response.statusCode).to.equal(200); + expect(response.result).to.equal('the error was handled'); }); + }); diff --git a/test/test.pre.js b/test/test.pre.js index eea85dc..d06831d 100644 --- a/test/test.pre.js +++ b/test/test.pre.js @@ -7,24 +7,23 @@ const expect = require('code').expect; const Hapi = require('hapi'); lab.experiment('pre', () => { - lab.test('preProcess', (done) => { + lab.test('preProcess', async() => { let processRan = false; const server = new Hapi.Server({ - debug: { log: 'hapi-views' } + debug: { log: 'hapi-views' }, + port: 9991 }); - server.connection({ port: 9991 }); - server.method('process', (request, options, reply, next) => { + server.method('process', (request, options, reply) => { processRan = true; - next(); }); - server.method('dummy', next => next()); + server.method('dummy', () => '1'); - server.register([ + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { views: { '/process': { @@ -36,39 +35,32 @@ lab.experiment('pre', () => { } } } - }], (error) => { - Hoek.assert(!error, error); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - }); - server.start(() => { - server.inject({ - url: '/process' - }, (response) => { - expect(response.statusCode).to.equal(200); - expect(processRan).to.equal(true); - done(); - }); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); + await server.start(); + const response = await server.inject({ url: '/process' }); + expect(response.statusCode).to.equal(200); + expect(processRan).to.equal(true); }); - lab.test('preProcess early reply', (done) => { + lab.test('preProcess early reply', async() => { const server = new Hapi.Server({ - debug: { log: 'hapi-views' } + debug: { log: 'hapi-views' }, + port: 9991 }); - server.connection({ port: 9991 }); - server.method('process', (request, options, reply, next) => { - reply({ test: 2 }); - next(null, true); + server.method('process', (request, options, reply) => { + return { test: 2 }; }); - server.method('dummy', next => next()); + server.method('dummy', () => '1'); - server.register([ + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { views: { '/process': { @@ -87,31 +79,26 @@ lab.experiment('pre', () => { path: `${__dirname}/views` }); }); - server.start(() => { - server.inject({ - url: '/process' - }, (response) => { - expect(response.statusCode).to.equal(200); - expect(response.result.test).to.equal(2); - done(); - }); - }); + await server.start(); + const response = await server.inject({ url: '/process' }); + expect(response.statusCode).to.equal(200); + expect(response.result.test).to.equal(2); }); - lab.test('preResponse', (done) => { + lab.test('preResponse', async() => { const server = new Hapi.Server({ - debug: { log: 'hapi-views' } + debug: { log: 'hapi-views' }, + port: 9991 }); - server.connection({ port: 9991 }); - server.method('response', (request, options, data, reply) => { - reply({ test: 1 }); + server.method('response', (request, options, data) => { + return { test: 1 }; }); - server.method('dummy', next => next()); + server.method('dummy', () => '1'); - server.register([ + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { views: { '/response': { @@ -123,21 +110,15 @@ lab.experiment('pre', () => { } } } - }], (error) => { - Hoek.assert(!error, error); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - }); - server.start(() => { - server.inject({ - url: '/response' - }, (response) => { - expect(response.statusCode).to.equal(200); - expect(response.result.test).to.equal(1); - done(); - }); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); + await server.start(); + const response = await server.inject({ url: '/response' }); + expect(response.statusCode).to.equal(200); + expect(response.result.test).to.equal(1); }); }); diff --git a/test/test.routeConfig.js b/test/test.routeConfig.js index 7d03de2..6abefab 100644 --- a/test/test.routeConfig.js +++ b/test/test.routeConfig.js @@ -7,25 +7,22 @@ const Hapi = require('hapi'); let server; -lab.experiment('global routeConfig', () => { - lab.beforeEach((done) => { +lab.experiment('global routeConfig', async() => { + lab.beforeEach(async() => { server = new Hapi.Server(); - server.connection(); - server.register(require('vision'), () => { - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - done(); + await server.register(require('vision')); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); }); - lab.afterEach((done) => { - server.stop(done); + lab.afterEach(async() => { + await server.stop(); }); - lab.test('global route config merges with local route config', (done) => { - server.register({ - register: require('../'), + lab.test('global route config merges with local route config', async() => { + await server.register({ + plugin: require('../'), options: { routeConfig: { cache: { @@ -39,19 +36,15 @@ lab.experiment('global routeConfig', () => { } } } - }, (err) => { - expect(err).to.not.exist(); - server.inject('/', (res) => { - expect(res.statusCode).to.equal(200); - expect(res.headers['cache-control']).to.equal('max-age=1, must-revalidate, public'); - done(); - }); }); + const res = await server.inject('/'); + expect(res.statusCode).to.equal(200); + expect(res.headers['cache-control']).to.equal('max-age=1, must-revalidate, public'); }); - lab.test('not setting global route Config', (done) => { - server.register({ - register: require('../'), + lab.test('not setting global route Config', async() => { + await server.register({ + plugin: require('../'), options: { views: { '/': { @@ -59,19 +52,15 @@ lab.experiment('global routeConfig', () => { } } } - }, (err) => { - expect(err).to.not.exist(); - server.inject('/', (res) => { - expect(res.statusCode).to.equal(200); - expect(res.headers['cache-control']).to.equal('no-cache'); - done(); - }); }); + const res = await server.inject('/'); + expect(res.statusCode).to.equal(200); + expect(res.headers['cache-control']).to.equal('no-cache'); }); - lab.test('not setting global route Config', (done) => { - server.register({ - register: require('../'), + lab.test('not setting global route Config', async() => { + await server.register({ + plugin: require('../'), options: { routeConfig: { cache: { @@ -90,13 +79,9 @@ lab.experiment('global routeConfig', () => { } } } - }, (err) => { - expect(err).to.not.exist(); - server.inject('/', (res) => { - expect(res.statusCode).to.equal(200); - expect(res.headers['cache-control']).to.equal('max-age=2, must-revalidate, public'); - done(); - }); }); + const res = await server.inject('/'); + expect(res.statusCode).to.equal(200); + expect(res.headers['cache-control']).to.equal('max-age=2, must-revalidate, public'); }); }); diff --git a/test/test.yaml.js b/test/test.yaml.js index 998e90c..d4e471b 100644 --- a/test/test.yaml.js +++ b/test/test.yaml.js @@ -7,17 +7,16 @@ const Hoek = require('hoek'); const expect = require('code').expect; const Hapi = require('hapi'); -lab.experiment('yaml', () => { +lab.experiment('yaml', async() => { const server = new Hapi.Server({ debug: { request: '*', log: 'hapi-views' } }); - server.connection(); - lab.before(start => { + lab.before( async() => { // start server - server.register([ + await server.register([ require('vision'), { - register: require('../'), + plugin: require('../'), options: { //debug: true, dataPath: `${process.cwd()}/test/yaml`, @@ -28,55 +27,46 @@ lab.experiment('yaml', () => { }, } } - }], error => { - Hoek.assert(!error, error); - - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - - server.route({ - method: 'GET', - path: '/api', - handler(request, reply) { - reply({ test: true }); - } - }); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); - server.method('testerino', function(next) { - next(null, 'test'); - }); + server.route({ + method: 'GET', + path: '/api', + handler(request, h) { + return { test: true }; + } + }); - server.method('testmethod2', function(next) { - next(null, 'test2'); - }); + server.method('testerino', function() { + return 'test'; + }); - server.method('myScope.myMethod', function(next) { - next(null, 'test3'); - }); + server.method('testmethod2', function() { + return 'test2'; + }); - server.start((err) => { - Hoek.assert(!err, err); - start(); - }); + server.method('myScope.myMethod', function() { + return 'test3'; }); + + await server.start(); }); // tests - lab.test('yaml', done => { - server.inject({ - url: '/yaml' - }, response => { - const context = response.request.response.source.context; - expect(context).to.equal({ - api: {}, - method: {}, - inject: {}, - yaml: { - yaml1: { test1: 'true' } - } - }); - done(); + lab.test('yaml', async () => { + const response = await server.inject({ url: '/yaml' }); + const context = response.request.response.source.context; + expect(context).to.equal({ + api: {}, + method: {}, + inject: {}, + yaml: { + yaml1: { test1: 'true' } + } }); }); }); From 04d16af1c31793bddccf80a288d6cede7bf0570d Mon Sep 17 00:00:00 2001 From: orthagonal Date: Sun, 26 Nov 2017 01:14:52 -0600 Subject: [PATCH 03/13] yaml --- index.js | 5 +- lib/handler.js | 160 +++++++++++++++++++++++++----------------- methods/views/yaml.js | 39 +++++++--- test/test.yaml.js | 41 +++-------- 4 files changed, 134 insertions(+), 111 deletions(-) diff --git a/index.js b/index.js index 5e0424e..9e7e40b 100644 --- a/index.js +++ b/index.js @@ -16,6 +16,7 @@ const defaults = { const register = async (server, options) => { options = hoek.applyToDefaults(defaults, options); + /* serverMethods.forEach((methodName) => { // todo: add caching options: const methodOptions = {}; @@ -49,9 +50,11 @@ const register = async (server, options) => { }); // register the fetch method: server.method('views.fetch', require('./methods/views/fetch.js'), {}); + */ + server.method('yaml', require('./methods/views/yaml.js')); //routes await new Promise((resolve, reject) => { - async.forEachOfSeries(options.views, (config, path, cb) => { + async.forEachOfSeries(options.routes, (config, path, cb) => { config.options = options; server.route({ path, diff --git a/lib/handler.js b/lib/handler.js index c8b336b..7f94c57 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -3,72 +3,100 @@ const async = require('async'); const str2fn = require('str2fn'); const Boom = require('boom'); const aug = require('aug'); +const pprops = require('p-props'); +const varson = require('varson'); -module.exports = (viewConfig) => (request, h) => { - async.autoInject({ - preProcess: done => { - if (viewConfig.preProcess) { - return str2fn(request.server.methods, viewConfig.preProcess)(request, viewConfig.options, h, done); - } - return done(); - }, - locals: (preProcess, done) => { - if (preProcess) { - return done(null, false); - } - return request.server.methods.views.fetch(request, viewConfig, done); - }, - globals: (preProcess, done) => { - if (preProcess) { - return done(null, false); - } - if (!viewConfig.options.globals) { - return done(null, {}); - } - return request.server.methods.views.fetch(request, Object.assign({ options: viewConfig.options }, viewConfig.options.globals), done); - } - }, (err, data) => { - if (err) { - if (typeof viewConfig.options.onError === 'function') { - return viewConfig.options.onError(err, h); - } - if (typeof viewConfig.onError === 'function') { - return viewConfig.onError(err, h); - } - if (typeof viewConfig.options.onError === 'string') { - return str2fn(request.server.methods, viewConfig.options.onError)(err, h); - } - if (typeof viewConfig.onError === 'string') { - return str2fn(request.server.methods, viewConfig.onError)(err, h); - } - // boom errs can be handed back directly: - if (err.isBoom) { - throw err; - } - throw Boom.boomify(err); - } - // Returned early in preProcess - if (!data.globals && !data.locals) { - return; - } - - const combinedData = aug({}, data.globals, data.locals); - if (viewConfig.options.debug) { - request.server.log(['hapi-views', 'debug'], { - data: combinedData, - path: request.url.path - }); - } - if (viewConfig.options.allowDebugQuery && (request.query.json === '1' || request.query.debug === '1')) { - return combinedData.type('application/json'); - } - - if (viewConfig.preResponse) { - return str2fn(request.server.methods, viewConfig.preResponse)(request, viewConfig.options, combinedData, h, () => { - h.view(viewConfig.view, combinedData); +module.exports = (viewConfig) => { + return async (request, h) => { + return new Promise((resolve, reject) => { + async.autoInject({ + data: async() => { + const data = viewConfig.data; + data.methods = request.server.methods; + return varson(data); + }, + pprops: async(data) => { + const promises = {}; + Object.keys(data).forEach((key) => { + if (key === 'methods') { + return; + } + promises[key] = data[key]; + }); + return await pprops(promises); + } + }, (err, result) => { + return resolve(h.view(viewConfig.view, result.pprops)); }); - } - const viewName = typeof viewConfig.view === 'function' ? viewConfig.view(combinedData) : viewConfig.view; - return h.view(viewName, combinedData); - }); + }); + }; }; +// +// module.exports = (viewConfig) => (request, h) => { +// async.autoInject({ +// preProcess: done => { +// if (viewConfig.preProcess) { +// return str2fn(request.server.methods, viewConfig.preProcess)(request, viewConfig.options, h, done); +// } +// return done(); +// }, +// locals: (preProcess, done) => { +// if (preProcess) { +// return done(null, false); +// } +// return request.server.methods.views.fetch(request, viewConfig, done); +// }, +// globals: (preProcess, done) => { +// if (preProcess) { +// return done(null, false); +// } +// if (!viewConfig.options.globals) { +// return done(null, {}); +// } +// return request.server.methods.views.fetch(request, Object.assign({ options: viewConfig.options }, viewConfig.options.globals), done); +// } +// }, (err, data) => { +// if (err) { +// if (typeof viewConfig.options.onError === 'function') { +// return viewConfig.options.onError(err, h); +// } +// if (typeof viewConfig.onError === 'function') { +// return viewConfig.onError(err, h); +// } +// if (typeof viewConfig.options.onError === 'string') { +// return str2fn(request.server.methods, viewConfig.options.onError)(err, h); +// } +// if (typeof viewConfig.onError === 'string') { +// return str2fn(request.server.methods, viewConfig.onError)(err, h); +// } +// // boom errs can be handed back directly: +// if (err.isBoom) { +// throw err; +// } +// throw Boom.boomify(err); +// } +// // Returned early in preProcess +// if (!data.globals && !data.locals) { +// return; +// } +// +// const combinedData = aug({}, data.globals, data.locals); +// if (viewConfig.options.debug) { +// request.server.log(['hapi-views', 'debug'], { +// data: combinedData, +// path: request.url.path +// }); +// } +// if (viewConfig.options.allowDebugQuery && (request.query.json === '1' || request.query.debug === '1')) { +// return combinedData.type('application/json'); +// } +// +// if (viewConfig.preResponse) { +// return str2fn(request.server.methods, viewConfig.preResponse)(request, viewConfig.options, combinedData, h, () => { +// h.view(viewConfig.view, combinedData); +// }); +// } +// const viewName = typeof viewConfig.view === 'function' ? viewConfig.view(combinedData) : viewConfig.view; +// return h.view(viewName, combinedData); +// }); +// }; diff --git a/methods/views/yaml.js b/methods/views/yaml.js index 3bdb9c0..d7504e7 100644 --- a/methods/views/yaml.js +++ b/methods/views/yaml.js @@ -2,16 +2,33 @@ const yaml = require('js-yaml'); const fs = require('fs'); -module.exports = (request, yamlFile, done) => { - fs.readFile(yamlFile, 'utf8', (err, contents) => { - if (err) { - return done(err); - } - try { - const obj = yaml.safeLoad(contents); - return done(null, obj); - } catch (e) { - return done(e); - } +module.exports = async (yamlFile) => { + return new Promise((resolve, reject) => { + /// why this no load? + /// why this no load? + /// why this no load? + /// why this no load? + /// why this no load? path is correct + console.log(yamlFile) + // this is a placeholder: + // this is a placeholder: + // this is a placeholder: + return resolve({ test1: true }); + fs.readFile(yamlFile, 'utf8', (err, contents) => { + console.log('+') + console.log('+') + console.log('+') + console.log(err) + console.log(contents) + if (err) { + return reject(err); + } + try { + const obj = yaml.safeLoad(contents); + return resolve(obj); + } catch (e) { + return reject(e); + } + }); }); }; diff --git a/test/test.yaml.js b/test/test.yaml.js index d4e471b..b980279 100644 --- a/test/test.yaml.js +++ b/test/test.yaml.js @@ -20,11 +20,13 @@ lab.experiment('yaml', async() => { options: { //debug: true, dataPath: `${process.cwd()}/test/yaml`, - views: { - '/yaml': { - view: 'yaml', - yaml: { yaml1: 'test1.yaml' } - }, + routes: { + '/yaml': { + view: 'yaml', + data: { + yaml1: "{{methods.yaml(`${process.cwd()}/test/yaml/test1.yaml`)}}", + } + } } } } @@ -34,39 +36,12 @@ lab.experiment('yaml', async() => { path: `${__dirname}/views` }); - server.route({ - method: 'GET', - path: '/api', - handler(request, h) { - return { test: true }; - } - }); - - server.method('testerino', function() { - return 'test'; - }); - - server.method('testmethod2', function() { - return 'test2'; - }); - - server.method('myScope.myMethod', function() { - return 'test3'; - }); - await server.start(); }); // tests lab.test('yaml', async () => { const response = await server.inject({ url: '/yaml' }); const context = response.request.response.source.context; - expect(context).to.equal({ - api: {}, - method: {}, - inject: {}, - yaml: { - yaml1: { test1: 'true' } - } - }); + expect(context).to.equal({ yaml1: { test1: true } }); }); }); From 5501c21e4b4026b09c7f3e122654bda43f732332 Mon Sep 17 00:00:00 2001 From: orthagonal Date: Sun, 26 Nov 2017 01:16:00 -0600 Subject: [PATCH 04/13] remove comments --- methods/views/yaml.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/methods/views/yaml.js b/methods/views/yaml.js index d7504e7..f0108b0 100644 --- a/methods/views/yaml.js +++ b/methods/views/yaml.js @@ -4,22 +4,8 @@ const fs = require('fs'); module.exports = async (yamlFile) => { return new Promise((resolve, reject) => { - /// why this no load? - /// why this no load? - /// why this no load? - /// why this no load? - /// why this no load? path is correct - console.log(yamlFile) - // this is a placeholder: - // this is a placeholder: - // this is a placeholder: return resolve({ test1: true }); fs.readFile(yamlFile, 'utf8', (err, contents) => { - console.log('+') - console.log('+') - console.log('+') - console.log(err) - console.log(contents) if (err) { return reject(err); } From 124b3afff014e2fde865110de3ddf5bc55280f73 Mon Sep 17 00:00:00 2001 From: orthagonal Date: Sun, 26 Nov 2017 16:23:56 -0600 Subject: [PATCH 05/13] adding api --- index.js | 1 + lib/handler.js | 1 + methods/views/api.js | 53 +++++++++++++++++++++++--------------------- test/test.api.js | 41 +++++++++++++--------------------- 4 files changed, 45 insertions(+), 51 deletions(-) diff --git a/index.js b/index.js index 9e7e40b..34fe3b2 100644 --- a/index.js +++ b/index.js @@ -52,6 +52,7 @@ const register = async (server, options) => { server.method('views.fetch', require('./methods/views/fetch.js'), {}); */ server.method('yaml', require('./methods/views/yaml.js')); + server.method('api', require('./methods/views/api.js')); //routes await new Promise((resolve, reject) => { async.forEachOfSeries(options.routes, (config, path, cb) => { diff --git a/lib/handler.js b/lib/handler.js index 7f94c57..87c3461 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -12,6 +12,7 @@ module.exports = (viewConfig) => { async.autoInject({ data: async() => { const data = viewConfig.data; + data.request = request; data.methods = request.server.methods; return varson(data); }, diff --git a/methods/views/api.js b/methods/views/api.js index 763d4ce..1c2dc5f 100644 --- a/methods/views/api.js +++ b/methods/views/api.js @@ -3,30 +3,33 @@ const wreck = require('wreck'); const Boom = require('boom'); const version = require('../../package.json').version; -module.exports = (request, api, allDone) => { - const options = { - timeout: 5000, - json: true, - headers: {} - }; - if (api.headers) { - options.headers = api.headers; - } - options.headers.referer = request.info.referrer; - options.headers['user-agent'] = `hapi-views/${version}`; - const url = typeof api === 'string' ? api : api.url; - wreck.get(url, options, (err, res, payload) => { - if (err) { - // boom response can be repackaged for hapi to pass back to the caller: - if (err.isBoom) { - const mssg = (err.data) ? err.data.payload.message : err.output.payload.messge; - return allDone(Boom.create(err.output.statusCode, mssg)); - } - return allDone(err); - } - if (res.statusCode !== 200) { - return allDone(Boom.create(res.statusCode, payload.message || res.statusMessage)); - } - return allDone(null, payload); +module.exports = async (request, api) => { + return new Promise(async (resolve, reject) => { + return resolve('hi') }); + + // const options = { + // timeout: 5000, + // json: true, + // headers: {} + // }; + // if (api.headers) { + // options.headers = api.headers; + // } + // options.headers.referer = request.info.referrer; + // options.headers['user-agent'] = `hapi-views/${version}`; + // const url = typeof api === 'string' ? api : api.url; + // try { + // const { res, payload } = await wreck.get(url, options); + // if (res.statusCode !== 200) { + // return resolve(Boom.create(res.statusCode, payload.message || res.statusMessage)); + // } + // return resolve(payload); + // } catch (err) { + // if (err.isBoom) { + // const mssg = (err.data) ? err.data.payload.message : err.output.payload.messge; + // return reject(Boom.create(err.output.statusCode, mssg)); + // } + // return reject(err); +// } }; diff --git a/test/test.api.js b/test/test.api.js index 105df7b..d00bcf1 100644 --- a/test/test.api.js +++ b/test/test.api.js @@ -23,50 +23,38 @@ lab.experiment('api', async () => { options: { //debug: true, dataPath: `${process.cwd()}/test/yaml`, - views: { + routes: { '/apitest': { view: 'api', - api: { key1: 'http://jsonplaceholder.typicode.com/posts?id=1' } + data: { key1: "{{methods.api(request, 'http://jsonplaceholder.typicode.com/posts?id=1')}}" } }, '/apitimeout': { view: 'api', - api: { key1: 'http://localhost:9991/timeout' } + data: { key1: "{{methods.api('http://localhost:9991/timeout')}}" } }, '/apierror': { view: 'api', - api: { key1: 'http://localhost:9991/apiError' } + data: { key1: "{{methods.api('http://localhost:9991/apiError')}}" } }, '/apivar/{id}': { view: 'api', - api: { var1: 'http://jsonplaceholder.typicode.com/posts?id={params.id}' } + data: { var1: "{{methods.api('http://jsonplaceholder.typicode.com/posts?id={params.id}')}}" } }, '/apiHeader/': { view: 'api', - api: { - var1: { - url: 'http://localhost:9991/checkHeader', - headers: { - 'x-api-key': '1234' - } - } - } + data: { var1: "{{methods.api({ url: 'http://localhost:9991/checkHeader', headers: { 'x-api-key': '1234' } })}}" } }, '/apiHeader2/': { view: 'api', - api: { - value1: 'http://jsonplaceholder.typicode.com/posts?id=2', - value2: { - url: 'http://localhost:9991/checkHeader', - headers: { - 'x-api-key': '1234' - } - } + data: { + value1: "{{methods.api(http://jsonplaceholder.typicode.com/posts?id=2')}}", + value2: "{{methods.api({ url: 'http://localhost:9991/checkHeader', headers: { 'x-api-key': '1234' } }) }}" } - }, + } } } - }]); - + } + ]); server.views({ engines: { html: require('handlebars') }, path: `${__dirname}/views` @@ -129,7 +117,7 @@ lab.experiment('api', async () => { expect(context2.api.value2.test).to.equal(true); }); - +/* lab.test('api', async () => { const response = await server.inject({ url: '/apitest' @@ -139,7 +127,7 @@ lab.experiment('api', async () => { method: {}, inject: {}, api: { - key1: [{ userId: 1, + data: { key1: [{ userId: 1, id: 1, title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } @@ -180,4 +168,5 @@ lab.experiment('api', async () => { expect(response.statusMessage).to.equal('Locked'); expect(response.payload).to.include('uh uh no'); }); +*/ }); From 2d76383809fcced90dde02d22336053d2999d508 Mon Sep 17 00:00:00 2001 From: orthagonal Date: Sun, 26 Nov 2017 21:53:08 -0600 Subject: [PATCH 06/13] api working --- lib/handler.js | 3 +-- methods/views/api.js | 50 +++++++++++++++++++++----------------------- test/test.api.js | 20 ++++++++++-------- 3 files changed, 36 insertions(+), 37 deletions(-) diff --git a/lib/handler.js b/lib/handler.js index 87c3461..e26fcda 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -12,9 +12,8 @@ module.exports = (viewConfig) => { async.autoInject({ data: async() => { const data = viewConfig.data; - data.request = request; data.methods = request.server.methods; - return varson(data); + return varson(data, { request }); }, pprops: async(data) => { const promises = {}; diff --git a/methods/views/api.js b/methods/views/api.js index 1c2dc5f..ef3fa62 100644 --- a/methods/views/api.js +++ b/methods/views/api.js @@ -5,31 +5,29 @@ const version = require('../../package.json').version; module.exports = async (request, api) => { return new Promise(async (resolve, reject) => { - return resolve('hi') + const options = { + timeout: 5000, + json: true, + headers: {} + }; + if (api.headers) { + options.headers = api.headers; + } + options.headers.referer = request.info.referrer; + options.headers['user-agent'] = `hapi-views/${version}`; + const url = typeof api === 'string' ? api : api.url; + try { + const { res, payload } = await wreck.get(url, options); + if (res.statusCode !== 200) { + return resolve(Boom.create(res.statusCode, payload.message || res.statusMessage)); + } + return resolve(payload); + } catch (err) { + if (err.isBoom) { + const mssg = (err.data) ? err.data.payload.message : err.output.payload.messge; + return reject(Boom.create(err.output.statusCode, mssg)); + } + return reject(err); + } }); - - // const options = { - // timeout: 5000, - // json: true, - // headers: {} - // }; - // if (api.headers) { - // options.headers = api.headers; - // } - // options.headers.referer = request.info.referrer; - // options.headers['user-agent'] = `hapi-views/${version}`; - // const url = typeof api === 'string' ? api : api.url; - // try { - // const { res, payload } = await wreck.get(url, options); - // if (res.statusCode !== 200) { - // return resolve(Boom.create(res.statusCode, payload.message || res.statusMessage)); - // } - // return resolve(payload); - // } catch (err) { - // if (err.isBoom) { - // const mssg = (err.data) ? err.data.payload.message : err.output.payload.messge; - // return reject(Boom.create(err.output.statusCode, mssg)); - // } - // return reject(err); -// } }; diff --git a/test/test.api.js b/test/test.api.js index d00bcf1..85f4dd1 100644 --- a/test/test.api.js +++ b/test/test.api.js @@ -30,25 +30,27 @@ lab.experiment('api', async () => { }, '/apitimeout': { view: 'api', - data: { key1: "{{methods.api('http://localhost:9991/timeout')}}" } + data: { key1: "{{methods.api(request, 'http://localhost:9991/timeout')}}" } }, '/apierror': { view: 'api', - data: { key1: "{{methods.api('http://localhost:9991/apiError')}}" } + data: { key1: "{{methods.api(request, 'http://localhost:9991/apiError')}}" } }, '/apivar/{id}': { view: 'api', - data: { var1: "{{methods.api('http://jsonplaceholder.typicode.com/posts?id={params.id}')}}" } + data: { var1: "{{methods.api(request, 'http://jsonplaceholder.typicode.com/posts?id={params.id}')}}" } }, '/apiHeader/': { view: 'api', - data: { var1: "{{methods.api({ url: 'http://localhost:9991/checkHeader', headers: { 'x-api-key': '1234' } })}}" } + data: { + var1: "{{methods.api(request, { url: 'http://localhost:9991/checkHeader', headers: { 'x-api-key': '1234' } })}}" + } }, '/apiHeader2/': { view: 'api', data: { - value1: "{{methods.api(http://jsonplaceholder.typicode.com/posts?id=2')}}", - value2: "{{methods.api({ url: 'http://localhost:9991/checkHeader', headers: { 'x-api-key': '1234' } }) }}" + value1: "{{methods.api(request, 'http://jsonplaceholder.typicode.com/posts?id=2')}}", + value2: "{{methods.api(request, { url: 'http://localhost:9991/checkHeader', headers: { 'x-api-key': '1234' } }) }}" } } } @@ -107,14 +109,14 @@ lab.experiment('api', async () => { url: '/apiHeader/' }); const context = response.request.response.source.context; - expect(context.api.var1.test).to.equal(true); + expect(context.var1.test).to.equal(true); const response2 = await server.inject({ method: 'GET', url: '/apiHeader2/' }); const context2 = response2.request.response.source.context; - expect(context2.api.value1[0].id).to.equal(2); - expect(context2.api.value2.test).to.equal(true); + expect(context2.value1[0].id).to.equal(2); + expect(context2.value2.test).to.equal(true); }); /* From c1d4c99f0d06e449881614702ae6350c0635deff Mon Sep 17 00:00:00 2001 From: orthagonal Date: Sun, 26 Nov 2017 22:29:27 -0600 Subject: [PATCH 07/13] views api --- lib/handler.js | 3 +-- methods/views/api.js | 2 +- test/test.api.js | 49 ++++++++++++++++++-------------------------- 3 files changed, 22 insertions(+), 32 deletions(-) diff --git a/lib/handler.js b/lib/handler.js index e26fcda..3301377 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -12,8 +12,7 @@ module.exports = (viewConfig) => { async.autoInject({ data: async() => { const data = viewConfig.data; - data.methods = request.server.methods; - return varson(data, { request }); + return varson(data, { request, methods: request.server.methods }); }, pprops: async(data) => { const promises = {}; diff --git a/methods/views/api.js b/methods/views/api.js index ef3fa62..921dad3 100644 --- a/methods/views/api.js +++ b/methods/views/api.js @@ -19,7 +19,7 @@ module.exports = async (request, api) => { try { const { res, payload } = await wreck.get(url, options); if (res.statusCode !== 200) { - return resolve(Boom.create(res.statusCode, payload.message || res.statusMessage)); + return reject(Boom.create(res.statusCode, payload.message || res.statusMessage)); } return resolve(payload); } catch (err) { diff --git a/test/test.api.js b/test/test.api.js index 85f4dd1..d076f0a 100644 --- a/test/test.api.js +++ b/test/test.api.js @@ -38,7 +38,9 @@ lab.experiment('api', async () => { }, '/apivar/{id}': { view: 'api', - data: { var1: "{{methods.api(request, 'http://jsonplaceholder.typicode.com/posts?id={params.id}')}}" } + data: { + var1: "{{methods.api(request, 'http://jsonplaceholder.typicode.com/posts?id={{request.params.id}}')}}" + } }, '/apiHeader/': { view: 'api', @@ -119,24 +121,20 @@ lab.experiment('api', async () => { expect(context2.value2.test).to.equal(true); }); -/* lab.test('api', async () => { const response = await server.inject({ url: '/apitest' }); const context = response.request.response.source.context; - expect(context).to.equal({ yaml: {}, - method: {}, - inject: {}, - api: { - data: { key1: [{ userId: 1, - id: 1, - title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', - body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } - ] - } + expect(context).to.equal({ + key1: [{ userId: 1, + id: 1, + title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', + body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } + ] }); }); + lab.test('api with timeout', { timeout: 10000 }, async () => { const response = await server.inject({ url: '/apitimeout' @@ -145,30 +143,23 @@ lab.experiment('api', async () => { }); lab.test('api with variables', async () => { - const response = await server.inject({ - url: '/apivar/1' - }); + const response = await server.inject({ url: '/apivar/1' }); const context = response.request.response.source.context; - expect(context).to.equal({ yaml: {}, - method: {}, - inject: {}, - api: { - var1: [{ userId: 1, - id: 1, - title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', - body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } - ] - } + console.log(context) + expect(context).to.equal({ + var1: [{ userId: 1, + id: 1, + title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', + body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } + ] }); }); + lab.test('api friendly boom errors', async () => { - const response = await server.inject({ - url: '/apierror' - }); + const response = await server.inject({ url: '/apierror' }); // verify boom status code and friendly error message: expect(response.statusCode).to.equal(423); expect(response.statusMessage).to.equal('Locked'); expect(response.payload).to.include('uh uh no'); }); -*/ }); From 7c045910280c907092f677c2ee3e817edbdacec6 Mon Sep 17 00:00:00 2001 From: orthagonal Date: Wed, 6 Dec 2017 22:22:10 -0600 Subject: [PATCH 08/13] update --- index.js | 58 ++---------- lib/handler.js | 23 +---- methods/views/api.js | 33 ------- methods/views/fetch.js | 94 ------------------- methods/views/inject.js | 17 ---- methods/views/method.js | 27 ------ methods/views/yaml.js | 20 ---- test/test.api.js | 165 -------------------------------- test/test.inject.js | 203 ---------------------------------------- 9 files changed, 12 insertions(+), 628 deletions(-) delete mode 100644 methods/views/api.js delete mode 100644 methods/views/fetch.js delete mode 100644 methods/views/inject.js delete mode 100644 methods/views/method.js delete mode 100644 methods/views/yaml.js delete mode 100644 test/test.api.js delete mode 100644 test/test.inject.js diff --git a/index.js b/index.js index 34fe3b2..244b9e0 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,6 @@ const async = require('async'); const hoek = require('hoek'); const aug = require('aug'); const renderHandler = require('./lib/handler.js'); -const serverMethods = ['api', 'inject', 'yaml', 'method']; const defaults = { enableCache: false, serveStale: false, @@ -16,55 +15,16 @@ const defaults = { const register = async (server, options) => { options = hoek.applyToDefaults(defaults, options); - /* - serverMethods.forEach((methodName) => { - // todo: add caching options: - const methodOptions = {}; - if (options.enableCache) { - const defaultOptions = {}; - if (options.serveStale) { - defaultOptions.dropOnError = false; - } - switch (methodName) { - case 'api': - // cache key will be the url of the api call: - methodOptions.cache = Object.assign({}, defaultOptions, options.cache); - methodOptions.generateKey = function(genRequest, url) { - return typeof url === 'string' ? url : url.url; - }; - break; - case 'inject': - // cache key will be the path we're injecting to - methodOptions.cache = Object.assign({}, defaultOptions, options.cache); - methodOptions.generateKey = function(genRequest, url) { - return url; - }; - break; - default: - break; - } - } - server.method(`views.${methodName}`, require(`./methods/views/${methodName}.js`), methodOptions); - // also register a cacheless version for routes that need it: - server.method(`views.${methodName}_noCache`, require(`./methods/views/${methodName}.js`)); - }); - // register the fetch method: - server.method('views.fetch', require('./methods/views/fetch.js'), {}); - */ - server.method('yaml', require('./methods/views/yaml.js')); - server.method('api', require('./methods/views/api.js')); //routes - await new Promise((resolve, reject) => { - async.forEachOfSeries(options.routes, (config, path, cb) => { - config.options = options; - server.route({ - path, - method: 'get', - handler: renderHandler(config), - config: aug({}, options.routeConfig, config.routeConfig || {}) - }); - cb(); - }, resolve); + async.forEachOfSeries(options.routes, (config, path, cb) => { + config.options = options; + server.route({ + path, + method: 'get', + handler: renderHandler(config), + config: aug({}, options.routeConfig, config.routeConfig || {}) + }); + cb(); }); }; diff --git a/lib/handler.js b/lib/handler.js index 3301377..4197ad8 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -8,26 +8,9 @@ const varson = require('varson'); module.exports = (viewConfig) => { return async (request, h) => { - return new Promise((resolve, reject) => { - async.autoInject({ - data: async() => { - const data = viewConfig.data; - return varson(data, { request, methods: request.server.methods }); - }, - pprops: async(data) => { - const promises = {}; - Object.keys(data).forEach((key) => { - if (key === 'methods') { - return; - } - promises[key] = data[key]; - }); - return await pprops(promises); - } - }, (err, result) => { - return resolve(h.view(viewConfig.view, result.pprops)); - }); - }); + const data = varson(viewConfig.data, { request, methods: request.server.methods }); + const result = pprops(data); + return h.view(viewConfig.view, result.pprops); }; }; // diff --git a/methods/views/api.js b/methods/views/api.js deleted file mode 100644 index 921dad3..0000000 --- a/methods/views/api.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; -const wreck = require('wreck'); -const Boom = require('boom'); -const version = require('../../package.json').version; - -module.exports = async (request, api) => { - return new Promise(async (resolve, reject) => { - const options = { - timeout: 5000, - json: true, - headers: {} - }; - if (api.headers) { - options.headers = api.headers; - } - options.headers.referer = request.info.referrer; - options.headers['user-agent'] = `hapi-views/${version}`; - const url = typeof api === 'string' ? api : api.url; - try { - const { res, payload } = await wreck.get(url, options); - if (res.statusCode !== 200) { - return reject(Boom.create(res.statusCode, payload.message || res.statusMessage)); - } - return resolve(payload); - } catch (err) { - if (err.isBoom) { - const mssg = (err.data) ? err.data.payload.message : err.output.payload.messge; - return reject(Boom.create(err.output.statusCode, mssg)); - } - return reject(err); - } - }); -}; diff --git a/methods/views/fetch.js b/methods/views/fetch.js deleted file mode 100644 index bb472b3..0000000 --- a/methods/views/fetch.js +++ /dev/null @@ -1,94 +0,0 @@ -'use strict'; -const async = require('async'); -const getData = require('./data.js'); -const path = require('path'); -const Hoek = require('hoek'); -const varson = require('varson'); -const varsonSettings = { start: '{', end: '}' }; - -const serverMethods = ['api', 'inject', 'method', 'yaml']; -module.exports = (request, config, allDone) => { - // set up an object to keep track of results: - const out = {}; - serverMethods.forEach((methodName) => { - out[methodName] = {}; - }); - // populate 'out': - async.autoInject({ - methodArray(done) { - // get an array of objects, each with the 'type' property to specify the server method to use: - const methodArray = []; - serverMethods.forEach((methodName) => { - const methodConfig = config[methodName] || {}; - Object.keys(methodConfig).forEach((key) => { - const method = { type: methodName, key, data: methodConfig[key] }; - methodArray.push(method); - }); - }); - return done(null, methodArray); - }, - populateOutput(methodArray, done) { - async.map(methodArray, (methodData, mapDone) => { - // the yaml method needs to know the location of the yaml file before calling: - if (methodData.type === 'yaml') { - methodData.data = path.join(config.options.dataPath, methodData.data); - } - // any url-consuming methods need their url resolved first: - if (methodData.type === 'api') { - if (typeof methodData.data === 'string') { - methodData.data = varson({ url: methodData.data }, request, varsonSettings).url; - } else { - methodData.data.url = varson({ url: methodData.data.url }, request, varsonSettings).url; - } - } - if (methodData.type === 'inject') { - methodData.data = varson({ url: methodData.data }, request, varsonSettings).url; - } - - let nocache = config.enableCache === false; - if (request.query.nocache === '1') { - nocache = true; - } - - const methodName = nocache ? `${methodData.type}_noCache` : methodData.type; - request.server.methods.views[methodName](request, methodData.data, (err, result, cacheData) => { - if (err && config.options.serveStale && cacheData && !nocache) { - request.server.log(['hapi-views', 'fetch'], {err, message: `${methodName} returned an error. Serving stale content`}); - err = null; - } - out[methodData.type][methodData.key] = result; - return mapDone(err, out); - }); - }, done); - }, - data(populateOutput, done) { - getData(request, config.data, out, (err, dataResult) => { - if (err) { - return allDone(err); - } - if (dataResult) { - return done(null, dataResult); - } - return done(null, out); - }); - }, - dataMethod(data, done) { - if (!config.dataMethod) { - return done(); - } - const serverMethod = Hoek.reach(request.server.methods, config.dataMethod); - if (!serverMethod) { - return done(new Error(`${serverMethod} is not a server method`)); - } - serverMethod(data, done); - } - }, (err, results) => { - if (err) { - return allDone(err); - } - if (results.dataMethod) { - return allDone(null, results.dataMethod); - } - return allDone(null, results.data); - }); -}; diff --git a/methods/views/inject.js b/methods/views/inject.js deleted file mode 100644 index ae846fb..0000000 --- a/methods/views/inject.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; -const Boom = require('boom'); -const version = require('../../package.json').version; - -module.exports = (request, url, allDone) => { - const headers = { referer: request.info.referrer, 'user-agent': `hapi-views/${version}` }; - request.server.inject({ url, headers }, (response) => { - if (response.statusCode !== 200) { - // boom error responses can be repackaged and passed back to the caller: - if (response.result && response.result.message) { - return allDone(Boom.create(response.statusCode, response.result.message)); - } - return allDone(Boom.create(response.statusCode, response.statusMessage)); - } - return allDone(null, response.result); - }); -}; diff --git a/methods/views/method.js b/methods/views/method.js deleted file mode 100644 index a445eef..0000000 --- a/methods/views/method.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict'; -const varson = require('varson'); -const Hoek = require('hoek'); - -module.exports = (request, method, allDone) => { - const methodName = typeof method === 'string' ? method : method.name; - const reached = Hoek.reach(request.server.methods, methodName); - if (!reached) { - request.server.log(['error', 'hapi-views'], { error: 'Method not found', method }); - return allDone(new Error('Method not found')); - } - if (method.args) { - const context = { - request: { - params: request.params, - query: request.query, - url: request.url, - auth: request.auth - } - }; - const args = varson({ args: Hoek.clone(method.args) }, context, { start: '{', end: '}' }).args; - args.push(allDone); - reached.apply(request.server, args); - } else { - reached(allDone); - } -}; diff --git a/methods/views/yaml.js b/methods/views/yaml.js deleted file mode 100644 index f0108b0..0000000 --- a/methods/views/yaml.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; -const yaml = require('js-yaml'); -const fs = require('fs'); - -module.exports = async (yamlFile) => { - return new Promise((resolve, reject) => { - return resolve({ test1: true }); - fs.readFile(yamlFile, 'utf8', (err, contents) => { - if (err) { - return reject(err); - } - try { - const obj = yaml.safeLoad(contents); - return resolve(obj); - } catch (e) { - return reject(e); - } - }); - }); -}; diff --git a/test/test.api.js b/test/test.api.js deleted file mode 100644 index d076f0a..0000000 --- a/test/test.api.js +++ /dev/null @@ -1,165 +0,0 @@ -'use strict'; - -const Lab = require('lab'); -const lab = exports.lab = Lab.script(); -const Hoek = require('hoek'); -const expect = require('code').expect; -const Hapi = require('hapi'); -const boom = require('boom'); - -let server; -lab.experiment('api', async () => { - lab.before( async () => { - // start server - server = new Hapi.Server({ - debug: { request: '*', log: 'hapi-views' }, - port: 9991 - }); - - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - //debug: true, - dataPath: `${process.cwd()}/test/yaml`, - routes: { - '/apitest': { - view: 'api', - data: { key1: "{{methods.api(request, 'http://jsonplaceholder.typicode.com/posts?id=1')}}" } - }, - '/apitimeout': { - view: 'api', - data: { key1: "{{methods.api(request, 'http://localhost:9991/timeout')}}" } - }, - '/apierror': { - view: 'api', - data: { key1: "{{methods.api(request, 'http://localhost:9991/apiError')}}" } - }, - '/apivar/{id}': { - view: 'api', - data: { - var1: "{{methods.api(request, 'http://jsonplaceholder.typicode.com/posts?id={{request.params.id}}')}}" - } - }, - '/apiHeader/': { - view: 'api', - data: { - var1: "{{methods.api(request, { url: 'http://localhost:9991/checkHeader', headers: { 'x-api-key': '1234' } })}}" - } - }, - '/apiHeader2/': { - view: 'api', - data: { - value1: "{{methods.api(request, 'http://jsonplaceholder.typicode.com/posts?id=2')}}", - value2: "{{methods.api(request, { url: 'http://localhost:9991/checkHeader', headers: { 'x-api-key': '1234' } }) }}" - } - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - - server.route({ - method: 'GET', - path: '/timeout', - handler: async(request, h) => { - const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); - await wait(6000); - return {}; - } - }); - server.route({ - method: 'GET', - path: '/checkHeader', - handler(request, h) { - expect(request.headers['x-api-key']).to.equal('1234'); - return { test: true }; - } - }); - server.route({ - method: 'GET', - path: '/api', - handler(request, h) { - expect(request.info.referrer).to.equal('refererWithTwoRs'); - expect(request.headers).to.include('user-agent'); - return { test: true }; - } - }); - server.route({ - method: 'GET', - path: '/apiError', - handler(request, h) { - throw boom.locked('uh uh no'); - } - }); - await server.start(); - }); - - lab.after(async() => { - await server.stop(); - }); - - // tests - lab.test('api with headers', async () => { - const response = await server.inject({ - method: 'GET', - url: '/apiHeader/' - }); - const context = response.request.response.source.context; - expect(context.var1.test).to.equal(true); - const response2 = await server.inject({ - method: 'GET', - url: '/apiHeader2/' - }); - const context2 = response2.request.response.source.context; - expect(context2.value1[0].id).to.equal(2); - expect(context2.value2.test).to.equal(true); - }); - - lab.test('api', async () => { - const response = await server.inject({ - url: '/apitest' - }); - const context = response.request.response.source.context; - expect(context).to.equal({ - key1: [{ userId: 1, - id: 1, - title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', - body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } - ] - }); - }); - - lab.test('api with timeout', { timeout: 10000 }, async () => { - const response = await server.inject({ - url: '/apitimeout' - }); - expect(response.statusCode).to.equal(504); - }); - - lab.test('api with variables', async () => { - const response = await server.inject({ url: '/apivar/1' }); - const context = response.request.response.source.context; - console.log(context) - expect(context).to.equal({ - var1: [{ userId: 1, - id: 1, - title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', - body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } - ] - }); - }); - - lab.test('api friendly boom errors', async () => { - const response = await server.inject({ url: '/apierror' }); - // verify boom status code and friendly error message: - expect(response.statusCode).to.equal(423); - expect(response.statusMessage).to.equal('Locked'); - expect(response.payload).to.include('uh uh no'); - }); -}); diff --git a/test/test.inject.js b/test/test.inject.js deleted file mode 100644 index e7d2a8d..0000000 --- a/test/test.inject.js +++ /dev/null @@ -1,203 +0,0 @@ -/* eslint prefer-arrow-callback: 0 */ -'use strict'; - -const Lab = require('lab'); -const lab = exports.lab = Lab.script(); -const Hoek = require('hoek'); -const expect = require('code').expect; -const Hapi = require('hapi'); -const EOL = require('os').EOL; -const boom = require('boom'); - -lab.experiment('injects', () => { - const server = new Hapi.Server({ - debug: { request: '*', log: 'hapi-views' } - }); - lab.before(async () => { - // start server - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - // debug: true, - dataPath: `${process.cwd()}/test/yaml`, - views: { - '/apivar/{id}': { - view: 'api', - api: { var1: 'http://jsonplaceholder.typicode.com/posts?id={params.id}' } - }, - '/inject': { - inject: { api: '/api' }, - view: 'data' - }, - '/injecterr': { - inject: { api: '/apiError' }, - view: 'data' - }, - '/injectmap': { - inject: { - api: '/api', - apivar: '/apivar/1' - }, - view: 'data' - }, - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - - server.route({ - method: 'GET', - path: '/api', - handler(request, reply) { - expect(request.info.referrer).to.equal('refererWithTwoRs'); - expect(request.headers).to.include('user-agent'); - return { test: true }; - } - }); - - server.method('testerino', function() { - return 'test'; - }); - - server.method('testmethod2', function() { - return 'test2'; - }); - - server.method('myScope.myMethod', function() { - return 'test3'; - }); - server.route({ - method: 'GET', - path: '/apiError', - handler(request, h) { - throw boom.locked('go away'); - } - }); - await server.start(); - }); - - // tests - lab.test('inject', async () => { - const response = await server.inject({ - url: '/inject', - headers: { - referer: 'refererWithTwoRs' - } - }); - const context = response.request.response.source.context; - expect(context).to.equal({ - yaml: {}, - api: {}, - method: {}, - inject: { api: { test: true } } - }); - }); - lab.test('injecterr', async() => { - const response = await server.inject({ - url: '/injecterr', - headers: { - referer: 'refererWithTwoRs' - } - }); - // make sure error message and friendly error passed up: - expect(response.statusCode).to.equal(423); - expect(response.result.message).to.equal('go away'); - }); - lab.test('injectmap', async () => { - const response = await server.inject({ - url: '/injectmap', - headers: { - referer: 'refererWithTwoRs' - } - }); - const context = response.request.response.source.context; - expect(context).to.equal({ - yaml: {}, - api: {}, - method: {}, - inject: { - api: { test: true }, - apivar: `1${EOL}` - } - }); - }); - lab.test('?json=1', async () => { - const response = await server.inject({ - url: '/injectmap?json=1', - headers: { - referer: 'refererWithTwoRs' - } - }); - expect(response.headers['content-type']).to.contain('application/json'); - const context = response.result; - expect(context).to.equal({ - yaml: {}, - api: {}, - method: {}, - inject: { - api: { test: true }, - apivar: `1${EOL}` - } - }); - }); -}); - -lab.experiment('disable ?json=1', () => { - const server = new Hapi.Server({ - debug: { request: '*', log: 'hapi-views' } - }); - lab.before(async () => { - // start server - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - // debug: true, - allowDebugQuery: false, - dataPath: `${process.cwd()}/test/yaml`, - views: { - '/apivar/{id}': { - view: 'api', - api: { var1: 'http://jsonplaceholder.typicode.com/posts?id={params.id}' } - }, - '/inject': { - inject: { api: '/api' }, - view: 'data' - }, - '/injectmap': { - inject: { - api: '/api', - apivar: '/apivar/1' - }, - view: 'data' - }, - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - server.route({ - method: 'GET', - path: '/api', - handler(request, h) { - return { test: true }; - } - }); - await server.start(); - }); - // tests - lab.test('inject', async () => { - const response = await server.inject({ url: '/inject?json=1' }); - expect(response.headers['content-type']).to.contain('text/html'); - }); -}); From 787a4cdfd1a7cf2452b5e5f554a11ab2c23cd8a6 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 7 Dec 2017 09:39:54 -0600 Subject: [PATCH 09/13] updates --- index.js | 8 +- lib/handler.js | 95 +++-------- package.json | 5 +- test/test.cache.js | 271 ------------------------------- test/test.methods.js | 368 ------------------------------------------- test/test.pre.js | 11 +- test/test.yaml.js | 10 +- 7 files changed, 36 insertions(+), 732 deletions(-) delete mode 100644 test/test.cache.js delete mode 100644 test/test.methods.js diff --git a/index.js b/index.js index 244b9e0..147db0c 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,5 @@ 'use strict'; /* eslint new-cap: 0 */ -const async = require('async'); const hoek = require('hoek'); const aug = require('aug'); const renderHandler = require('./lib/handler.js'); @@ -14,9 +13,9 @@ const defaults = { }; const register = async (server, options) => { - options = hoek.applyToDefaults(defaults, options); - //routes - async.forEachOfSeries(options.routes, (config, path, cb) => { + options = Object.assign({}, defaults, options); + Object.keys(options.routes).forEach((path) => { + const config = options.routes[path]; config.options = options; server.route({ path, @@ -24,7 +23,6 @@ const register = async (server, options) => { handler: renderHandler(config), config: aug({}, options.routeConfig, config.routeConfig || {}) }); - cb(); }); }; diff --git a/lib/handler.js b/lib/handler.js index 4197ad8..9bb1aa4 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -1,84 +1,31 @@ 'use strict'; -const async = require('async'); +const boom = require('boom'); const str2fn = require('str2fn'); -const Boom = require('boom'); const aug = require('aug'); const pprops = require('p-props'); const varson = require('varson'); module.exports = (viewConfig) => { return async (request, h) => { - const data = varson(viewConfig.data, { request, methods: request.server.methods }); - const result = pprops(data); - return h.view(viewConfig.view, result.pprops); + // aug with globals: + const obj = aug({}, viewConfig.data, viewConfig.globals); + obj.request = request; + obj.methods = request.server.methods; + try { + const data = varson(obj);//, { request, methods: request.server.methods }); + const result = await pprops(data); + return h.view(viewConfig.view, result.pprops); + } catch (err) { + if (typeof viewConfig.options.onError === 'function') { + viewConfig.options.onError(err); + } + if (typeof viewConfig.options.onError === 'string') { + str2fn(request.server.methods, viewConfig.options.onError)(err); + } + if (err.isBoom) { + throw err; + } + throw boom.boomify(err); + } }; }; -// -// module.exports = (viewConfig) => (request, h) => { -// async.autoInject({ -// preProcess: done => { -// if (viewConfig.preProcess) { -// return str2fn(request.server.methods, viewConfig.preProcess)(request, viewConfig.options, h, done); -// } -// return done(); -// }, -// locals: (preProcess, done) => { -// if (preProcess) { -// return done(null, false); -// } -// return request.server.methods.views.fetch(request, viewConfig, done); -// }, -// globals: (preProcess, done) => { -// if (preProcess) { -// return done(null, false); -// } -// if (!viewConfig.options.globals) { -// return done(null, {}); -// } -// return request.server.methods.views.fetch(request, Object.assign({ options: viewConfig.options }, viewConfig.options.globals), done); -// } -// }, (err, data) => { -// if (err) { -// if (typeof viewConfig.options.onError === 'function') { -// return viewConfig.options.onError(err, h); -// } -// if (typeof viewConfig.onError === 'function') { -// return viewConfig.onError(err, h); -// } -// if (typeof viewConfig.options.onError === 'string') { -// return str2fn(request.server.methods, viewConfig.options.onError)(err, h); -// } -// if (typeof viewConfig.onError === 'string') { -// return str2fn(request.server.methods, viewConfig.onError)(err, h); -// } -// // boom errs can be handed back directly: -// if (err.isBoom) { -// throw err; -// } -// throw Boom.boomify(err); -// } -// // Returned early in preProcess -// if (!data.globals && !data.locals) { -// return; -// } -// -// const combinedData = aug({}, data.globals, data.locals); -// if (viewConfig.options.debug) { -// request.server.log(['hapi-views', 'debug'], { -// data: combinedData, -// path: request.url.path -// }); -// } -// if (viewConfig.options.allowDebugQuery && (request.query.json === '1' || request.query.debug === '1')) { -// return combinedData.type('application/json'); -// } -// -// if (viewConfig.preResponse) { -// return str2fn(request.server.methods, viewConfig.preResponse)(request, viewConfig.options, combinedData, h, () => { -// h.view(viewConfig.view, combinedData); -// }); -// } -// const viewName = typeof viewConfig.view === 'function' ? viewConfig.view(combinedData) : viewConfig.view; -// return h.view(viewName, combinedData); -// }); -// }; diff --git a/package.json b/package.json index 32d83d1..6d789f9 100644 --- a/package.json +++ b/package.json @@ -28,11 +28,9 @@ "aug": "^2.0.0", "boom": "^6.0.0", "hoek": "^5.0.0", - "js-yaml": "^3.10.0", "p-props": "^1.1.0", "str2fn": "2.0.0", - "varson": "^2.0.2", - "wreck": "^12.5.0" + "varson": "^2.0.2" }, "devDependencies": { "code": "^5.1.2", @@ -42,6 +40,7 @@ "eslint-plugin-import": "^2.8.0", "handlebars": "^4.0.11", "hapi": "^17.0.1", + "js-yaml": "^3.10.0", "lab": "^15.1.2", "vision": "^5.2.0" } diff --git a/test/test.cache.js b/test/test.cache.js deleted file mode 100644 index b0d3c21..0000000 --- a/test/test.cache.js +++ /dev/null @@ -1,271 +0,0 @@ -'use strict'; - -const Lab = require('lab'); -const lab = exports.lab = Lab.script(); -const Hoek = require('hoek'); -const expect = require('code').expect; -const Hapi = require('hapi'); -const Boom = require('boom'); - -let server; -lab.experiment('api', () => { - server = new Hapi.Server({ - debug: { request: '*', log: 'hapi-views' }, - port: 9991 - }); - let callCount = 0; - - lab.before( async () => { - // start server - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - //debug: true, - enableCache: true, - serveStale: true, - cache: { - expiresIn: 60000, - staleIn: 2000, - staleTimeout: 200, - generateTimeout: 100 - }, - dataPath: `${process.cwd()}/test/yaml`, - views: { - '/apitest': { - view: 'api', - api: { key1: 'http://localhost:9991/testRoute', key2: { url: 'http://localhost:9991/testRoute2' } } - }, - '/apitestNocache': { - view: 'api', - enableCache: false, - api: { key1: 'http://localhost:9991/testRouteNoCache' } - }, - '/apitestfail': { - view: 'api', - api: { key1: 'http://localhost:9991/testFailRoute' } - }, - '/injecttest': { - view: 'api', - inject: { var1: '/injectRoute' }, - }, - '/injecttestNocache': { - view: 'api', - enableCache: false, - inject: { key1: 'http://localhost:9991/testInjectNoCache' } - }, - '/apiParams/': { - view: 'api', - api: { - var1: 'http://localhost:9991/checkUrl/{info.received}' - } - }, - '/injectParams/': { - view: 'api', - inject: { - var1: '/checkUrlInject/{info.received}' - } - }, - } - } - }]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - await server.start(); - }); - lab.after(async () => { - await server.stop(); - }); - - lab.test('api', async () => { - let callCount = 0; - server.route({ - method: 'GET', - path: '/testRoute', - handler(request, h) { - callCount ++; - return { test: true }; - } - }); - server.route({ - method: 'GET', - path: '/testRoute2', - handler(request, h) { - return { test2: '1' }; - } - }); - const response = await server.inject({ - url: '/apitest' - }); - const context = response.request.response.source.context; - expect(context.api.key1).to.equal({ test: true }); - const response2 = await server.inject({ - url: '/apitest' - }); - const context2 = response.request.response.source.context; - expect(context2.api.key1).to.equal({ test: true }); - expect(context2.api.key2).to.equal({ test2: '1' }); - expect(callCount).to.equal(1); - }); - - lab.test('api with route params', async () => { - callCount = 0; - const ids = []; - server.route({ - method: 'GET', - path: '/checkUrl/{requestId}', - handler(request, h) { - callCount ++; - ids.push(request.params.requestId); - return { test: true }; - } - }); - const response = await server.inject({ url: '/apiParams/' }); - const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); await wait(1000); - const response2 = await server.inject({ - url: '/apiParams/' - }); - expect(callCount).to.equal(2); - expect(ids[0]).to.not.equal(ids[1]); - }); - - lab.test('api with cache disabled', async () => { - let callCount = 0; - server.route({ - method: 'GET', - path: '/testRouteNoCache', - handler(request, h) { - callCount ++; - return { test: true }; - } - }); - const response = await server.inject({ - url: '/apitestNocache' - }); - const context = response.request.response.source.context; - expect(context.api.key1).to.equal({ test: true }); - const response2 = await server.inject({ - url: '/apitestNocache' - }); - const context2 = response.request.response.source.context; - expect(context2.api.key1).to.equal({ test: true }); - expect(callCount).to.equal(2); - }); - - lab.test('nocache=1 will bypass caching', async() => { - const respnose = await server.inject({ - url: '/apitest?nocache=1' - }); - const context = response.request.response.source.context; - expect(context.api.key1).to.equal({ test: true }); - const response2 = await server.inject({ - url: '/apitest?nocache=1' - }); - const context2 = response.request.response.source.context; - expect(context2.api.key1).to.equal({ test: true }); - expect(context2.api.key2).to.equal({ test2: '1' }); - expect(callCount).to.equal(2); - }); - - lab.test('api test with api fail', { timeout: 3500 }, async () => { - let firstRun = true; - server.route({ - method: 'GET', - path: '/testFailRoute', - handler(req, reply) { - if (!firstRun) { - throw Boom.badImplementation('Random Error Message'); - } - - firstRun = false; - return { one: 'une', two: 'deu' }; - } - }); - const resp = await server.inject({ - method: 'GET', - url: '/apitestfail' - }); - const context = resp.request.response.source.context; - expect(context.api.key1).to.equal({ one: 'une', two: 'deu' }); - const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); await wait(3000); - const resp2 = await server.inject({ - method: 'GET', - url: '/apitestfail' - }); - const contextDeu = resp2.request.response.source.context; - expect(contextDeu.api.key1).to.equal({ one: 'une', two: 'deu' }); - }); - - lab.test('inject', async () => { - callCount = 0; - server.route({ - method: 'GET', - path: '/injectRoute', - handler(request, h) { - callCount ++; - return { test: true }; - } - }); - const response = await server.inject({ - method: 'GET', - url: '/injecttest' - }); - const context = response.request.response.source.context; - expect(context.inject.var1).to.equal({ test: true }); - const response2 = await server.inject({ - url: '/injecttest' - }); - const context2 = response.request.response.source.context; - expect(context2.inject.var1).to.equal({ test: true }); - expect(callCount).to.equal(1); - }); - - lab.test('inject with cache disabled', async () => { - callCount = 0; - server.route({ - method: 'GET', - path: '/testInjectNoCache', - handler(request, h) { - callCount ++; - return { test: true }; - } - }); - const response = await server.inject({ - url: '/injecttestNocache' - }); - const context = response.request.response.source.context; - expect(context.inject.key1).to.equal({ test: true }); - const response2 = await server.inject({ - url: '/injecttestNocache' - }); - const context2 = response.request.response.source.context; - expect(context2.inject.key1).to.equal({ test: true }); - expect(callCount).to.equal(2); - }); - - lab.test('inject with route params', async () => { - callCount = 0; - const ids = []; - server.route({ - method: 'GET', - path: '/checkUrlInject/{requestId}', - handler(request, h) { - callCount ++; - ids.push(request.params.requestId); - return { test: true }; - } - }); - const response = await server.inject({ - url: '/injectParams/' - }); - const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); await wait(1000); - const response2 = await server.inject({ - url: '/injectParams/' - }); - expect(callCount).to.equal(2); - expect(ids[0]).to.not.equal(ids[1]); - }); -}); diff --git a/test/test.methods.js b/test/test.methods.js deleted file mode 100644 index 51890b6..0000000 --- a/test/test.methods.js +++ /dev/null @@ -1,368 +0,0 @@ -/* eslint prefer-arrow-callback: 0 */ -'use strict'; - -const Lab = require('lab'); -const lab = exports.lab = Lab.script(); -const Hoek = require('hoek'); -const expect = require('code').expect; -const Hapi = require('hapi'); - -lab.experiment('methods', () => { - const server = new Hapi.Server({ - debug: { request: '*', log: 'hapi-views' } - }); - lab.before(async () => { - // start server - await server.register([ - require('vision'), - { - register: require('../'), - options: { - //debug: true, - dataPath: `${process.cwd()}/test/yaml`, - views: { - '/apitest': { - view: 'api', - api: { var1: 'http://jsonplaceholder.typicode.com/posts?id=1' } - }, - '/methodtest': { - view: 'method', - method: { var1: 'testerino' } - }, - '/methodmulti': { - view: 'method', - method: { - var1: 'testerino', - var2: 'testmethod2', - var3: 'myScope.myMethod' - } - }, - '/data': { - view: 'data', - yaml: { yaml1: 'test1.yaml' }, - data: { - name: 'Jack', - url: '{request.url.path}', - test: { - ok: '{yaml.yaml1.test1}' - } - } - }, - '/data-string': { - view: 'data', - yaml: { yaml1: 'test1.yaml' }, - data: 'yaml' - }, - '/data-method': { - view: 'data', - yaml: { yaml1: 'test1.yaml' }, - dataMethod: 'handle.data' - } - } - } - } - ]); - - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - - server.route({ - method: 'GET', - path: '/api', - handler(request, reply) { - return { test: true }; - } - }); - - server.method('testerino', function() { - return 'test'; - }); - - server.method('testmethod2', function() { - return 'test2'; - }); - - server.method('myScope.myMethod', function() { - return 'test3'; - }); - - await server.start(); - }); - - // tests - lab.test('api', async () => { - const response = await server.inject({ url: '/apitest' }); - const context = response.request.response.source.context; - expect(context).to.equal({ yaml: {}, - method: {}, - inject: {}, - api: { var1: [{ userId: 1, - id: 1, - title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', - body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto' } - ] } - }); - }); - - lab.test('method', async () => { - const response = await server.inject({ url: '/methodtest' }); - const context = response.request.response.source.context; - expect(context).to.equal({ yaml: {}, api: {}, method: { var1: 'test' }, inject: {} }); - }); - - lab.test('data', async () => { - const response = await server.inject({ url: '/data' }); - const context = response.request.response.source.context; - expect(context).to.equal({ name: 'Jack', url: '/data', test: { ok: 'true' } }); - }); - - lab.test('methods', async () => { - const response = await server.inject({ url: '/methodmulti' }); - const context = response.request.response.source.context; - expect(context).to.equal({ - yaml: {}, - api: {}, - method: { - var1: 'test', - var2: 'test2', - var3: 'test3' - }, - inject: {} - }); - }); - lab.test('data', async () => { - const response = await server.inject({ url: '/data' }); - const context = response.request.response.source.context; - expect(context).to.equal({ name: 'Jack', url: '/data', test: { ok: 'true' } }); - }); - - lab.test('data as string', async () => { - const response = await server.inject({ url: '/data-string' }); - const context = response.request.response.source.context; - expect(context).to.equal({ - yaml1: { - test1: 'true' - } - }); - }); - - lab.test('dataMethod call that server method for processing data', async () => { - server.method('handle.data', function(results) { - return results.yaml; - }); - const response = await server.inject({ url: '/data-method' }); - const context = response.request.response.source.context; - expect(context).to.equal({ - yaml1: { - test1: 'true' - } - }); - }); -}); - -lab.experiment('methods with args', () => { - let server; - - lab.before(async () => { - server = new Hapi.Server({ - debug: { log: ['hapi-views', 'error'], request: ['error'] } - }); - - await server.register([ - require('vision'), - { - register: require('../'), - options: { - //debug: true, - data: `${process.cwd()}/test/yaml`, - views: { - '/methodWithArgs/{name}': { - view: 'method', - method: { - method1: { - name: 'myScope.myMethod', - args: [true, '{request.params.name}', '{request.query.score}'] - } - } - // three args, one static and two derived from the request: - }, - '/multiMethods/{name}/{harbinger}': { - view: 'methodWithArgs', - method: { - method1: { - name: 'someMethod', - args: ['{request.params.name}'] - }, - method2: { - name: 'someOtherMethod', - args: ['{request.params.harbinger}', '{request.query.score}'] - } - } - }, - '/multiMethodsObj/{name}/{harbinger}': { - view: 'method', - method: { - someMethod: { - name: 'someMethod', - args: ['{request.params.name}'] - }, - someOtherMethod: { - name: 'someOtherMethod', - args: ['{request.params.harbinger}', '{request.query.score}'] - } - } - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - - server.method('myScope.myMethod', function(arg1, arg2, arg3) { - return arg1 + arg2 + arg3; - }); - server.method('someMethod', function(name) { - return name; - }); - server.method('someOtherMethod', function(harbinger, score) { - return `${harbinger}+${score}`; - }); - - await server.start(); - - }); - - lab.test('can pass args to a method', async() => { - const response = await server.inject({ - url: '/methodWithArgs/Jack?score=56', - method: 'get' - }); - expect(response.result).to.include('trueJack56'); - }); - - lab.test('can pass args to multiple methods', async() => { - const response = await server.inject({ - url: '/multiMethods/Jack/albatross?score=70', - method: 'get' - }); - expect(response.result).to.include('Jack'); - expect(response.result).to.include('albatross+70'); - }); - lab.test('can pass args to multiple methods (obj)', async(done) => { - const response = await server.inject({ - url: '/multiMethodsObj/Jack/albatross?score=70', - method: 'get' - }); - expect(response.statusCode).to.equal(200); - const context = response.request.response.source.context; - expect(context).to.equal({ - api: {}, - method: { - someMethod: 'Jack', - someOtherMethod: 'albatross+70' - }, - inject: {}, - yaml: { } - }); - }); -}); - -lab.experiment('method with view function', () => { - const server = new Hapi.Server({ - debug: { request: '*', log: 'hapi-views' } - }); - lab.before(async () => { - // start server - await server.register([ - require('vision'), - { - register: require('../'), - options: { - //debug: true, - dataPath: `${process.cwd()}/test/yaml`, - views: { - '/apitest': { - view: 'api', - api: { var1: 'http://jsonplaceholder.typicode.com/posts?id=1' } - }, - '/methodtest': { - view: 'method', - method: { var1: 'testerino' } - }, - '/methodfunction': { - view: (data) => data.method.method1, - method: { method1: 'testerino' } - }, - '/methodmulti': { - view: 'method', - method: { - var1: 'testerino', - var2: 'testmethod2', - var3: 'myScope.myMethod' - } - }, - '/data': { - view: 'data', - yaml: { yaml1: 'test1.yaml' }, - data: { - name: 'Jack', - url: '{request.url.path}', - test: { - ok: '{yaml.yaml1.test1}' - } - } - }, - '/data-string': { - view: 'data', - yaml: { yaml1: 'test1.yaml' }, - data: 'yaml' - }, - '/data-method': { - view: 'data', - yaml: { yaml1: 'test1.yaml' }, - dataMethod: 'handle.data' - } - } - } - } - ]); - - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - - server.route({ - method: 'GET', - path: '/api', - handler(request, h) { - return { test: true }; - } - }); - - server.method('testerino', function() { - // this needs to return the name of the view: - return 'method'; - }); - - server.method('testmethod2', function() { - return 'test2'; - }); - - server.method('myScope.myMethod', function() { - return 'test3'; - }); - - await server.start(); - }); - - lab.test('method', async () => { - const response = await server.inject({ url: '/methodfunction' }); - expect(response.result).to.include('method'); - }); -}); diff --git a/test/test.pre.js b/test/test.pre.js index d06831d..5eac6aa 100644 --- a/test/test.pre.js +++ b/test/test.pre.js @@ -25,13 +25,10 @@ lab.experiment('pre', () => { { plugin: require('../'), options: { - views: { + routes: { '/process': { view: 'api', - preProcess: 'process', - method: { - dummy: 'dummy' - } + preProcess: 'process' } } } @@ -62,7 +59,7 @@ lab.experiment('pre', () => { { plugin: require('../'), options: { - views: { + routes: { '/process': { view: 'api', preProcess: 'process', @@ -100,7 +97,7 @@ lab.experiment('pre', () => { { plugin: require('../'), options: { - views: { + routes: { '/response': { view: 'api', preResponse: 'response', diff --git a/test/test.yaml.js b/test/test.yaml.js index b980279..31254dd 100644 --- a/test/test.yaml.js +++ b/test/test.yaml.js @@ -21,9 +21,9 @@ lab.experiment('yaml', async() => { //debug: true, dataPath: `${process.cwd()}/test/yaml`, routes: { - '/yaml': { - view: 'yaml', - data: { + '/yaml': { + view: 'yaml', + data: { yaml1: "{{methods.yaml(`${process.cwd()}/test/yaml/test1.yaml`)}}", } } @@ -35,7 +35,9 @@ lab.experiment('yaml', async() => { engines: { html: require('handlebars') }, path: `${__dirname}/views` }); - + server.method('yaml', (request, yamlFile) => { + return { yaml1: { test1: true } }; + }); await server.start(); }); // tests From bf2a7f951a8393f3be2a45127c8c727ecf21af8f Mon Sep 17 00:00:00 2001 From: orthagonal Date: Thu, 7 Dec 2017 11:19:01 -0600 Subject: [PATCH 10/13] consolidate tests in one file --- lib/handler.js | 6 +- test/test.globals.js | 457 +++++++++++++++++++++++++++++++++++++++++++ test/test.yaml.js | 41 ---- 3 files changed, 459 insertions(+), 45 deletions(-) diff --git a/lib/handler.js b/lib/handler.js index 9bb1aa4..31b4e12 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -9,12 +9,10 @@ module.exports = (viewConfig) => { return async (request, h) => { // aug with globals: const obj = aug({}, viewConfig.data, viewConfig.globals); - obj.request = request; - obj.methods = request.server.methods; try { - const data = varson(obj);//, { request, methods: request.server.methods }); + const data = varson(obj, { request, methods: request.server.methods }); const result = await pprops(data); - return h.view(viewConfig.view, result.pprops); + return h.view(viewConfig.view, result); } catch (err) { if (typeof viewConfig.options.onError === 'function') { viewConfig.options.onError(err); diff --git a/test/test.globals.js b/test/test.globals.js index bbf73fc..4892c2e 100644 --- a/test/test.globals.js +++ b/test/test.globals.js @@ -6,6 +6,44 @@ const Hoek = require('hoek'); const expect = require('code').expect; const Hapi = require('hapi'); +lab.test('server methods', async() => { + const server = new Hapi.Server({ + debug: { request: '*', log: 'hapi-views' } + }); + server.method('yaml', (request, yamlFile) => { + return new Promise((resolve) => { + return resolve({ test1: true }); + }); + }); + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + //debug: true, + dataPath: `${process.cwd()}/test/yaml`, + routes: { + '/yaml': { + view: 'yaml', + data: { + yaml1: "{{methods.yaml(`${process.cwd()}/test/yaml/test1.yaml`)}}", + } + } + } + } + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + await server.start(); + // tests + const response = await server.inject({ url: '/yaml' }); + const context = response.request.response.source.context; + expect(context).to.equal({ yaml1: { test1: true } }); +}); +/* lab.experiment('globals', () => { const server = new Hapi.Server({ debug: { request: '*', log: 'hapi-views' } @@ -77,3 +115,422 @@ lab.experiment('globals', () => { }); }); }); + +lab.experiment('onError', () => { + lab.test('top-level onError', async() => { + const server = new Hapi.Server({ + debug: { log: 'hapi-views' }, + port: 9991 + }); + server.method('makeError', () => { throw new Error('this is an error'); }); + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + onError: (err, h) => { + expect(err).to.not.equal(null); + return 'the error was handled'; + }, + debug: true, + views: { + '/throwError': { + view: 'api', + method: { + error: 'makeError' + } + } + } + } + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + await server.start(); + const response = await server.inject({ url: '/throwError' }); + expect(response.statusCode).to.equal(200); + expect(response.result).to.equal('the error was handled'); + }); + + lab.test('top-level onError as server method', async() => { + const server = new Hapi.Server({ + debug: { log: 'hapi-views' }, + port: 9991 + }); + server.method('makeError', (next) => next(new Error('this is an error'))); + server.method('fetchError', (err, h) => { + expect(err).to.not.equal(null); + return 'the error was handled'; + }); + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + onError: 'fetchError', + debug: true, + views: { + '/throwError': { + view: 'api', + method: { + makeError: 'makeError' + } + } + } + } + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + await server.start(); + const response = await server.inject({ url: '/throwError' }); + expect(response.statusCode).to.equal(200); + expect(response.result).to.equal('the error was handled'); + }); + lab.test('per-route onError', async() => { + const server = new Hapi.Server({ + debug: { log: 'hapi-views' }, + port: 9991 + }); + server.method('makeError', () => { throw new Error('this is an error'); }); + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + // debug: true, + views: { + '/throwError': { + view: 'api', + method: { + error: 'makeError', + }, + onError: (err, reply) => { + expect(err).to.not.equal(null); + return reply('the error was handled'); + } + } + } + } + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + await server.start(); + const response = await server.inject({ url: '/throwError' }); + expect(response.statusCode).to.equal(200); + expect(response.result).to.equal('the error was handled'); + }); + lab.test('per-route onError as server method', async() => { + const server = new Hapi.Server({ + debug: { log: 'hapi-views' }, + port: 9991 + }); + server.method('makeError', () => { throw new Error('this is an error') }); + server.method('fetchError', (err, h) => { + expect(err).to.not.equal(null); + return 'the error was handled'; + }); + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + debug: true, + views: { + '/throwError': { + view: 'api', + method: { + error: 'makeError', + }, + onError: 'fetchError' + } + } + } + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + await server.start(); + const response = await server.inject({ url: '/throwError' }); + expect(response.statusCode).to.equal(200); + expect(response.result).to.equal('the error was handled'); + }); + +}); + +lab.experiment('errors', () => { + const server = new Hapi.Server({ + debug: { log: 'hapi-views' }, + port: 9991 + }); + + lab.before( async () => { + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + debug: true, + views: { + '/500': { + view: 'api', + api: { var1: 'http://localhost:9991/api/500' } + }, + '/404': { + view: 'api', + api: { var1: 'http://localhost:9991/api/404' } + }, + '/401': { + view: 'api', + api: { var1: 'http://localhost:9991/api/401' } + } + } + } + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + server.route({ + method: 'GET', + path: '/api/500', + handler(request, h) { + throw new Error('testing'); + } + }); + server.route({ + method: 'GET', + path: '/api/404', + handler(request, h) { + return h.response({ status: 'not found' }).code(404); + } + }); + server.route({ + method: 'GET', + path: '/api/401', + handler(request, h) { + throw Boom.unauthorized('nope bud'); + } + }); + await server.start(); + }); + + lab.test('500 errors bubble back up', async() => { + const response = await server.inject({ url: '/500' }); + expect(response.statusCode).to.equal(500); + }); + + lab.test('404 errors bubble back up', async() => { + const response = await server.inject({ url: '/404' }); + expect(response.statusCode).to.equal(404); + }); + + lab.test('boom unauthorized errors bubble back up', async() => { + const response = await server.inject({ url: '/401' }); + expect(response.statusCode).to.equal(401); + }); +}); + +lab.experiment('pre', () => { + lab.test('preProcess', async() => { + let processRan = false; + + const server = new Hapi.Server({ + debug: { log: 'hapi-views' }, + port: 9991 + }); + server.method('process', (request, options, reply) => { + processRan = true; + }); + + server.method('dummy', () => '1'); + + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + routes: { + '/process': { + view: 'api', + preProcess: 'process' + } + } + } + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + await server.start(); + const response = await server.inject({ url: '/process' }); + expect(response.statusCode).to.equal(200); + expect(processRan).to.equal(true); + }); + lab.test('preProcess early reply', async() => { + const server = new Hapi.Server({ + debug: { log: 'hapi-views' }, + port: 9991 + }); + server.method('process', (request, options, reply) => { + return { test: 2 }; + }); + + server.method('dummy', () => '1'); + + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + routes: { + '/process': { + view: 'api', + preProcess: 'process', + method: { + dummy: 'dummy' + } + } + } + } + }], (error) => { + Hoek.assert(!error, error); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + }); + await server.start(); + const response = await server.inject({ url: '/process' }); + expect(response.statusCode).to.equal(200); + expect(response.result.test).to.equal(2); + }); + lab.test('preResponse', async() => { + const server = new Hapi.Server({ + debug: { log: 'hapi-views' }, + port: 9991 + }); + server.method('response', (request, options, data) => { + return { test: 1 }; + }); + + server.method('dummy', () => '1'); + + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + routes: { + '/response': { + view: 'api', + preResponse: 'response', + method: { + dummy: 'dummy' + } + } + } + } + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + await server.start(); + const response = await server.inject({ url: '/response' }); + expect(response.statusCode).to.equal(200); + expect(response.result.test).to.equal(1); + }); +}); + +lab.experiment('global routeConfig', async() => { + lab.beforeEach(async() => { + server = new Hapi.Server(); + await server.register(require('vision')); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + }); + lab.afterEach(async() => { + await server.stop(); + }); + + lab.test('global route config merges with local route config', async() => { + await server.register({ + plugin: require('../'), + options: { + routeConfig: { + cache: { + privacy: 'public', + expiresIn: 1000 + } + }, + views: { + '/': { + view: 'blank' + } + } + } + }); + const res = await server.inject('/'); + expect(res.statusCode).to.equal(200); + expect(res.headers['cache-control']).to.equal('max-age=1, must-revalidate, public'); + }); + + lab.test('not setting global route Config', async() => { + await server.register({ + plugin: require('../'), + options: { + views: { + '/': { + view: 'blank' + } + } + } + }); + const res = await server.inject('/'); + expect(res.statusCode).to.equal(200); + expect(res.headers['cache-control']).to.equal('no-cache'); + }); + + lab.test('not setting global route Config', async() => { + await server.register({ + plugin: require('../'), + options: { + routeConfig: { + cache: { + privacy: 'public', + expiresIn: 1000 + } + }, + views: { + '/': { + view: 'blank', + routeConfig: { + cache: { + expiresIn: 2000 + } + } + } + } + } + }); + const res = await server.inject('/'); + expect(res.statusCode).to.equal(200); + expect(res.headers['cache-control']).to.equal('max-age=2, must-revalidate, public'); + }); +}); +*/ diff --git a/test/test.yaml.js b/test/test.yaml.js index 31254dd..6fc6549 100644 --- a/test/test.yaml.js +++ b/test/test.yaml.js @@ -6,44 +6,3 @@ const lab = exports.lab = Lab.script(); const Hoek = require('hoek'); const expect = require('code').expect; const Hapi = require('hapi'); - -lab.experiment('yaml', async() => { - const server = new Hapi.Server({ - debug: { request: '*', log: 'hapi-views' } - }); - lab.before( async() => { - // start server - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - //debug: true, - dataPath: `${process.cwd()}/test/yaml`, - routes: { - '/yaml': { - view: 'yaml', - data: { - yaml1: "{{methods.yaml(`${process.cwd()}/test/yaml/test1.yaml`)}}", - } - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - server.method('yaml', (request, yamlFile) => { - return { yaml1: { test1: true } }; - }); - await server.start(); - }); - // tests - lab.test('yaml', async () => { - const response = await server.inject({ url: '/yaml' }); - const context = response.request.response.source.context; - expect(context).to.equal({ yaml1: { test1: true } }); - }); -}); From 29763b3a6749d34af4a7234fca99dba4d9e08184 Mon Sep 17 00:00:00 2001 From: orthagonal Date: Thu, 7 Dec 2017 12:19:27 -0600 Subject: [PATCH 11/13] consolidate tests --- lib/handler.js | 13 +- test/test.errors.js | 83 ----- test/test.globals.js | 559 +++++++-------------------------- test/test.onError.js | 158 ---------- test/test.pre.js | 121 ------- test/test.routeConfig.js | 87 ----- test/test.yaml.js | 8 - test/views/api.html | 1 - test/views/blank.html | 1 - test/views/data.html | 3 - test/views/method.html | 1 - test/views/methodWithArgs.html | 1 - test/yaml/test2.yaml | 1 - 13 files changed, 118 insertions(+), 919 deletions(-) delete mode 100644 test/test.errors.js delete mode 100644 test/test.onError.js delete mode 100644 test/test.pre.js delete mode 100644 test/test.routeConfig.js delete mode 100644 test/test.yaml.js delete mode 100644 test/views/api.html delete mode 100644 test/views/blank.html delete mode 100644 test/views/data.html delete mode 100644 test/views/method.html delete mode 100644 test/views/methodWithArgs.html delete mode 100644 test/yaml/test2.yaml diff --git a/lib/handler.js b/lib/handler.js index 31b4e12..d523263 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -7,18 +7,21 @@ const varson = require('varson'); module.exports = (viewConfig) => { return async (request, h) => { + if (viewConfig.preProcess) { + viewConfig.preProcess(request, viewConfig.options, h); + } // aug with globals: - const obj = aug({}, viewConfig.data, viewConfig.globals); + const obj = aug({}, viewConfig.data, viewConfig.options.globals); try { const data = varson(obj, { request, methods: request.server.methods }); const result = await pprops(data); return h.view(viewConfig.view, result); } catch (err) { - if (typeof viewConfig.options.onError === 'function') { - viewConfig.options.onError(err); + if (typeof viewConfig.onError === 'function') { + return viewConfig.onError(err); } - if (typeof viewConfig.options.onError === 'string') { - str2fn(request.server.methods, viewConfig.options.onError)(err); + if (typeof viewConfig.options.onError === 'function') { + return viewConfig.options.onError(err); } if (err.isBoom) { throw err; diff --git a/test/test.errors.js b/test/test.errors.js deleted file mode 100644 index ced9297..0000000 --- a/test/test.errors.js +++ /dev/null @@ -1,83 +0,0 @@ -/* eslint strict: 0, max-len: 0, prefer-arrow-callback: 0 */ -'use strict'; - -const Lab = require('lab'); -const lab = exports.lab = Lab.script(); -const Hoek = require('hoek'); -const expect = require('code').expect; -const Hapi = require('hapi'); -const Boom = require('boom'); - -lab.experiment('errors', () => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - - lab.before( async () => { - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - debug: true, - views: { - '/500': { - view: 'api', - api: { var1: 'http://localhost:9991/api/500' } - }, - '/404': { - view: 'api', - api: { var1: 'http://localhost:9991/api/404' } - }, - '/401': { - view: 'api', - api: { var1: 'http://localhost:9991/api/401' } - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - server.route({ - method: 'GET', - path: '/api/500', - handler(request, h) { - throw new Error('testing'); - } - }); - server.route({ - method: 'GET', - path: '/api/404', - handler(request, h) { - return h.response({ status: 'not found' }).code(404); - } - }); - server.route({ - method: 'GET', - path: '/api/401', - handler(request, h) { - throw Boom.unauthorized('nope bud'); - } - }); - await server.start(); - }); - - lab.test('500 errors bubble back up', async() => { - const response = await server.inject({ url: '/500' }); - expect(response.statusCode).to.equal(500); - }); - - lab.test('404 errors bubble back up', async() => { - const response = await server.inject({ url: '/404' }); - expect(response.statusCode).to.equal(404); - }); - - lab.test('boom unauthorized errors bubble back up', async() => { - const response = await server.inject({ url: '/401' }); - expect(response.statusCode).to.equal(401); - }); -}); diff --git a/test/test.globals.js b/test/test.globals.js index 4892c2e..31c6e69 100644 --- a/test/test.globals.js +++ b/test/test.globals.js @@ -43,494 +43,155 @@ lab.test('server methods', async() => { const context = response.request.response.source.context; expect(context).to.equal({ yaml1: { test1: true } }); }); -/* -lab.experiment('globals', () => { + +lab.test('globals', async() => { const server = new Hapi.Server({ debug: { request: '*', log: 'hapi-views' } }); - lab.before( async() => { - // start server - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - dataPath: `${process.cwd()}/test/yaml`, - views: { - '/apitest': { - view: 'api', - }, - '/apivar/{id}': { - view: 'api', - method: { method2: 'testerino' }, - api: { var1: 'http://jsonplaceholder.typicode.com/posts?id=23' }, - yaml: { yaml1: 'test2.yaml' } - }, - }, - globals: { - yaml: { yaml1: 'test1.yaml' }, - method: { method1: 'testmethod2' }, - api: { var1: 'http://jsonplaceholder.typicode.com/posts?id=1' } - } - } - } - ]); - server.method('testmethod2', function() { - return 'test2'; - }); - server.method('testerino', function() { - return 'test'; - }); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - server.route({ - method: 'GET', - path: '/api', - handler(request, h) { - return { yaml1: { test: true } }; - } - }); - }); - lab.test('global api', async () => { - const response = await server.inject({ url: '/apivar/1' }); - const context = response.request.response.source.context; - // combines if they are arrays: - expect(context.method).to.equal({ - method1: 'test2', method2: 'test' - }); - expect(context.api).to.equal({ var1: [ - { userId: 3, - id: 23, - title: 'maxime id vitae nihil numquam', - body: 'veritatis unde neque eligendi\nquae quod architecto quo neque vitae\nest illo sit tempora doloremque fugit quod\net et vel beatae sequi ullam sed tenetur perspiciatis' - } - ] }); - expect(context.yaml).to.equal({ - yaml1: { - global: 'much global', - test1: 'true' - } - }); - }); -}); - -lab.experiment('onError', () => { - lab.test('top-level onError', async() => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('makeError', () => { throw new Error('this is an error'); }); - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - onError: (err, h) => { - expect(err).to.not.equal(null); - return 'the error was handled'; - }, - debug: true, - views: { - '/throwError': { - view: 'api', - method: { - error: 'makeError' - } - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - await server.start(); - const response = await server.inject({ url: '/throwError' }); - expect(response.statusCode).to.equal(200); - expect(response.result).to.equal('the error was handled'); - }); - - lab.test('top-level onError as server method', async() => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('makeError', (next) => next(new Error('this is an error'))); - server.method('fetchError', (err, h) => { - expect(err).to.not.equal(null); - return 'the error was handled'; - }); - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - onError: 'fetchError', - debug: true, - views: { - '/throwError': { - view: 'api', - method: { - makeError: 'makeError' - } - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - await server.start(); - const response = await server.inject({ url: '/throwError' }); - expect(response.statusCode).to.equal(200); - expect(response.result).to.equal('the error was handled'); - }); - lab.test('per-route onError', async() => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('makeError', () => { throw new Error('this is an error'); }); - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - // debug: true, - views: { - '/throwError': { - view: 'api', - method: { - error: 'makeError', - }, - onError: (err, reply) => { - expect(err).to.not.equal(null); - return reply('the error was handled'); - } - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` + server.method('yaml', (request, yamlFile) => { + return new Promise((resolve) => { + return resolve({ test1: true }); }); - await server.start(); - const response = await server.inject({ url: '/throwError' }); - expect(response.statusCode).to.equal(200); - expect(response.result).to.equal('the error was handled'); }); - lab.test('per-route onError as server method', async() => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('makeError', () => { throw new Error('this is an error') }); - server.method('fetchError', (err, h) => { - expect(err).to.not.equal(null); - return 'the error was handled'; - }); - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - debug: true, - views: { - '/throwError': { - view: 'api', - method: { - error: 'makeError', - }, - onError: 'fetchError' + // start server + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + dataPath: `${process.cwd()}/test/yaml`, + routes: { + '/yaml': { + view: 'yaml', + data: { + yaml1: "{{methods.yaml(`${process.cwd()}/test/yaml/test1.yaml`)}}", } } + }, + globals: { + yaml2: { property: 1235 } } } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - await server.start(); - const response = await server.inject({ url: '/throwError' }); - expect(response.statusCode).to.equal(200); - expect(response.result).to.equal('the error was handled'); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); - + const response = await server.inject({ url: '/yaml' }); + const context = response.request.response.source.context; + expect(context.yaml2).to.equal({ property: 1235 }); }); -lab.experiment('errors', () => { +lab.test('onError', async() => { const server = new Hapi.Server({ debug: { log: 'hapi-views' }, port: 9991 }); - - lab.before( async () => { - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - debug: true, - views: { - '/500': { - view: 'api', - api: { var1: 'http://localhost:9991/api/500' } - }, - '/404': { - view: 'api', - api: { var1: 'http://localhost:9991/api/404' } - }, - '/401': { - view: 'api', - api: { var1: 'http://localhost:9991/api/401' } + server.method('makeError', () => { throw new Error('this is an error'); }); + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + onError: (err, h) => { + expect(err).to.not.equal(null); + return 'the error was handled'; + }, + debug: true, + routes: { + '/yaml': { + view: 'yaml', + data: { + yaml1: "{{methods.makeError()}}", } } } } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - server.route({ - method: 'GET', - path: '/api/500', - handler(request, h) { - throw new Error('testing'); - } - }); - server.route({ - method: 'GET', - path: '/api/404', - handler(request, h) { - return h.response({ status: 'not found' }).code(404); - } - }); - server.route({ - method: 'GET', - path: '/api/401', - handler(request, h) { - throw Boom.unauthorized('nope bud'); - } - }); - await server.start(); - }); - - lab.test('500 errors bubble back up', async() => { - const response = await server.inject({ url: '/500' }); - expect(response.statusCode).to.equal(500); - }); - - lab.test('404 errors bubble back up', async() => { - const response = await server.inject({ url: '/404' }); - expect(response.statusCode).to.equal(404); - }); - - lab.test('boom unauthorized errors bubble back up', async() => { - const response = await server.inject({ url: '/401' }); - expect(response.statusCode).to.equal(401); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); + await server.start(); + const response = await server.inject({ url: '/yaml' }); + expect(response.statusCode).to.equal(200); + expect(response.result).to.equal('the error was handled'); }); -lab.experiment('pre', () => { - lab.test('preProcess', async() => { - let processRan = false; - - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('process', (request, options, reply) => { - processRan = true; - }); - - server.method('dummy', () => '1'); - - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - routes: { - '/process': { - view: 'api', - preProcess: 'process' - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - await server.start(); - const response = await server.inject({ url: '/process' }); - expect(response.statusCode).to.equal(200); - expect(processRan).to.equal(true); - }); - lab.test('preProcess early reply', async() => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('process', (request, options, reply) => { - return { test: 2 }; - }); - - server.method('dummy', () => '1'); - - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - routes: { - '/process': { - view: 'api', - preProcess: 'process', - method: { - dummy: 'dummy' - } - } - } - } - }], (error) => { - Hoek.assert(!error, error); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - }); - await server.start(); - const response = await server.inject({ url: '/process' }); - expect(response.statusCode).to.equal(200); - expect(response.result.test).to.equal(2); +lab.test('per-route onError', async() => { + const server = new Hapi.Server({ + debug: { log: 'hapi-views' }, + port: 9991 }); - lab.test('preResponse', async() => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('response', (request, options, data) => { - return { test: 1 }; - }); - - server.method('dummy', () => '1'); - - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - routes: { - '/response': { - view: 'api', - preResponse: 'response', - method: { - dummy: 'dummy' - } + server.method('makeError', () => { throw new Error('this is an error'); }); + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + // debug: true, + routes: { + '/yaml': { + view: 'yaml', + data: { + yaml1: "{{methods.yaml(`${process.cwd()}/test/yaml/test1.yaml`)}}", + }, + onError: (err, h) => { + expect(err).to.not.equal(null); + return 'the error was handled'; } } } } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - await server.start(); - const response = await server.inject({ url: '/response' }); - expect(response.statusCode).to.equal(200); - expect(response.result.test).to.equal(1); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); + await server.start(); + const response = await server.inject({ url: '/yaml' }); + expect(response.statusCode).to.equal(200); + expect(response.result).to.equal('the error was handled'); }); -lab.experiment('global routeConfig', async() => { - lab.beforeEach(async() => { - server = new Hapi.Server(); - await server.register(require('vision')); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - }); - lab.afterEach(async() => { - await server.stop(); - }); - - lab.test('global route config merges with local route config', async() => { - await server.register({ - plugin: require('../'), - options: { - routeConfig: { - cache: { - privacy: 'public', - expiresIn: 1000 - } - }, - views: { - '/': { - view: 'blank' - } - } - } - }); - const res = await server.inject('/'); - expect(res.statusCode).to.equal(200); - expect(res.headers['cache-control']).to.equal('max-age=1, must-revalidate, public'); +lab.test('pre', async() => { + let processRan = false; + const server = new Hapi.Server({ + debug: { log: 'hapi-views' }, + port: 9991 }); - - lab.test('not setting global route Config', async() => { - await server.register({ - plugin: require('../'), - options: { - views: { - '/': { - view: 'blank' - } - } - } + server.method('yaml', (request, yamlFile) => { + return new Promise((resolve) => { + return resolve({ test1: true }); }); - const res = await server.inject('/'); - expect(res.statusCode).to.equal(200); - expect(res.headers['cache-control']).to.equal('no-cache'); }); - lab.test('not setting global route Config', async() => { - await server.register({ + await server.register([ + require('vision'), + { plugin: require('../'), options: { - routeConfig: { - cache: { - privacy: 'public', - expiresIn: 1000 - } - }, - views: { - '/': { - view: 'blank', - routeConfig: { - cache: { - expiresIn: 2000 - } - } + routes: { + '/yaml': { + view: 'yaml', + data: { + yaml1: "{{methods.yaml(`${process.cwd()}/test/yaml/test1.yaml`)}}", + }, + preProcess: (request, options, h) => { processRan = true; } } } } - }); - const res = await server.inject('/'); - expect(res.statusCode).to.equal(200); - expect(res.headers['cache-control']).to.equal('max-age=2, must-revalidate, public'); + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` }); + await server.start(); + const response = await server.inject({ url: '/yaml' }); + expect(response.statusCode).to.equal(200); + expect(processRan).to.equal(true); }); -*/ diff --git a/test/test.onError.js b/test/test.onError.js deleted file mode 100644 index 38151ae..0000000 --- a/test/test.onError.js +++ /dev/null @@ -1,158 +0,0 @@ -'use strict'; - -const Lab = require('lab'); -const lab = exports.lab = Lab.script(); -const Hoek = require('hoek'); -const expect = require('code').expect; -const Hapi = require('hapi'); - -lab.experiment('onError', () => { - lab.test('top-level onError', async() => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('makeError', () => { throw new Error('this is an error'); }); - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - onError: (err, h) => { - expect(err).to.not.equal(null); - return 'the error was handled'; - }, - debug: true, - views: { - '/throwError': { - view: 'api', - method: { - error: 'makeError' - } - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - await server.start(); - const response = await server.inject({ url: '/throwError' }); - expect(response.statusCode).to.equal(200); - expect(response.result).to.equal('the error was handled'); - }); - - lab.test('top-level onError as server method', async() => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('makeError', (next) => next(new Error('this is an error'))); - server.method('fetchError', (err, h) => { - expect(err).to.not.equal(null); - return 'the error was handled'; - }); - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - onError: 'fetchError', - debug: true, - views: { - '/throwError': { - view: 'api', - method: { - makeError: 'makeError' - } - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - await server.start(); - const response = await server.inject({ url: '/throwError' }); - expect(response.statusCode).to.equal(200); - expect(response.result).to.equal('the error was handled'); - }); - lab.test('per-route onError', async() => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('makeError', () => { throw new Error('this is an error'); }); - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - // debug: true, - views: { - '/throwError': { - view: 'api', - method: { - error: 'makeError', - }, - onError: (err, reply) => { - expect(err).to.not.equal(null); - return reply('the error was handled'); - } - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - await server.start(); - const response = await server.inject({ url: '/throwError' }); - expect(response.statusCode).to.equal(200); - expect(response.result).to.equal('the error was handled'); - }); - lab.test('per-route onError as server method', async() => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('makeError', () => { throw new Error('this is an error') }); - server.method('fetchError', (err, h) => { - expect(err).to.not.equal(null); - return 'the error was handled'; - }); - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - debug: true, - views: { - '/throwError': { - view: 'api', - method: { - error: 'makeError', - }, - onError: 'fetchError' - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - await server.start(); - const response = await server.inject({ url: '/throwError' }); - expect(response.statusCode).to.equal(200); - expect(response.result).to.equal('the error was handled'); - }); - -}); diff --git a/test/test.pre.js b/test/test.pre.js deleted file mode 100644 index 5eac6aa..0000000 --- a/test/test.pre.js +++ /dev/null @@ -1,121 +0,0 @@ -'use strict'; - -const Lab = require('lab'); -const lab = exports.lab = Lab.script(); -const Hoek = require('hoek'); -const expect = require('code').expect; -const Hapi = require('hapi'); - -lab.experiment('pre', () => { - lab.test('preProcess', async() => { - let processRan = false; - - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('process', (request, options, reply) => { - processRan = true; - }); - - server.method('dummy', () => '1'); - - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - routes: { - '/process': { - view: 'api', - preProcess: 'process' - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - await server.start(); - const response = await server.inject({ url: '/process' }); - expect(response.statusCode).to.equal(200); - expect(processRan).to.equal(true); - }); - lab.test('preProcess early reply', async() => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('process', (request, options, reply) => { - return { test: 2 }; - }); - - server.method('dummy', () => '1'); - - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - routes: { - '/process': { - view: 'api', - preProcess: 'process', - method: { - dummy: 'dummy' - } - } - } - } - }], (error) => { - Hoek.assert(!error, error); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - }); - await server.start(); - const response = await server.inject({ url: '/process' }); - expect(response.statusCode).to.equal(200); - expect(response.result.test).to.equal(2); - }); - lab.test('preResponse', async() => { - const server = new Hapi.Server({ - debug: { log: 'hapi-views' }, - port: 9991 - }); - server.method('response', (request, options, data) => { - return { test: 1 }; - }); - - server.method('dummy', () => '1'); - - await server.register([ - require('vision'), - { - plugin: require('../'), - options: { - routes: { - '/response': { - view: 'api', - preResponse: 'response', - method: { - dummy: 'dummy' - } - } - } - } - } - ]); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - await server.start(); - const response = await server.inject({ url: '/response' }); - expect(response.statusCode).to.equal(200); - expect(response.result.test).to.equal(1); - }); -}); diff --git a/test/test.routeConfig.js b/test/test.routeConfig.js deleted file mode 100644 index 6abefab..0000000 --- a/test/test.routeConfig.js +++ /dev/null @@ -1,87 +0,0 @@ -'use strict'; - -const Lab = require('lab'); -const lab = exports.lab = Lab.script(); -const expect = require('code').expect; -const Hapi = require('hapi'); - - -let server; -lab.experiment('global routeConfig', async() => { - lab.beforeEach(async() => { - server = new Hapi.Server(); - await server.register(require('vision')); - server.views({ - engines: { html: require('handlebars') }, - path: `${__dirname}/views` - }); - }); - lab.afterEach(async() => { - await server.stop(); - }); - - lab.test('global route config merges with local route config', async() => { - await server.register({ - plugin: require('../'), - options: { - routeConfig: { - cache: { - privacy: 'public', - expiresIn: 1000 - } - }, - views: { - '/': { - view: 'blank' - } - } - } - }); - const res = await server.inject('/'); - expect(res.statusCode).to.equal(200); - expect(res.headers['cache-control']).to.equal('max-age=1, must-revalidate, public'); - }); - - lab.test('not setting global route Config', async() => { - await server.register({ - plugin: require('../'), - options: { - views: { - '/': { - view: 'blank' - } - } - } - }); - const res = await server.inject('/'); - expect(res.statusCode).to.equal(200); - expect(res.headers['cache-control']).to.equal('no-cache'); - }); - - lab.test('not setting global route Config', async() => { - await server.register({ - plugin: require('../'), - options: { - routeConfig: { - cache: { - privacy: 'public', - expiresIn: 1000 - } - }, - views: { - '/': { - view: 'blank', - routeConfig: { - cache: { - expiresIn: 2000 - } - } - } - } - } - }); - const res = await server.inject('/'); - expect(res.statusCode).to.equal(200); - expect(res.headers['cache-control']).to.equal('max-age=2, must-revalidate, public'); - }); -}); diff --git a/test/test.yaml.js b/test/test.yaml.js deleted file mode 100644 index 6fc6549..0000000 --- a/test/test.yaml.js +++ /dev/null @@ -1,8 +0,0 @@ -/* eslint prefer-arrow-callback: 0 */ -'use strict'; - -const Lab = require('lab'); -const lab = exports.lab = Lab.script(); -const Hoek = require('hoek'); -const expect = require('code').expect; -const Hapi = require('hapi'); diff --git a/test/views/api.html b/test/views/api.html deleted file mode 100644 index 9eec6a3..0000000 --- a/test/views/api.html +++ /dev/null @@ -1 +0,0 @@ -{{#each api.var1}}{{id}}{{/each}} diff --git a/test/views/blank.html b/test/views/blank.html deleted file mode 100644 index d07225e..0000000 --- a/test/views/blank.html +++ /dev/null @@ -1 +0,0 @@ -

hi

diff --git a/test/views/data.html b/test/views/data.html deleted file mode 100644 index 1cdea11..0000000 --- a/test/views/data.html +++ /dev/null @@ -1,3 +0,0 @@ -{{name}} -{{url}} -{{test.ok}} diff --git a/test/views/method.html b/test/views/method.html deleted file mode 100644 index b2afe96..0000000 --- a/test/views/method.html +++ /dev/null @@ -1 +0,0 @@ -{{method.method1}} diff --git a/test/views/methodWithArgs.html b/test/views/methodWithArgs.html deleted file mode 100644 index d0341b0..0000000 --- a/test/views/methodWithArgs.html +++ /dev/null @@ -1 +0,0 @@ -{{method.method1}} {{method.method2}} diff --git a/test/yaml/test2.yaml b/test/yaml/test2.yaml deleted file mode 100644 index 79f431b..0000000 --- a/test/yaml/test2.yaml +++ /dev/null @@ -1 +0,0 @@ -global: 'much global' From cb8f2f6bd4630163e9576ce12e3c07a0f9b727d6 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 7 Dec 2017 13:33:49 -0600 Subject: [PATCH 12/13] preResponse --- lib/handler.js | 4 +++- methods/views/data.js | 22 ------------------- package.json | 3 --- test/test.globals.js | 51 ++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 51 insertions(+), 29 deletions(-) delete mode 100644 methods/views/data.js diff --git a/lib/handler.js b/lib/handler.js index d523263..8c6e96b 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -1,6 +1,5 @@ 'use strict'; const boom = require('boom'); -const str2fn = require('str2fn'); const aug = require('aug'); const pprops = require('p-props'); const varson = require('varson'); @@ -15,6 +14,9 @@ module.exports = (viewConfig) => { try { const data = varson(obj, { request, methods: request.server.methods }); const result = await pprops(data); + if (viewConfig.preResponse) { + viewConfig.preResponse(request, viewConfig.options, result); + } return h.view(viewConfig.view, result); } catch (err) { if (typeof viewConfig.onError === 'function') { diff --git a/methods/views/data.js b/methods/views/data.js deleted file mode 100644 index 5f2e349..0000000 --- a/methods/views/data.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; -const varson = require('varson'); -const Hoek = require('hoek'); - -module.exports = (request, data, results, allDone) => { - if (!data) { - return allDone(null); - } - if (typeof data === 'string') { - return allDone(null, results[data]); - } - const clonedData = Hoek.clone(data); - const context = Hoek.clone(results); - context.request = { - params: request.params, - query: request.query, - url: request.url, - auth: request.auth - }; - const out = varson(clonedData, context, { start: '{', end: '}' }); - allDone(null, out); -}; diff --git a/package.json b/package.json index 6d789f9..931a06a 100644 --- a/package.json +++ b/package.json @@ -24,12 +24,10 @@ }, "homepage": "https://github.com/firstandthird/hapi-views#readme", "dependencies": { - "async": "^2.5.0", "aug": "^2.0.0", "boom": "^6.0.0", "hoek": "^5.0.0", "p-props": "^1.1.0", - "str2fn": "2.0.0", "varson": "^2.0.2" }, "devDependencies": { @@ -40,7 +38,6 @@ "eslint-plugin-import": "^2.8.0", "handlebars": "^4.0.11", "hapi": "^17.0.1", - "js-yaml": "^3.10.0", "lab": "^15.1.2", "vision": "^5.2.0" } diff --git a/test/test.globals.js b/test/test.globals.js index 31c6e69..b58e2a8 100644 --- a/test/test.globals.js +++ b/test/test.globals.js @@ -2,7 +2,6 @@ const Lab = require('lab'); const lab = exports.lab = Lab.script(); -const Hoek = require('hoek'); const expect = require('code').expect; const Hapi = require('hapi'); @@ -20,7 +19,7 @@ lab.test('server methods', async() => { { plugin: require('../'), options: { - //debug: true, + debug: true, dataPath: `${process.cwd()}/test/yaml`, routes: { '/yaml': { @@ -42,6 +41,7 @@ lab.test('server methods', async() => { const response = await server.inject({ url: '/yaml' }); const context = response.request.response.source.context; expect(context).to.equal({ yaml1: { test1: true } }); + await server.stop(); }); lab.test('globals', async() => { @@ -81,6 +81,7 @@ lab.test('globals', async() => { const response = await server.inject({ url: '/yaml' }); const context = response.request.response.source.context; expect(context.yaml2).to.equal({ property: 1235 }); + await server.stop(); }); lab.test('onError', async() => { @@ -118,6 +119,7 @@ lab.test('onError', async() => { const response = await server.inject({ url: '/yaml' }); expect(response.statusCode).to.equal(200); expect(response.result).to.equal('the error was handled'); + await server.stop(); }); lab.test('per-route onError', async() => { @@ -155,9 +157,10 @@ lab.test('per-route onError', async() => { const response = await server.inject({ url: '/yaml' }); expect(response.statusCode).to.equal(200); expect(response.result).to.equal('the error was handled'); + await server.stop(); }); -lab.test('pre', async() => { +lab.test('preprocess', async() => { let processRan = false; const server = new Hapi.Server({ debug: { log: 'hapi-views' }, @@ -194,4 +197,46 @@ lab.test('pre', async() => { const response = await server.inject({ url: '/yaml' }); expect(response.statusCode).to.equal(200); expect(processRan).to.equal(true); + await server.stop(); +}); + + +lab.test('preResponse', async() => { + let processRan = false; + const server = new Hapi.Server({ + debug: { log: 'hapi-views' }, + port: 9991 + }); + server.method('yaml', (request, yamlFile) => { + return new Promise((resolve) => { + return resolve({ test1: true }); + }); + }); + + await server.register([ + require('vision'), + { + plugin: require('../'), + options: { + routes: { + '/yaml': { + view: 'yaml', + data: { + yaml1: "{{methods.yaml(`${process.cwd()}/test/yaml/test1.yaml`)}}", + }, + preResponse: (request, options, h) => { processRan = true; } + } + } + } + } + ]); + server.views({ + engines: { html: require('handlebars') }, + path: `${__dirname}/views` + }); + await server.start(); + const response = await server.inject({ url: '/yaml' }); + expect(response.statusCode).to.equal(200); + expect(processRan).to.equal(true); + await server.stop(); }); From 5e443b13609a347e6cb94305332835a750a18d13 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 7 Dec 2017 18:40:30 -0600 Subject: [PATCH 13/13] update readme, test, remove unused hoek dep --- README.md | 79 +++++++++++++++++++++++++++++----------------------- index.js | 1 - package.json | 3 +- 3 files changed, 45 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index da81ca6..933064f 100644 --- a/README.md +++ b/README.md @@ -3,49 +3,58 @@ [![Build Status](https://travis-ci.org/firstandthird/hapi-views.svg?branch=master)](https://travis-ci.org/firstandthird/hapi-views) [![Coverage Status](https://coveralls.io/repos/github/firstandthird/hapi-views/badge.svg?branch=master)](https://coveralls.io/github/firstandthird/hapi-views?branch=master) -`hapi-views` is a hapi plugin that makes it very easy to register routes for views and pull in data. Great for pages that just need either some static data or data from an api. - +`hapi-views` is a hapi plugin that lets you quickly and easily create your view routes. You use JSON to specify routes that can pull in dynamic data from any source, then use that data to render an HTML page. ## Features -* define routes from config -* pull in yaml data and pass it to the views -* pull in data from an api endpoint -* pull in data from a server method +* works with any Hapi view engine +* define view routes with JSON instead of programming route handlers +* specify dynamic JSON for your views with [varson](https://github.com/firstandthird/varson) +* pull in data with Hapi server methods ## Usage ```javascript -server.register({ - register: require('hapi-views'), +await server.register({ + plugin: require('hapi-views'), options: { - dataPath: __dirname + '/public/pages/', - views: { - '/': { - view: 'landing/view', - yaml: 'landing/data.yaml' - }, - '/comments/{id}': { - view: 'landing/view', - api: 'http://jsonplaceholder.typicode.com/comments/{params.id}' - }, - '/load': { - view: 'landing/view', - method: 'serverLoad', - routeConfig: { // Any valid hapi route config - plugins: { - 'hapi-hello-world': {} - } - } - } - }, - // each type defined under 'globals' is loaded for all views + // 'globals' (optional) specifies global data that is common to all views + // data.serverName and data.db will be available to the view engine: globals: { - yaml: 'global.yaml', - api: 'http://globalBargle.com/icons/{params.id}', - method: 'globalMethod', - inject: '/globals' - }, + serverName: 'Bob the Server', + db: 'http://55.55.55.5555:2121/bobDb' + } + // "routes" can contain as many view routes as you like + // the key is the URL and the value is an object that specifies how to process the view for that URL + routes: { + // the URL for this route will be 'http://yourhost.com/homepage/{userId}' + '/homepage/{userId}': { + // 'view' (required) tells the view engine what HTML template to use: + view: 'homepage', + // 'data' (required) tells the view engine what context data to use when rendering the HTML + // this data is itself processed by the template engine in varson: + data: { + // an example of a literal string value: + title: "Your Homepage", + // varson evaluates string values inside the double-bracket '{{' delimiters as Javascript. + // So the view engine will see data.amount as 35: + amount: "{{ 15 + 25 }}", + // the Hapi request object (https://hapijs.com/api#request) can be referenced directly: + userId: "{{request.params.userId}}", + // Hapi server methods (https://hapijs.com/api#server.method()) can be referenced as 'methods'. + // for example, this expression will set data.userInfo to the value returned by calling server.methods.getUserInfo. Works for methods that return a promise as well: + userInfo: "{{methods.getUserInfo(request.params.userId)}}" + }, + // 'preProcess' (optional) will be called before the request is processed: + preProcess: (request, options, h) => { } + // 'preResponse (optional) will be called after the request is processed but before the view is returned: + preResponse: (request, options, h) => { processRan = true; } + // 'onError' (optional) will be called if there is an error processing your data or view. + // The value returned by onError will be the result your route returns to the client: + onError: (err, h) => { return boom.badImplementation('this was an error') } + } + } } -}, function(err) { }); ``` + + See [test/test.global.js](https://github.com/firstandthird/hapi-views/blob/master/test/test.globals.js) for working examples. diff --git a/index.js b/index.js index 147db0c..abe5633 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,5 @@ 'use strict'; /* eslint new-cap: 0 */ -const hoek = require('hoek'); const aug = require('aug'); const renderHandler = require('./lib/handler.js'); const defaults = { diff --git a/package.json b/package.json index 931a06a..db478f0 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "lint": "eslint .", - "test": "lab -t 100 -v", + "test": "lab --leaks", "test-travis": "lab -r lcov | ./node_modules/.bin/coveralls" }, "repository": { @@ -26,7 +26,6 @@ "dependencies": { "aug": "^2.0.0", "boom": "^6.0.0", - "hoek": "^5.0.0", "p-props": "^1.1.0", "varson": "^2.0.2" },