Skip to content

Commit 3aede11

Browse files
committed
Add the nock proxy
1 parent 956d137 commit 3aede11

File tree

6 files changed

+183
-3
lines changed

6 files changed

+183
-3
lines changed

addon-test-support/index.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { fetch } from 'whatwg-fetch';
22
import { setupContext, teardownContext } from '@ember/test-helpers';
33
import { mockServer } from './-private/mock-server';
44
import param from 'jquery-param';
5+
import * as Comlink from 'comlink';
56

67
export function setup(hooks) {
78
hooks.beforeEach(async function() {
@@ -39,6 +40,35 @@ export async function visit(url, options = {}) {
3940

4041
export { mockServer };
4142

43+
export const nock = Comlink.wrapChain({
44+
listeners: [],
45+
46+
async postMessage(message) {
47+
let response = await fetch('/__nock-proxy', {
48+
method: 'post',
49+
headers: {
50+
'Content-Type': 'application/json',
51+
},
52+
body: JSON.stringify(message),
53+
});
54+
55+
let result = await response.json();
56+
57+
for (let listener of this.listeners) {
58+
listener({ data: result });
59+
}
60+
},
61+
62+
addEventListener(type, listener) {
63+
this.listeners.push(listener);
64+
},
65+
66+
removeEventListener(type, listener) {
67+
let index = this.listeners.indexOf(listener);
68+
this.listeners.splice(index, 1);
69+
},
70+
});
71+
4272
// private
4373

4474
let fetchFromEmberCli = async function(url, headers) {

index.js

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,46 @@ let FastBoot = require('fastboot');
44
let url = require('url');
55
let resolve = require('resolve');
66
let nock = require('nock');
7-
let bodyParser = require('body-parser')
7+
let bodyParser = require('body-parser');
8+
let Comlink = require('comlink');
9+
10+
let nockInterface = {
11+
listeners: [],
12+
lastMessage: null,
13+
14+
dispatchEvent(message) {
15+
let listener = this.listeners[0];
16+
return listener({ data: message });
17+
},
18+
19+
postMessage(message) {
20+
this.lastMessage = message;
21+
},
22+
23+
addEventListener(type, listener) {
24+
this.listeners.push(listener);
25+
},
26+
27+
removeEventListener(type, listener) {
28+
let index = this.listeners.indexOf(listener);
29+
this.listeners.splice(index, 1);
30+
},
31+
}
32+
33+
Comlink.expose(nock, nockInterface);
34+
35+
let getCircularReplacer = () => {
36+
let seen = new WeakSet();
37+
return (key, value) => {
38+
if (typeof value === "object" && value !== null) {
39+
if (seen.has(value)) {
40+
return;
41+
}
42+
seen.add(value);
43+
}
44+
return value;
45+
};
46+
}
847

948
module.exports = {
1049
name: 'ember-cli-fastboot-testing',
@@ -41,6 +80,16 @@ module.exports = {
4180
},
4281

4382
_fastbootRenderingMiddleware(app) {
83+
app.post('/__nock-proxy', bodyParser.json(), (req, res) => {
84+
nockInterface.dispatchEvent(req.body).then(() => {
85+
let body = JSON.stringify(
86+
nockInterface.lastMessage,
87+
getCircularReplacer()
88+
);
89+
90+
res.send(body);
91+
});
92+
});
4493

4594
app.post('/__mock-request', bodyParser.json(), (req, res) => {
4695
let mock = nock(req.headers.origin)

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
},
2323
"dependencies": {
2424
"body-parser": "^1.18.3",
25+
"comlink": "^4.0.1",
2526
"ember-auto-import": "^1.2.15",
2627
"ember-cli-babel": "^6.6.0",
2728
"fastboot": "^1.2.1",

tests/fastboot/network-mocking-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ module('Fastboot | network mocking', function(hooks) {
6969

7070
test('it can mock a get request', async function(assert) {
7171
await mockServer.get('/api/notes', [
72-
{ id: 1, title: 'get note'},
72+
{ id: 1, title: 'get note' },
7373
]);
7474

7575
await visit('/examples/network/other/get-request');
@@ -79,7 +79,7 @@ module('Fastboot | network mocking', function(hooks) {
7979

8080
test('it can mock a post request', async function(assert) {
8181
await mockServer.post('/api/notes', [
82-
{ id: 1, title: 'post note'},
82+
{ id: 1, title: 'post note' },
8383
]);
8484

8585
await visit('/examples/network/other/post-request');

tests/fastboot/nock-proxy-test.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { module, test } from 'qunit';
2+
import { setup, visit, nock } from 'ember-cli-fastboot-testing/test-support';
3+
4+
module('Fastboot | nock proxy', function(hooks) {
5+
setup(hooks);
6+
7+
test('it will not change an endpoint that already exists', async function(assert) {
8+
await visit('/examples/network/other/echo?message=hello%20world');
9+
assert.dom('[data-test-id="echo"]').hasText("hello world");
10+
});
11+
12+
test('it can mock an array of models', async function(assert) {
13+
await nock('http://localhost:7357')
14+
.intercept('/api/notes', 'GET')
15+
.reply(200, {
16+
data: [
17+
{
18+
type: 'note',
19+
id: '1',
20+
attributes: {
21+
title: 'test note'
22+
}
23+
},
24+
{
25+
type: 'note',
26+
id: '2',
27+
attributes: {
28+
title: 'test 2'
29+
}
30+
}
31+
]
32+
});
33+
34+
await visit('/examples/network/notes');
35+
36+
assert.dom('[data-test-id="title-1"]').hasText("test note")
37+
assert.dom('[data-test-id="title-2"]').hasText("test 2")
38+
});
39+
40+
test('it can mock a single model', async function(assert) {
41+
await nock('http://localhost:7357')
42+
.intercept('/api/notes/1', 'GET')
43+
.reply(200, {
44+
data: {
45+
type: "notes",
46+
id: "1",
47+
attributes: {
48+
title: 'test note'
49+
}
50+
}
51+
});
52+
53+
await visit('/examples/network/notes/1');
54+
55+
assert.dom('[data-test-id="title"]').hasText("test note");
56+
});
57+
58+
test('it can mock 404s', async function(assert) {
59+
await nock('http://localhost:7357')
60+
.intercept('/api/notes/1', 'GET')
61+
.reply(404, {
62+
errors: [
63+
{ title: "Not found" }
64+
]
65+
});
66+
67+
await visit('/examples/network/notes/1');
68+
69+
assert.dom().includesText('Ember Data Request GET /api/notes/1 returned a 404');
70+
});
71+
72+
test('it can mock a get request', async function(assert) {
73+
await nock('http://localhost:7357')
74+
.intercept('/api/notes', 'GET')
75+
.reply(200, [
76+
{ id: 1, title: 'get note' },
77+
]);
78+
79+
await visit('/examples/network/other/get-request');
80+
81+
assert.dom('[data-test-id="title-1"]').hasText("get note")
82+
});
83+
84+
test('it can mock a post request', async function(assert) {
85+
await nock('http://localhost:7357')
86+
.intercept('/api/notes', 'POST')
87+
.reply(200, [
88+
{ id: 1, title: 'post note' },
89+
]);
90+
91+
await visit('/examples/network/other/post-request');
92+
93+
assert.dom('[data-test-id="title-1"]').hasText("post note")
94+
});
95+
});

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3760,6 +3760,11 @@ combined-stream@~0.0.4:
37603760
dependencies:
37613761
delayed-stream "0.0.5"
37623762

3763+
comlink@^4.0.1:
3764+
version "4.0.1"
3765+
resolved "https://registry.yarnpkg.com/comlink/-/comlink-4.0.1.tgz#b20d0fca012ef80cf7eae89b76e4b43b2a1a0e6d"
3766+
integrity sha512-xEI50m6xEff5aZ29Epd+eNP+Plq2xTcUXGDJeWNqptudNB0hr59NV2KIi1xz6igb/Y2azKKSAj4ehI3wgGbREw==
3767+
37633768
commander@2.12.2:
37643769
version "2.12.2"
37653770
resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"

0 commit comments

Comments
 (0)