Skip to content

Commit

Permalink
Merge pull request #1619 from shanear/feature-custom-middleware
Browse files Browse the repository at this point in the history
feat(web-server): allow injection of custom middleware.
  • Loading branch information
dignifiedquire committed Oct 14, 2015
2 parents 0863bb6 + 2e963c3 commit 60975de
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 5 deletions.
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

0 comments on commit 60975de

Please sign in to comment.