From ebdcedadbe485eb7cc4cfcacd57af544977cd2cb Mon Sep 17 00:00:00 2001 From: ferdinando-ferreira Date: Mon, 20 Aug 2018 16:21:24 +0100 Subject: [PATCH 1/7] Add the option `acceptedMethods` Add the option `acceptedMethods` to allow for requests with method other than "GET" to be processed --- lib/middleware.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/middleware.js b/lib/middleware.js index dd720729e..7af6f54dc 100644 --- a/lib/middleware.js +++ b/lib/middleware.js @@ -24,7 +24,8 @@ module.exports = function wrapper(context) { })); } - if (req.method !== 'GET') { + const acceptedMethods = context.options.acceptedMethods || ['GET']; + if (acceptedMethods.indexOf(req.method) === -1) { return goNext(); } From 60aa130c2f7735be62d2d70f95e556ff597bcfb8 Mon Sep 17 00:00:00 2001 From: ferdinando-ferreira Date: Mon, 20 Aug 2018 16:25:57 +0100 Subject: [PATCH 2/7] Update README.md Update README.md documenting the addition of the option `acceptedMethods` --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 6b883a42e..0ff57722b 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,13 @@ for the Object. _Note: The `publicPath` property is required, whereas all other options are optional_ +### acceptedMethods + +Type: `Array` +Default: `[ 'GET' ]` + +This property allows a user to pass the list of HTTP request methods accepted by the server. + ### headers Type: `Object` From 795b08a39fc46c6f571f05ca7474672fca60e9bd Mon Sep 17 00:00:00 2001 From: ferdinando-ferreira Date: Mon, 20 Aug 2018 18:45:10 +0100 Subject: [PATCH 3/7] Tests for the option `acceptedMethods` Add a set of testes for the option `acceptedMethods` --- test/tests/server.js | 878 ++++++++++++++++++++++--------------------- 1 file changed, 453 insertions(+), 425 deletions(-) diff --git a/test/tests/server.js b/test/tests/server.js index af851daf4..1d576891b 100644 --- a/test/tests/server.js +++ b/test/tests/server.js @@ -1,425 +1,453 @@ -'use strict'; - -/* eslint import/no-extraneous-dependencies: off */ - -const fs = require('fs'); -const path = require('path'); -const assert = require('assert'); -const express = require('express'); -const webpack = require('webpack'); -const request = require('supertest'); -const middleware = require('../../'); -const webpackConfig = require('../fixtures/server-test/webpack.config'); -const webpackMultiConfig = require('../fixtures/server-test/webpack.array.config'); -const webpackClientServerConfig = require('../fixtures/server-test/webpack.client.server.config'); - -describe('Server', () => { - let instance; - let listen; - let app; - - const logLevel = 'error'; - - function listenShorthand(done) { - return app.listen(8000, '127.0.0.1', (err) => { - if (err) done(err); - done(); - }); - } - - function close(done) { - instance.close(); - - if (listen) { - listen.close(done); - } else { - done(); - } - } - - describe('requests', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - publicPath: '/public/' - }); - app.use(instance); - listen = listenShorthand(done); - // Hack to add a mock HMR json file to the in-memory filesystem. - instance.fileSystem.writeFileSync('/123a123412.hot-update.json', '["hi"]'); - }); - - after(close); - - it('should not find a bundle file on disk', (done) => { - request(app).get('/public/bundle.js') - .expect(200, () => { - const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); - assert(!fs.existsSync(bundlePath)); - done(); - }); - }); - - it('GET request to bundle file', (done) => { - request(app).get('/public/bundle.js') - .expect('Content-Type', 'application/javascript; charset=UTF-8') - .expect('Content-Length', '3645') - .expect(200, /console\.log\('Hey\.'\)/, done); - }); - - it('POST request to bundle file', (done) => { - request(app).post('/public/bundle.js') - .expect(404, done); - }); - - it('request to image', (done) => { - request(app).get('/public/svg.svg') - .expect('Content-Type', 'image/svg+xml; charset=UTF-8') - .expect('Content-Length', '4778') - .expect(200, done); - }); - - it('request to non existing file', (done) => { - request(app).get('/public/nope') - .expect('Content-Type', 'text/html; charset=utf-8') - .expect(404, done); - }); - - it('request to HMR json', (done) => { - request(app).get('/public/123a123412.hot-update.json') - .expect('Content-Type', 'application/json; charset=UTF-8') - .expect(200, /\["hi"\]/, done); - }); - - it('request to directory', (done) => { - request(app).get('/public/') - .expect('Content-Type', 'text/html; charset=UTF-8') - .expect('Content-Length', '10') - .expect(200, /My Index\./, done); - }); - - it('invalid range header', (done) => { - request(app).get('/public/svg.svg') - .set('Range', 'bytes=6000-') - .expect(416, done); - }); - - it('valid range header', (done) => { - request(app).get('/public/svg.svg') - .set('Range', 'bytes=3000-3500') - .expect('Content-Length', '501') - .expect('Content-Range', 'bytes 3000-3500/4778') - .expect(206, done); - }); - - it('request to non-public path', (done) => { - request(app).get('/nonpublic/') - .expect('Content-Type', 'text/html; charset=utf-8') - .expect(404, done); - }); - }); - - describe('no index mode', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - index: false, - publicPath: '/' - }); - app.use(instance); - listen = listenShorthand(done); - }); - after(close); - - it('request to directory', (done) => { - request(app).get('/') - .expect('Content-Type', 'text/html; charset=utf-8') - .expect(404, done); - }); - }); - - describe('lazy mode', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - lazy: true, - publicPath: '/' - }); - app.use(instance); - listen = listenShorthand(done); - }); - after(close); - - it('GET request to bundle file', (done) => { - request(app).get('/bundle.js') - .expect('Content-Length', '3645') - .expect(200, /console\.log\('Hey\.'\)/, done); - }); - }); - - describe('custom headers', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - headers: { 'X-nonsense-1': 'yes', 'X-nonsense-2': 'no' } - }); - app.use(instance); - listen = listenShorthand(done); - }); - after(close); - - it('request to bundle file', (done) => { - request(app).get('/bundle.js') - .expect('X-nonsense-1', 'yes') - .expect('X-nonsense-2', 'no') - .expect(200, done); - }); - }); - - describe('custom mimeTypes', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - index: 'Index.phtml', - mimeTypes: { - 'text/html': ['phtml'] - } - }); - app.use(instance); - listen = listenShorthand(done); - instance.fileSystem.writeFileSync('/Index.phtml', 'welcome'); - }); - after(close); - - it('request to Index.phtml', (done) => { - request(app).get('/') - .expect('welcome') - .expect('Content-Type', /text\/html/) - .expect(200, done); - }); - }); - - describe('WebAssembly', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel - }); - app.use(instance); - listen = listenShorthand(done); - instance.fileSystem.writeFileSync('/hello.wasm', 'welcome'); - }); - after(close); - - it('request to hello.wasm', (done) => { - request(app).get('/hello.wasm') - .expect('Content-Type', 'application/wasm') - .expect('welcome') - .expect(200, done); - }); - }); - - describe('MultiCompiler', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackMultiConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - publicPath: '/' - }); - app.use(instance); - listen = listenShorthand(done); - }); - after(close); - - it('request to both bundle files', (done) => { - request(app).get('/js1/foo.js') - .expect(200, () => { - request(app).get('/js2/bar.js') - .expect(200, done); - }); - }); - }); - - describe('MultiCompiler: One `publicPath`', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackClientServerConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel - }); - app.use(instance); - listen = listenShorthand(done); - }); - after(close); - - it('request to bundle file', (done) => { - request(app).get('/static/foo.js').expect(200, done); - }); - - it('request to nonexistent file', (done) => { - request(app).get('/static/invalid.js').expect(404, done); - }); - - it('request to non-public path', (done) => { - request(app).get('/').expect(404, done); - }); - }); - - describe('server side render', () => { - let locals; - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - serverSideRender: true - }); - app.use(instance); - app.use((req, res) => { - locals = res.locals; // eslint-disable-line prefer-destructuring - res.sendStatus(200); - }); - listen = listenShorthand(done); - }); - after(close); - - it('request to bundle file', (done) => { - request(app).get('/foo/bar') - .expect(200, () => { - assert(locals.webpackStats); - done(); - }); - }); - }); - - function writeToDisk(value, done) { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - writeToDisk: value - }); - app.use(instance); - app.use((req, res) => { - res.sendStatus(200); - }); - listen = listenShorthand(done); - } - - describe('write to disk', () => { - before((done) => { - writeToDisk(true, done); - }); - after(close); - - it('should find the bundle file on disk', (done) => { - request(app).get('/foo/bar') - .expect(200, () => { - const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); - assert(fs.existsSync(bundlePath)); - fs.unlinkSync(bundlePath); - done(); - }); - }); - }); - - describe('write to disk with filter', () => { - before((done) => { - writeToDisk(filePath => /bundle\.js$/.test(filePath), done); - }); - after(close); - - it('should find the bundle file on disk', (done) => { - request(app).get('/foo/bar') - .expect(200, () => { - const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); - assert(fs.existsSync(bundlePath)); - fs.unlinkSync(bundlePath); - done(); - }); - }); - }); - - describe('write to disk with false filter', () => { - before((done) => { - writeToDisk(filePath => !(/bundle\.js$/.test(filePath)), done); - }); - after(close); - - it('should not find the bundle file on disk', (done) => { - request(app).get('/foo/bar') - .expect(200, () => { - const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); - assert(!fs.existsSync(bundlePath)); - done(); - }); - }); - }); - - function multiToDisk(value, done) { - app = express(); - const compiler = webpack(webpackMultiConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - writeToDisk: value - }); - app.use(instance); - app.use((req, res) => { - res.sendStatus(200); - }); - listen = listenShorthand(done); - } - - describe('write to disk with MultiCompiler', () => { - before((done) => { - multiToDisk(true, done); - }); - after(close); - - it('should find the bundle files on disk', (done) => { - request(app).get('/foo/bar') - .expect(200, () => { - const bundleFiles = [ - '../fixtures/server-test/js1/foo.js', - '../fixtures/server-test/js1/index.html', - '../fixtures/server-test/js1/svg.svg', - '../fixtures/server-test/js2/bar.js' - ]; - - for (const bundleFile of bundleFiles) { - const bundlePath = path.join(__dirname, bundleFile); - assert(fs.existsSync(bundlePath)); - fs.unlinkSync(bundlePath); - } - - fs.rmdirSync(path.join(__dirname, '../fixtures/server-test/js1/')); - fs.rmdirSync(path.join(__dirname, '../fixtures/server-test/js2/')); - - done(); - }); - }); - }); -}); +'use strict'; + +/* eslint import/no-extraneous-dependencies: off */ + +const fs = require('fs'); +const path = require('path'); +const assert = require('assert'); +const express = require('express'); +const webpack = require('webpack'); +const request = require('supertest'); +const middleware = require('../../'); +const webpackConfig = require('../fixtures/server-test/webpack.config'); +const webpackMultiConfig = require('../fixtures/server-test/webpack.array.config'); +const webpackClientServerConfig = require('../fixtures/server-test/webpack.client.server.config'); + +describe('Server', () => { + let instance; + let listen; + let app; + + const logLevel = 'error'; + + function listenShorthand(done) { + return app.listen(8000, '127.0.0.1', (err) => { + if (err) done(err); + done(); + }); + } + + function close(done) { + instance.close(); + + if (listen) { + listen.close(done); + } else { + done(); + } + } + + describe('requests', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + publicPath: '/public/' + }); + app.use(instance); + listen = listenShorthand(done); + // Hack to add a mock HMR json file to the in-memory filesystem. + instance.fileSystem.writeFileSync('/123a123412.hot-update.json', '["hi"]'); + }); + + after(close); + + it('should not find a bundle file on disk', (done) => { + request(app).get('/public/bundle.js') + .expect(200, () => { + const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); + assert(!fs.existsSync(bundlePath)); + done(); + }); + }); + + it('GET request to bundle file', (done) => { + request(app).get('/public/bundle.js') + .expect('Content-Type', 'application/javascript; charset=UTF-8') + .expect('Content-Length', '3645') + .expect(200, /console\.log\('Hey\.'\)/, done); + }); + + it('POST request to bundle file', (done) => { + request(app).post('/public/bundle.js') + .expect(404, done); + }); + + it('request to image', (done) => { + request(app).get('/public/svg.svg') + .expect('Content-Type', 'image/svg+xml; charset=UTF-8') + .expect('Content-Length', '4778') + .expect(200, done); + }); + + it('request to non existing file', (done) => { + request(app).get('/public/nope') + .expect('Content-Type', 'text/html; charset=utf-8') + .expect(404, done); + }); + + it('request to HMR json', (done) => { + request(app).get('/public/123a123412.hot-update.json') + .expect('Content-Type', 'application/json; charset=UTF-8') + .expect(200, /\["hi"\]/, done); + }); + + it('request to directory', (done) => { + request(app).get('/public/') + .expect('Content-Type', 'text/html; charset=UTF-8') + .expect('Content-Length', '10') + .expect(200, /My Index\./, done); + }); + + it('invalid range header', (done) => { + request(app).get('/public/svg.svg') + .set('Range', 'bytes=6000-') + .expect(416, done); + }); + + it('valid range header', (done) => { + request(app).get('/public/svg.svg') + .set('Range', 'bytes=3000-3500') + .expect('Content-Length', '501') + .expect('Content-Range', 'bytes 3000-3500/4778') + .expect(206, done); + }); + + it('request to non-public path', (done) => { + request(app).get('/nonpublic/') + .expect('Content-Type', 'text/html; charset=utf-8') + .expect(404, done); + }); + }); + + describe('accepted methods', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + acceptedMethods: ['POST'], + logLevel, + publicPath: '/public/' + }); + app.use(instance); + listen = listenShorthand(done); + }); + after(close); + + it('POST request to bundle file with acceptedMethods set to [\'POST\']', (done) => { + request(app).post('/public/bundle.js') + .expect('Content-Type', 'application/javascript; charset=UTF-8') + .expect('Content-Length', '3645') + .expect(200, /console\.log\('Hey\.'\)/, done); + }); + + it('GET request to bundle file with acceptedMethods set to [\'POST\']', (done) => { + request(app).get('/public/bundle.js') + .expect(404, done); + }); + }); + + describe('no index mode', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + index: false, + publicPath: '/' + }); + app.use(instance); + listen = listenShorthand(done); + }); + after(close); + + it('request to directory', (done) => { + request(app).get('/') + .expect('Content-Type', 'text/html; charset=utf-8') + .expect(404, done); + }); + }); + + describe('lazy mode', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + lazy: true, + publicPath: '/' + }); + app.use(instance); + listen = listenShorthand(done); + }); + after(close); + + it('GET request to bundle file', (done) => { + request(app).get('/bundle.js') + .expect('Content-Length', '3645') + .expect(200, /console\.log\('Hey\.'\)/, done); + }); + }); + + describe('custom headers', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + headers: { 'X-nonsense-1': 'yes', 'X-nonsense-2': 'no' } + }); + app.use(instance); + listen = listenShorthand(done); + }); + after(close); + + it('request to bundle file', (done) => { + request(app).get('/bundle.js') + .expect('X-nonsense-1', 'yes') + .expect('X-nonsense-2', 'no') + .expect(200, done); + }); + }); + + describe('custom mimeTypes', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + index: 'Index.phtml', + mimeTypes: { + 'text/html': ['phtml'] + } + }); + app.use(instance); + listen = listenShorthand(done); + instance.fileSystem.writeFileSync('/Index.phtml', 'welcome'); + }); + after(close); + + it('request to Index.phtml', (done) => { + request(app).get('/') + .expect('welcome') + .expect('Content-Type', /text\/html/) + .expect(200, done); + }); + }); + + describe('WebAssembly', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel + }); + app.use(instance); + listen = listenShorthand(done); + instance.fileSystem.writeFileSync('/hello.wasm', 'welcome'); + }); + after(close); + + it('request to hello.wasm', (done) => { + request(app).get('/hello.wasm') + .expect('Content-Type', 'application/wasm') + .expect('welcome') + .expect(200, done); + }); + }); + + describe('MultiCompiler', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackMultiConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + publicPath: '/' + }); + app.use(instance); + listen = listenShorthand(done); + }); + after(close); + + it('request to both bundle files', (done) => { + request(app).get('/js1/foo.js') + .expect(200, () => { + request(app).get('/js2/bar.js') + .expect(200, done); + }); + }); + }); + + describe('MultiCompiler: One `publicPath`', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackClientServerConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel + }); + app.use(instance); + listen = listenShorthand(done); + }); + after(close); + + it('request to bundle file', (done) => { + request(app).get('/static/foo.js').expect(200, done); + }); + + it('request to nonexistent file', (done) => { + request(app).get('/static/invalid.js').expect(404, done); + }); + + it('request to non-public path', (done) => { + request(app).get('/').expect(404, done); + }); + }); + + describe('server side render', () => { + let locals; + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + serverSideRender: true + }); + app.use(instance); + app.use((req, res) => { + locals = res.locals; // eslint-disable-line prefer-destructuring + res.sendStatus(200); + }); + listen = listenShorthand(done); + }); + after(close); + + it('request to bundle file', (done) => { + request(app).get('/foo/bar') + .expect(200, () => { + assert(locals.webpackStats); + done(); + }); + }); + }); + + function writeToDisk(value, done) { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + writeToDisk: value + }); + app.use(instance); + app.use((req, res) => { + res.sendStatus(200); + }); + listen = listenShorthand(done); + } + + describe('write to disk', () => { + before((done) => { + writeToDisk(true, done); + }); + after(close); + + it('should find the bundle file on disk', (done) => { + request(app).get('/foo/bar') + .expect(200, () => { + const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); + assert(fs.existsSync(bundlePath)); + fs.unlinkSync(bundlePath); + done(); + }); + }); + }); + + describe('write to disk with filter', () => { + before((done) => { + writeToDisk(filePath => /bundle\.js$/.test(filePath), done); + }); + after(close); + + it('should find the bundle file on disk', (done) => { + request(app).get('/foo/bar') + .expect(200, () => { + const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); + assert(fs.existsSync(bundlePath)); + fs.unlinkSync(bundlePath); + done(); + }); + }); + }); + + describe('write to disk with false filter', () => { + before((done) => { + writeToDisk(filePath => !(/bundle\.js$/.test(filePath)), done); + }); + after(close); + + it('should not find the bundle file on disk', (done) => { + request(app).get('/foo/bar') + .expect(200, () => { + const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); + assert(!fs.existsSync(bundlePath)); + done(); + }); + }); + }); + + function multiToDisk(value, done) { + app = express(); + const compiler = webpack(webpackMultiConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + writeToDisk: value + }); + app.use(instance); + app.use((req, res) => { + res.sendStatus(200); + }); + listen = listenShorthand(done); + } + + describe('write to disk with MultiCompiler', () => { + before((done) => { + multiToDisk(true, done); + }); + after(close); + + it('should find the bundle files on disk', (done) => { + request(app).get('/foo/bar') + .expect(200, () => { + const bundleFiles = [ + '../fixtures/server-test/js1/foo.js', + '../fixtures/server-test/js1/index.html', + '../fixtures/server-test/js1/svg.svg', + '../fixtures/server-test/js2/bar.js' + ]; + + for (const bundleFile of bundleFiles) { + const bundlePath = path.join(__dirname, bundleFile); + assert(fs.existsSync(bundlePath)); + fs.unlinkSync(bundlePath); + } + + fs.rmdirSync(path.join(__dirname, '../fixtures/server-test/js1/')); + fs.rmdirSync(path.join(__dirname, '../fixtures/server-test/js2/')); + + done(); + }); + }); + }); +}); From df4654f7075f7aa7aaa9463a5ba53a5c84d953fa Mon Sep 17 00:00:00 2001 From: ferdinando-ferreira Date: Mon, 20 Aug 2018 18:49:55 +0100 Subject: [PATCH 4/7] Tests for the option `acceptedMethods` : smallfix, line ending --- test/tests/server.js | 906 +++++++++++++++++++++---------------------- 1 file changed, 453 insertions(+), 453 deletions(-) diff --git a/test/tests/server.js b/test/tests/server.js index 1d576891b..fd902f4d6 100644 --- a/test/tests/server.js +++ b/test/tests/server.js @@ -1,453 +1,453 @@ -'use strict'; - -/* eslint import/no-extraneous-dependencies: off */ - -const fs = require('fs'); -const path = require('path'); -const assert = require('assert'); -const express = require('express'); -const webpack = require('webpack'); -const request = require('supertest'); -const middleware = require('../../'); -const webpackConfig = require('../fixtures/server-test/webpack.config'); -const webpackMultiConfig = require('../fixtures/server-test/webpack.array.config'); -const webpackClientServerConfig = require('../fixtures/server-test/webpack.client.server.config'); - -describe('Server', () => { - let instance; - let listen; - let app; - - const logLevel = 'error'; - - function listenShorthand(done) { - return app.listen(8000, '127.0.0.1', (err) => { - if (err) done(err); - done(); - }); - } - - function close(done) { - instance.close(); - - if (listen) { - listen.close(done); - } else { - done(); - } - } - - describe('requests', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - publicPath: '/public/' - }); - app.use(instance); - listen = listenShorthand(done); - // Hack to add a mock HMR json file to the in-memory filesystem. - instance.fileSystem.writeFileSync('/123a123412.hot-update.json', '["hi"]'); - }); - - after(close); - - it('should not find a bundle file on disk', (done) => { - request(app).get('/public/bundle.js') - .expect(200, () => { - const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); - assert(!fs.existsSync(bundlePath)); - done(); - }); - }); - - it('GET request to bundle file', (done) => { - request(app).get('/public/bundle.js') - .expect('Content-Type', 'application/javascript; charset=UTF-8') - .expect('Content-Length', '3645') - .expect(200, /console\.log\('Hey\.'\)/, done); - }); - - it('POST request to bundle file', (done) => { - request(app).post('/public/bundle.js') - .expect(404, done); - }); - - it('request to image', (done) => { - request(app).get('/public/svg.svg') - .expect('Content-Type', 'image/svg+xml; charset=UTF-8') - .expect('Content-Length', '4778') - .expect(200, done); - }); - - it('request to non existing file', (done) => { - request(app).get('/public/nope') - .expect('Content-Type', 'text/html; charset=utf-8') - .expect(404, done); - }); - - it('request to HMR json', (done) => { - request(app).get('/public/123a123412.hot-update.json') - .expect('Content-Type', 'application/json; charset=UTF-8') - .expect(200, /\["hi"\]/, done); - }); - - it('request to directory', (done) => { - request(app).get('/public/') - .expect('Content-Type', 'text/html; charset=UTF-8') - .expect('Content-Length', '10') - .expect(200, /My Index\./, done); - }); - - it('invalid range header', (done) => { - request(app).get('/public/svg.svg') - .set('Range', 'bytes=6000-') - .expect(416, done); - }); - - it('valid range header', (done) => { - request(app).get('/public/svg.svg') - .set('Range', 'bytes=3000-3500') - .expect('Content-Length', '501') - .expect('Content-Range', 'bytes 3000-3500/4778') - .expect(206, done); - }); - - it('request to non-public path', (done) => { - request(app).get('/nonpublic/') - .expect('Content-Type', 'text/html; charset=utf-8') - .expect(404, done); - }); - }); - - describe('accepted methods', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - acceptedMethods: ['POST'], - logLevel, - publicPath: '/public/' - }); - app.use(instance); - listen = listenShorthand(done); - }); - after(close); - - it('POST request to bundle file with acceptedMethods set to [\'POST\']', (done) => { - request(app).post('/public/bundle.js') - .expect('Content-Type', 'application/javascript; charset=UTF-8') - .expect('Content-Length', '3645') - .expect(200, /console\.log\('Hey\.'\)/, done); - }); - - it('GET request to bundle file with acceptedMethods set to [\'POST\']', (done) => { - request(app).get('/public/bundle.js') - .expect(404, done); - }); - }); - - describe('no index mode', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - index: false, - publicPath: '/' - }); - app.use(instance); - listen = listenShorthand(done); - }); - after(close); - - it('request to directory', (done) => { - request(app).get('/') - .expect('Content-Type', 'text/html; charset=utf-8') - .expect(404, done); - }); - }); - - describe('lazy mode', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - lazy: true, - publicPath: '/' - }); - app.use(instance); - listen = listenShorthand(done); - }); - after(close); - - it('GET request to bundle file', (done) => { - request(app).get('/bundle.js') - .expect('Content-Length', '3645') - .expect(200, /console\.log\('Hey\.'\)/, done); - }); - }); - - describe('custom headers', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - headers: { 'X-nonsense-1': 'yes', 'X-nonsense-2': 'no' } - }); - app.use(instance); - listen = listenShorthand(done); - }); - after(close); - - it('request to bundle file', (done) => { - request(app).get('/bundle.js') - .expect('X-nonsense-1', 'yes') - .expect('X-nonsense-2', 'no') - .expect(200, done); - }); - }); - - describe('custom mimeTypes', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - index: 'Index.phtml', - mimeTypes: { - 'text/html': ['phtml'] - } - }); - app.use(instance); - listen = listenShorthand(done); - instance.fileSystem.writeFileSync('/Index.phtml', 'welcome'); - }); - after(close); - - it('request to Index.phtml', (done) => { - request(app).get('/') - .expect('welcome') - .expect('Content-Type', /text\/html/) - .expect(200, done); - }); - }); - - describe('WebAssembly', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel - }); - app.use(instance); - listen = listenShorthand(done); - instance.fileSystem.writeFileSync('/hello.wasm', 'welcome'); - }); - after(close); - - it('request to hello.wasm', (done) => { - request(app).get('/hello.wasm') - .expect('Content-Type', 'application/wasm') - .expect('welcome') - .expect(200, done); - }); - }); - - describe('MultiCompiler', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackMultiConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - publicPath: '/' - }); - app.use(instance); - listen = listenShorthand(done); - }); - after(close); - - it('request to both bundle files', (done) => { - request(app).get('/js1/foo.js') - .expect(200, () => { - request(app).get('/js2/bar.js') - .expect(200, done); - }); - }); - }); - - describe('MultiCompiler: One `publicPath`', () => { - before((done) => { - app = express(); - const compiler = webpack(webpackClientServerConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel - }); - app.use(instance); - listen = listenShorthand(done); - }); - after(close); - - it('request to bundle file', (done) => { - request(app).get('/static/foo.js').expect(200, done); - }); - - it('request to nonexistent file', (done) => { - request(app).get('/static/invalid.js').expect(404, done); - }); - - it('request to non-public path', (done) => { - request(app).get('/').expect(404, done); - }); - }); - - describe('server side render', () => { - let locals; - before((done) => { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - serverSideRender: true - }); - app.use(instance); - app.use((req, res) => { - locals = res.locals; // eslint-disable-line prefer-destructuring - res.sendStatus(200); - }); - listen = listenShorthand(done); - }); - after(close); - - it('request to bundle file', (done) => { - request(app).get('/foo/bar') - .expect(200, () => { - assert(locals.webpackStats); - done(); - }); - }); - }); - - function writeToDisk(value, done) { - app = express(); - const compiler = webpack(webpackConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - writeToDisk: value - }); - app.use(instance); - app.use((req, res) => { - res.sendStatus(200); - }); - listen = listenShorthand(done); - } - - describe('write to disk', () => { - before((done) => { - writeToDisk(true, done); - }); - after(close); - - it('should find the bundle file on disk', (done) => { - request(app).get('/foo/bar') - .expect(200, () => { - const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); - assert(fs.existsSync(bundlePath)); - fs.unlinkSync(bundlePath); - done(); - }); - }); - }); - - describe('write to disk with filter', () => { - before((done) => { - writeToDisk(filePath => /bundle\.js$/.test(filePath), done); - }); - after(close); - - it('should find the bundle file on disk', (done) => { - request(app).get('/foo/bar') - .expect(200, () => { - const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); - assert(fs.existsSync(bundlePath)); - fs.unlinkSync(bundlePath); - done(); - }); - }); - }); - - describe('write to disk with false filter', () => { - before((done) => { - writeToDisk(filePath => !(/bundle\.js$/.test(filePath)), done); - }); - after(close); - - it('should not find the bundle file on disk', (done) => { - request(app).get('/foo/bar') - .expect(200, () => { - const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); - assert(!fs.existsSync(bundlePath)); - done(); - }); - }); - }); - - function multiToDisk(value, done) { - app = express(); - const compiler = webpack(webpackMultiConfig); - instance = middleware(compiler, { - stats: 'errors-only', - logLevel, - writeToDisk: value - }); - app.use(instance); - app.use((req, res) => { - res.sendStatus(200); - }); - listen = listenShorthand(done); - } - - describe('write to disk with MultiCompiler', () => { - before((done) => { - multiToDisk(true, done); - }); - after(close); - - it('should find the bundle files on disk', (done) => { - request(app).get('/foo/bar') - .expect(200, () => { - const bundleFiles = [ - '../fixtures/server-test/js1/foo.js', - '../fixtures/server-test/js1/index.html', - '../fixtures/server-test/js1/svg.svg', - '../fixtures/server-test/js2/bar.js' - ]; - - for (const bundleFile of bundleFiles) { - const bundlePath = path.join(__dirname, bundleFile); - assert(fs.existsSync(bundlePath)); - fs.unlinkSync(bundlePath); - } - - fs.rmdirSync(path.join(__dirname, '../fixtures/server-test/js1/')); - fs.rmdirSync(path.join(__dirname, '../fixtures/server-test/js2/')); - - done(); - }); - }); - }); -}); +'use strict'; + +/* eslint import/no-extraneous-dependencies: off */ + +const fs = require('fs'); +const path = require('path'); +const assert = require('assert'); +const express = require('express'); +const webpack = require('webpack'); +const request = require('supertest'); +const middleware = require('../../'); +const webpackConfig = require('../fixtures/server-test/webpack.config'); +const webpackMultiConfig = require('../fixtures/server-test/webpack.array.config'); +const webpackClientServerConfig = require('../fixtures/server-test/webpack.client.server.config'); + +describe('Server', () => { + let instance; + let listen; + let app; + + const logLevel = 'error'; + + function listenShorthand(done) { + return app.listen(8000, '127.0.0.1', (err) => { + if (err) done(err); + done(); + }); + } + + function close(done) { + instance.close(); + + if (listen) { + listen.close(done); + } else { + done(); + } + } + + describe('requests', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + publicPath: '/public/' + }); + app.use(instance); + listen = listenShorthand(done); + // Hack to add a mock HMR json file to the in-memory filesystem. + instance.fileSystem.writeFileSync('/123a123412.hot-update.json', '["hi"]'); + }); + + after(close); + + it('should not find a bundle file on disk', (done) => { + request(app).get('/public/bundle.js') + .expect(200, () => { + const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); + assert(!fs.existsSync(bundlePath)); + done(); + }); + }); + + it('GET request to bundle file', (done) => { + request(app).get('/public/bundle.js') + .expect('Content-Type', 'application/javascript; charset=UTF-8') + .expect('Content-Length', '3645') + .expect(200, /console\.log\('Hey\.'\)/, done); + }); + + it('POST request to bundle file', (done) => { + request(app).post('/public/bundle.js') + .expect(404, done); + }); + + it('request to image', (done) => { + request(app).get('/public/svg.svg') + .expect('Content-Type', 'image/svg+xml; charset=UTF-8') + .expect('Content-Length', '4778') + .expect(200, done); + }); + + it('request to non existing file', (done) => { + request(app).get('/public/nope') + .expect('Content-Type', 'text/html; charset=utf-8') + .expect(404, done); + }); + + it('request to HMR json', (done) => { + request(app).get('/public/123a123412.hot-update.json') + .expect('Content-Type', 'application/json; charset=UTF-8') + .expect(200, /\["hi"\]/, done); + }); + + it('request to directory', (done) => { + request(app).get('/public/') + .expect('Content-Type', 'text/html; charset=UTF-8') + .expect('Content-Length', '10') + .expect(200, /My Index\./, done); + }); + + it('invalid range header', (done) => { + request(app).get('/public/svg.svg') + .set('Range', 'bytes=6000-') + .expect(416, done); + }); + + it('valid range header', (done) => { + request(app).get('/public/svg.svg') + .set('Range', 'bytes=3000-3500') + .expect('Content-Length', '501') + .expect('Content-Range', 'bytes 3000-3500/4778') + .expect(206, done); + }); + + it('request to non-public path', (done) => { + request(app).get('/nonpublic/') + .expect('Content-Type', 'text/html; charset=utf-8') + .expect(404, done); + }); + }); + + describe('accepted methods', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + acceptedMethods: ['POST'], + logLevel, + publicPath: '/public/' + }); + app.use(instance); + listen = listenShorthand(done); + }); + after(close); + + it('POST request to bundle file with acceptedMethods set to [\'POST\']', (done) => { + request(app).post('/public/bundle.js') + .expect('Content-Type', 'application/javascript; charset=UTF-8') + .expect('Content-Length', '3645') + .expect(200, /console\.log\('Hey\.'\)/, done); + }); + + it('GET request to bundle file with acceptedMethods set to [\'POST\']', (done) => { + request(app).get('/public/bundle.js') + .expect(404, done); + }); + }); + + describe('no index mode', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + index: false, + publicPath: '/' + }); + app.use(instance); + listen = listenShorthand(done); + }); + after(close); + + it('request to directory', (done) => { + request(app).get('/') + .expect('Content-Type', 'text/html; charset=utf-8') + .expect(404, done); + }); + }); + + describe('lazy mode', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + lazy: true, + publicPath: '/' + }); + app.use(instance); + listen = listenShorthand(done); + }); + after(close); + + it('GET request to bundle file', (done) => { + request(app).get('/bundle.js') + .expect('Content-Length', '3645') + .expect(200, /console\.log\('Hey\.'\)/, done); + }); + }); + + describe('custom headers', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + headers: { 'X-nonsense-1': 'yes', 'X-nonsense-2': 'no' } + }); + app.use(instance); + listen = listenShorthand(done); + }); + after(close); + + it('request to bundle file', (done) => { + request(app).get('/bundle.js') + .expect('X-nonsense-1', 'yes') + .expect('X-nonsense-2', 'no') + .expect(200, done); + }); + }); + + describe('custom mimeTypes', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + index: 'Index.phtml', + mimeTypes: { + 'text/html': ['phtml'] + } + }); + app.use(instance); + listen = listenShorthand(done); + instance.fileSystem.writeFileSync('/Index.phtml', 'welcome'); + }); + after(close); + + it('request to Index.phtml', (done) => { + request(app).get('/') + .expect('welcome') + .expect('Content-Type', /text\/html/) + .expect(200, done); + }); + }); + + describe('WebAssembly', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel + }); + app.use(instance); + listen = listenShorthand(done); + instance.fileSystem.writeFileSync('/hello.wasm', 'welcome'); + }); + after(close); + + it('request to hello.wasm', (done) => { + request(app).get('/hello.wasm') + .expect('Content-Type', 'application/wasm') + .expect('welcome') + .expect(200, done); + }); + }); + + describe('MultiCompiler', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackMultiConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + publicPath: '/' + }); + app.use(instance); + listen = listenShorthand(done); + }); + after(close); + + it('request to both bundle files', (done) => { + request(app).get('/js1/foo.js') + .expect(200, () => { + request(app).get('/js2/bar.js') + .expect(200, done); + }); + }); + }); + + describe('MultiCompiler: One `publicPath`', () => { + before((done) => { + app = express(); + const compiler = webpack(webpackClientServerConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel + }); + app.use(instance); + listen = listenShorthand(done); + }); + after(close); + + it('request to bundle file', (done) => { + request(app).get('/static/foo.js').expect(200, done); + }); + + it('request to nonexistent file', (done) => { + request(app).get('/static/invalid.js').expect(404, done); + }); + + it('request to non-public path', (done) => { + request(app).get('/').expect(404, done); + }); + }); + + describe('server side render', () => { + let locals; + before((done) => { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + serverSideRender: true + }); + app.use(instance); + app.use((req, res) => { + locals = res.locals; // eslint-disable-line prefer-destructuring + res.sendStatus(200); + }); + listen = listenShorthand(done); + }); + after(close); + + it('request to bundle file', (done) => { + request(app).get('/foo/bar') + .expect(200, () => { + assert(locals.webpackStats); + done(); + }); + }); + }); + + function writeToDisk(value, done) { + app = express(); + const compiler = webpack(webpackConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + writeToDisk: value + }); + app.use(instance); + app.use((req, res) => { + res.sendStatus(200); + }); + listen = listenShorthand(done); + } + + describe('write to disk', () => { + before((done) => { + writeToDisk(true, done); + }); + after(close); + + it('should find the bundle file on disk', (done) => { + request(app).get('/foo/bar') + .expect(200, () => { + const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); + assert(fs.existsSync(bundlePath)); + fs.unlinkSync(bundlePath); + done(); + }); + }); + }); + + describe('write to disk with filter', () => { + before((done) => { + writeToDisk(filePath => /bundle\.js$/.test(filePath), done); + }); + after(close); + + it('should find the bundle file on disk', (done) => { + request(app).get('/foo/bar') + .expect(200, () => { + const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); + assert(fs.existsSync(bundlePath)); + fs.unlinkSync(bundlePath); + done(); + }); + }); + }); + + describe('write to disk with false filter', () => { + before((done) => { + writeToDisk(filePath => !(/bundle\.js$/.test(filePath)), done); + }); + after(close); + + it('should not find the bundle file on disk', (done) => { + request(app).get('/foo/bar') + .expect(200, () => { + const bundlePath = path.join(__dirname, '../fixtures/server-test/bundle.js'); + assert(!fs.existsSync(bundlePath)); + done(); + }); + }); + }); + + function multiToDisk(value, done) { + app = express(); + const compiler = webpack(webpackMultiConfig); + instance = middleware(compiler, { + stats: 'errors-only', + logLevel, + writeToDisk: value + }); + app.use(instance); + app.use((req, res) => { + res.sendStatus(200); + }); + listen = listenShorthand(done); + } + + describe('write to disk with MultiCompiler', () => { + before((done) => { + multiToDisk(true, done); + }); + after(close); + + it('should find the bundle files on disk', (done) => { + request(app).get('/foo/bar') + .expect(200, () => { + const bundleFiles = [ + '../fixtures/server-test/js1/foo.js', + '../fixtures/server-test/js1/index.html', + '../fixtures/server-test/js1/svg.svg', + '../fixtures/server-test/js2/bar.js' + ]; + + for (const bundleFile of bundleFiles) { + const bundlePath = path.join(__dirname, bundleFile); + assert(fs.existsSync(bundlePath)); + fs.unlinkSync(bundlePath); + } + + fs.rmdirSync(path.join(__dirname, '../fixtures/server-test/js1/')); + fs.rmdirSync(path.join(__dirname, '../fixtures/server-test/js2/')); + + done(); + }); + }); + }); +}); From aa06f773435e0b1b8cc411e79b28a508b51c2d5c Mon Sep 17 00:00:00 2001 From: ferdinando-ferreira Date: Tue, 21 Aug 2018 10:16:52 +0100 Subject: [PATCH 5/7] Changed option name from acceptedMethods to methods --- lib/middleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/middleware.js b/lib/middleware.js index 7af6f54dc..23e2220cf 100644 --- a/lib/middleware.js +++ b/lib/middleware.js @@ -24,7 +24,7 @@ module.exports = function wrapper(context) { })); } - const acceptedMethods = context.options.acceptedMethods || ['GET']; + const acceptedMethods = context.options.methods || ['GET']; if (acceptedMethods.indexOf(req.method) === -1) { return goNext(); } From b1958469a328fe9bb998cefc5a107285aab9be2e Mon Sep 17 00:00:00 2001 From: ferdinando-ferreira Date: Tue, 21 Aug 2018 10:17:24 +0100 Subject: [PATCH 6/7] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ff57722b..321cc1b81 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ for the Object. _Note: The `publicPath` property is required, whereas all other options are optional_ -### acceptedMethods +### methods Type: `Array` Default: `[ 'GET' ]` From 091a0c02a74546b3691bbb8370439fbbdd664c9b Mon Sep 17 00:00:00 2001 From: ferdinando-ferreira Date: Tue, 21 Aug 2018 10:19:08 +0100 Subject: [PATCH 7/7] Changed option name from acceptedMethods to methods --- test/tests/server.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/tests/server.js b/test/tests/server.js index fd902f4d6..ba9ede7ed 100644 --- a/test/tests/server.js +++ b/test/tests/server.js @@ -128,7 +128,7 @@ describe('Server', () => { const compiler = webpack(webpackConfig); instance = middleware(compiler, { stats: 'errors-only', - acceptedMethods: ['POST'], + methods: ['POST'], logLevel, publicPath: '/public/' }); @@ -137,14 +137,14 @@ describe('Server', () => { }); after(close); - it('POST request to bundle file with acceptedMethods set to [\'POST\']', (done) => { + it('POST request to bundle file with methods set to [\'POST\']', (done) => { request(app).post('/public/bundle.js') .expect('Content-Type', 'application/javascript; charset=UTF-8') .expect('Content-Length', '3645') .expect(200, /console\.log\('Hey\.'\)/, done); }); - it('GET request to bundle file with acceptedMethods set to [\'POST\']', (done) => { + it('GET request to bundle file with methods set to [\'POST\']', (done) => { request(app).get('/public/bundle.js') .expect(404, done); });