Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web-server): allow injection of custom middleware. #1619

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions docs/config/01-configuration-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,35 @@ httpsServerOptions: {
**Description:** A list of log appenders to be used. See the documentation for [log4js] for more information.


## middleware
**Type:** Array

**Default:** `[]`

**Description:** List of names of additional middleware you want the karma server to use. Middleware will be used in the order listed.

You must have installed the middleware via a plugin/framework (either inline or via NPM). Additional information can be found in [plugins].

The plugin must provide an express/connect middleware function (details about this can be found in [the Express docs](http://expressjs.com/guide/using-middleware.html). An example of custom inline middleware is shown below.

**Example:**
```javascript
var CustomMiddlewareFactory = function (config) {
return function (request, response, /* next */) {
response.writeHead(200)
return response.end("content!")
}
}
```

```javascript
middleware: ['custom']
plugins: [
{'middleware:custom': ['factory', CustomMiddlewareFactory]}
...
]
```

## plugins
**Type:** Array

Expand Down
11 changes: 9 additions & 2 deletions lib/web-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,16 @@ var createWebServer = function (injector, emitter, fileList) {
// TODO(vojta): remove, this is only here because of karma-dart
// we need a better way of custom handlers
.use(injector.invoke(createCustomHandler))
.use(function (request, response) {
common.serve404(response, request.url)

if (config.middleware) {
config.middleware.forEach(function (middleware) {
handler.use(injector.get('middleware:' + middleware))
})
}

handler.use(function (request, response) {
common.serve404(response, request.url)
})

var serverClass = http
var serverArguments = [handler]
Expand Down
40 changes: 37 additions & 3 deletions test/unit/web-server.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('web-server', () => {
var m = mocks.loadFile(__dirname + '/../../lib/web-server.js', _mocks, _globals)

var customFileHandlers = server = emitter = null

var middlewareActive = false
var servedFiles = (files) => {
emitter.emit('file_list_modified', {included: [], served: files})
}
Expand All @@ -41,16 +41,31 @@ describe('web-server', () => {
beforeEach(() => {
customFileHandlers = []
emitter = new EventEmitter()
var config = {
basePath: '/base/path',
urlRoot: '/',
middleware: ['custom'],
middlewareResponse: 'hello middleware!'
}

var injector = new di.Injector([{
config: ['value', {basePath: '/base/path', urlRoot: '/'}],
config: ['value', config],
customFileHandlers: ['value', customFileHandlers],
emitter: ['value', emitter],
fileList: ['value', {files: {served: [], included: []}}],
capturedBrowsers: ['value', null],
reporter: ['value', null],
executor: ['value', null],
proxies: ['value', null]
proxies: ['value', null],
'middleware:custom': ['factory', function (config) {
return function (request, response, next) {
if (middlewareActive) {
response.writeHead(222)
return response.end(config.middlewareResponse)
}
next()
}
}]
}])

server = injector.invoke(m.createWebServer)
Expand Down Expand Up @@ -81,6 +96,25 @@ describe('web-server', () => {
.expect(200, 'new-js-source')
})

describe('middleware', () => {
beforeEach(() => {
servedFiles(new Set([new File('/base/path/one.js')]))
middlewareActive = true
})

it('should use injected middleware', () => {
return request(server)
.get('/base/other.js')
.expect(222, 'hello middleware!')
})

it('should inject middleware behind served files', () => {
return request(server)
.get('/base/one.js')
.expect(200, 'js-source')
})
})

it('should serve no files when they are not available yet', () => {
return request(server)
.get('/base/new.js')
Expand Down