mocks: docs, examples, tests
This commit is contained in:
106
README.md
106
README.md
@ -47,16 +47,6 @@ By default, typical SPA urls (e.g. `/user/1`, `/login`) would return `404 Not Fo
|
||||
|
||||
[Example](https://github.com/75lb/local-web-server/tree/master/example/spa).
|
||||
|
||||
### Access Control
|
||||
|
||||
By default, access to all files is allowed (including dot files). Use `--forbid` to establish a blacklist:
|
||||
```sh
|
||||
$ ws --forbid '*.json' '*.yml'
|
||||
serving at http://localhost:8000
|
||||
```
|
||||
|
||||
[Example](https://github.com/75lb/local-web-server/tree/master/example/forbid).
|
||||
|
||||
### URL rewriting
|
||||
|
||||
Your application requested `/css/style.css` but it's stored at `/build/css/style.css`. To avoid a 404 you need a rewrite rule:
|
||||
@ -79,7 +69,6 @@ $ ws --rewrite '/css/* -> /build/css/$1'
|
||||
|
||||
this rewrites `/css/a` as `/build/css/a`, `/css/a/b/c` as `/build/css/a/b/c` etc.
|
||||
|
||||
|
||||
#### Proxied requests
|
||||
|
||||
If the `to` URL contains a remote host, local-web-server will act as a proxy - fetching and responding with the remote resource.
|
||||
@ -96,6 +85,91 @@ $ ws --rewrite '/:user/repos/:name -> https://api.github.com/repos/:user/:name'
|
||||
|
||||
[Example](https://github.com/75lb/local-web-server/tree/master/example/rewrite).
|
||||
|
||||
### Mock Responses
|
||||
|
||||
Mock a data service, serve any custom/dynamic content.
|
||||
|
||||
A mock definition maps a route to a response. Mock a home page.
|
||||
```json
|
||||
{
|
||||
"mocks": [
|
||||
{
|
||||
"route": "/",
|
||||
"response": {
|
||||
"body": "<h1>Welcome to the Mock Responses example</h1>"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Conditional response, depending on the request.
|
||||
```json
|
||||
{
|
||||
"mocks": [
|
||||
{
|
||||
"route": "/two",
|
||||
"request": { "accepts": "xml" },
|
||||
"response": {
|
||||
"body": "<result id='2' name='whatever' />"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Multiple potential responses. First request to match.
|
||||
```json
|
||||
{
|
||||
"mocks": [
|
||||
{
|
||||
"route": "/three",
|
||||
"responses": [
|
||||
{
|
||||
"request": { "method": "GET" },
|
||||
"response": {
|
||||
"body": "<h1>Mock response for 'GET' request on /three</h1>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"request": { "method": "POST" },
|
||||
"response": {
|
||||
"status": 400,
|
||||
"body": { "message": "That method is not allowed." }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
More dynamic response.
|
||||
```json
|
||||
{
|
||||
"mocks": [
|
||||
{
|
||||
"route": "/four",
|
||||
"module": "/mocks/four.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Tokens in the route are passed to the response.
|
||||
```json
|
||||
{
|
||||
"mocks": [
|
||||
{
|
||||
"route": "/five/:id\\?name=:name",
|
||||
"module": "/mocks/five.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
[Example](https://github.com/75lb/local-web-server/tree/master/example/mock).
|
||||
|
||||
### Stored config
|
||||
|
||||
Use the same port and blacklist every time? Persist it to `package.json`:
|
||||
@ -136,6 +210,16 @@ serving at http://localhost:8000
|
||||
|
||||
The format value supplied is passed directly to [morgan](https://github.com/expressjs/morgan). The exception is `--log-format none` which disables all output.
|
||||
|
||||
### Access Control
|
||||
|
||||
By default, access to all files is allowed (including dot files). Use `--forbid` to establish a blacklist:
|
||||
```sh
|
||||
$ ws --forbid '*.json' '*.yml'
|
||||
serving at http://localhost:8000
|
||||
```
|
||||
|
||||
[Example](https://github.com/75lb/local-web-server/tree/master/example/forbid).
|
||||
|
||||
### Other usage
|
||||
|
||||
#### Debugging
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"mocks": [
|
||||
{
|
||||
"route": "/one",
|
||||
"route": "/",
|
||||
"response": {
|
||||
"body": { "id": 1, "name": "whatever" }
|
||||
"body": "<h1>Welcome to the Mock Responses example</h1>"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -15,11 +15,11 @@
|
||||
},
|
||||
{
|
||||
"route": "/three",
|
||||
"targets": [
|
||||
"responses": [
|
||||
{
|
||||
"request": { "method": "GET" },
|
||||
"response": {
|
||||
"body": { "id": 1, "name": "whatever" }
|
||||
"body": "<h1>Mock response for 'GET' request on /three</h1>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1,7 +0,0 @@
|
||||
body {
|
||||
background-color: #AA3939;
|
||||
color: #FFE2E2
|
||||
}
|
||||
svg {
|
||||
fill: #000
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
<head>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
</head>
|
||||
<h1>Mock responses</h1>
|
||||
<ul>
|
||||
<li>list data</li>
|
||||
</ul>
|
||||
<script src="bundle.js"></script>
|
@ -1,9 +0,0 @@
|
||||
'use strict'
|
||||
const request = require('req-then')
|
||||
const $ = document.querySelector.bind(document)
|
||||
|
||||
request('http://localhost:8000/tree').then(response => {
|
||||
$('ul').innerHTML = JSON.parse(response.data).map(tree => {
|
||||
return `<li>${tree.name}</li>`
|
||||
}).join('')
|
||||
})
|
3
example/mock/mocks/data.json
Normal file
3
example/mock/mocks/data.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"one": "static data"
|
||||
}
|
@ -1,8 +1,5 @@
|
||||
module.exports = {
|
||||
response: function (ctx, id, name) {
|
||||
this.body = {
|
||||
id: id,
|
||||
name: name
|
||||
}
|
||||
ctx.body = `<h1>id: ${id}, name: ${name}</h1>`
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
const fs = require('fs')
|
||||
|
||||
module.exports = {
|
||||
response: {
|
||||
body: { id: 2, name: 'eucalyptus', maxHeight: 210 }
|
||||
body: fs.createReadStream(__filename)
|
||||
}
|
||||
}
|
||||
|
@ -47,16 +47,6 @@ By default, typical SPA urls (e.g. `/user/1`, `/login`) would return `404 Not Fo
|
||||
|
||||
[Example](https://github.com/75lb/local-web-server/tree/master/example/spa).
|
||||
|
||||
### Access Control
|
||||
|
||||
By default, access to all files is allowed (including dot files). Use `--forbid` to establish a blacklist:
|
||||
```sh
|
||||
$ ws --forbid '*.json' '*.yml'
|
||||
serving at http://localhost:8000
|
||||
```
|
||||
|
||||
[Example](https://github.com/75lb/local-web-server/tree/master/example/forbid).
|
||||
|
||||
### URL rewriting
|
||||
|
||||
Your application requested `/css/style.css` but it's stored at `/build/css/style.css`. To avoid a 404 you need a rewrite rule:
|
||||
@ -79,7 +69,6 @@ $ ws --rewrite '/css/* -> /build/css/$1'
|
||||
|
||||
this rewrites `/css/a` as `/build/css/a`, `/css/a/b/c` as `/build/css/a/b/c` etc.
|
||||
|
||||
|
||||
#### Proxied requests
|
||||
|
||||
If the `to` URL contains a remote host, local-web-server will act as a proxy - fetching and responding with the remote resource.
|
||||
@ -96,6 +85,91 @@ $ ws --rewrite '/:user/repos/:name -> https://api.github.com/repos/:user/:name'
|
||||
|
||||
[Example](https://github.com/75lb/local-web-server/tree/master/example/rewrite).
|
||||
|
||||
### Mock Responses
|
||||
|
||||
Mock a data service, serve any custom/dynamic content.
|
||||
|
||||
A mock definition maps a route to a response. Mock a home page.
|
||||
```json
|
||||
{
|
||||
"mocks": [
|
||||
{
|
||||
"route": "/",
|
||||
"response": {
|
||||
"body": "<h1>Welcome to the Mock Responses example</h1>"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Conditional response, depending on the request.
|
||||
```json
|
||||
{
|
||||
"mocks": [
|
||||
{
|
||||
"route": "/two",
|
||||
"request": { "accepts": "xml" },
|
||||
"response": {
|
||||
"body": "<result id='2' name='whatever' />"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Multiple potential responses. First request to match.
|
||||
```json
|
||||
{
|
||||
"mocks": [
|
||||
{
|
||||
"route": "/three",
|
||||
"responses": [
|
||||
{
|
||||
"request": { "method": "GET" },
|
||||
"response": {
|
||||
"body": "<h1>Mock response for 'GET' request on /three</h1>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"request": { "method": "POST" },
|
||||
"response": {
|
||||
"status": 400,
|
||||
"body": { "message": "That method is not allowed." }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
More dynamic response.
|
||||
```json
|
||||
{
|
||||
"mocks": [
|
||||
{
|
||||
"route": "/four",
|
||||
"module": "/mocks/four.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Tokens in the route are passed to the response.
|
||||
```json
|
||||
{
|
||||
"mocks": [
|
||||
{
|
||||
"route": "/five/:id\\?name=:name",
|
||||
"module": "/mocks/five.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
[Example](https://github.com/75lb/local-web-server/tree/master/example/mock).
|
||||
|
||||
### Stored config
|
||||
|
||||
Use the same port and blacklist every time? Persist it to `package.json`:
|
||||
@ -136,6 +210,16 @@ serving at http://localhost:8000
|
||||
|
||||
The format value supplied is passed directly to [morgan](https://github.com/expressjs/morgan). The exception is `--log-format none` which disables all output.
|
||||
|
||||
### Access Control
|
||||
|
||||
By default, access to all files is allowed (including dot files). Use `--forbid` to establish a blacklist:
|
||||
```sh
|
||||
$ ws --forbid '*.json' '*.yml'
|
||||
serving at http://localhost:8000
|
||||
```
|
||||
|
||||
[Example](https://github.com/75lb/local-web-server/tree/master/example/forbid).
|
||||
|
||||
### Other usage
|
||||
|
||||
#### Debugging
|
||||
|
@ -148,11 +148,11 @@ function localWebServer (options) {
|
||||
/* Mock Responses */
|
||||
options.mocks.forEach(mock => {
|
||||
if (mock.module) {
|
||||
mock.targets = require(path.join(options.static.root, mock.module))
|
||||
mock.responses = require(path.join(options.static.root, mock.module))
|
||||
}
|
||||
|
||||
if (mock.targets) {
|
||||
app.use(mw.mockResponses(mock.route, mock.targets))
|
||||
if (mock.responses) {
|
||||
app.use(mw.mockResponses(mock.route, mock.responses))
|
||||
} else if (mock.response) {
|
||||
mock.target = {
|
||||
request: mock.request,
|
||||
|
134
test/test.js
134
test/test.js
@ -17,6 +17,13 @@ function launchServer (app, options) {
|
||||
})
|
||||
}
|
||||
|
||||
function checkResponse (t, status, body) {
|
||||
return function (response) {
|
||||
if (status) t.strictEqual(response.res.statusCode, status)
|
||||
if (body) t.ok(body.test(response.data))
|
||||
}
|
||||
}
|
||||
|
||||
test('static', function (t) {
|
||||
t.plan(1)
|
||||
const app = localWebServer({
|
||||
@ -201,3 +208,130 @@ test('rewrite: proxy with port', function (t) {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('mock: simple response', function (t) {
|
||||
t.plan(2)
|
||||
const app = localWebServer({
|
||||
log: { format: 'none' },
|
||||
mocks: [
|
||||
{ route: '/test', response: { body: 'test' } }
|
||||
]
|
||||
})
|
||||
launchServer(app, { path: '/test', onSuccess: response => {
|
||||
t.strictEqual(response.res.statusCode, 200)
|
||||
t.ok(/test/.test(response.data))
|
||||
}})
|
||||
})
|
||||
|
||||
test('mock: method request filter', function (t) {
|
||||
t.plan(3)
|
||||
const app = localWebServer({
|
||||
log: { format: 'none' },
|
||||
mocks: [
|
||||
{
|
||||
route: '/test',
|
||||
request: { method: 'POST' },
|
||||
response: { body: 'test' }
|
||||
}
|
||||
]
|
||||
})
|
||||
const server = http.createServer(app.callback())
|
||||
server.listen(8100, () => {
|
||||
request('http://localhost:8100/test')
|
||||
.then(checkResponse(t, 404))
|
||||
.then(() => request('http://localhost:8100/test', { data: 'something' }))
|
||||
.then(checkResponse(t, 200, /test/))
|
||||
.then(server.close.bind(server))
|
||||
})
|
||||
})
|
||||
|
||||
test('mock: accepts request filter', function (t) {
|
||||
t.plan(3)
|
||||
const app = localWebServer({
|
||||
log: { format: 'none' },
|
||||
mocks: [
|
||||
{
|
||||
route: '/test',
|
||||
request: { accepts: 'text' },
|
||||
response: { body: 'test' }
|
||||
}
|
||||
]
|
||||
})
|
||||
const server = http.createServer(app.callback())
|
||||
server.listen(8100, () => {
|
||||
request('http://localhost:8100/test', { headers: { Accept: '*/json' }})
|
||||
.then(checkResponse(t, 404))
|
||||
.then(() => request('http://localhost:8100/test', { headers: { Accept: 'text/plain' }}))
|
||||
.then(checkResponse(t, 200, /test/))
|
||||
.then(server.close.bind(server))
|
||||
})
|
||||
})
|
||||
|
||||
test('mock: responses array', function (t) {
|
||||
t.plan(4)
|
||||
const app = localWebServer({
|
||||
log: { format: 'none' },
|
||||
mocks: [
|
||||
{
|
||||
route: '/test',
|
||||
responses: [
|
||||
{ request: { method: 'GET' }, response: { body: 'get' } },
|
||||
{ request: { method: 'POST' }, response: { body: 'post' } }
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
const server = http.createServer(app.callback())
|
||||
server.listen(8100, () => {
|
||||
request('http://localhost:8100/test')
|
||||
.then(checkResponse(t, 200, /get/))
|
||||
.then(() => request('http://localhost:8100/test', { method: 'POST' }))
|
||||
.then(checkResponse(t, 200, /post/))
|
||||
.then(server.close.bind(server))
|
||||
})
|
||||
})
|
||||
|
||||
test('mock: response function', function (t) {
|
||||
t.plan(4)
|
||||
const app = localWebServer({
|
||||
log: { format: 'none' },
|
||||
mocks: [
|
||||
{
|
||||
route: '/test',
|
||||
responses: [
|
||||
{ request: { method: 'GET' }, response: ctx => ctx.body = 'get' },
|
||||
{ request: { method: 'POST' }, response: ctx => ctx.body = 'post' }
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
const server = http.createServer(app.callback())
|
||||
server.listen(8100, () => {
|
||||
request('http://localhost:8100/test')
|
||||
.then(checkResponse(t, 200, /get/))
|
||||
.then(() => request('http://localhost:8100/test', { method: 'POST' }))
|
||||
.then(checkResponse(t, 200, /post/))
|
||||
.then(server.close.bind(server))
|
||||
})
|
||||
})
|
||||
|
||||
test('mock: response function args', function (t) {
|
||||
t.plan(2)
|
||||
const app = localWebServer({
|
||||
log: { format: 'none' },
|
||||
mocks: [
|
||||
{
|
||||
route: '/test/:one',
|
||||
responses: [
|
||||
{ request: { method: 'GET' }, response: (ctx, one) => ctx.body = one }
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
const server = http.createServer(app.callback())
|
||||
server.listen(8100, () => {
|
||||
request('http://localhost:8100/test/yeah')
|
||||
.then(checkResponse(t, 200, /yeah/))
|
||||
.then(server.close.bind(server))
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user