10
'use strict';
11
12
describe('ReactFetchNode', () => {
13
- let ReactCache;
14
- let ReactFetchNode;
13
let http;
14
let fetch;
15
+ let waitForSuspense;
16
let server;
17
let serverEndpoint;
18
let serverImpl;
19
20
beforeEach(done => {
21
jest.resetModules();
23
- if (__EXPERIMENTAL__) {
24
- ReactCache = require('react/unstable-cache');
25
- // TODO: A way to pass load context.
26
- ReactCache.CacheProvider._context._currentValue = ReactCache.createCache();
27
- ReactFetchNode = require('react-fetch');
28
- fetch = ReactFetchNode.fetch;
29
- }
22
+
23
+ fetch = require('react-fetch').fetch;
24
http = require('http');
25
+ waitForSuspense = require('react-suspense-test-utils').waitForSuspense;
26
27
server = http.createServer((req, res) => {
28
serverImpl(req, res);
29
});
35
- server.listen(done);
36
- serverEndpoint = `http://localhost:${server.address().port}/`;
30
+ serverEndpoint = null;
31
+ server.listen(() => {
32
+ serverEndpoint = `http://localhost:${server.address().port}/`;
33
+ done();
34
+ });
35
});
36
37
afterEach(done => {
39
server = null;
40
});
41
44
- async function waitForSuspense(fn) {
45
- while (true) {
46
- try {
47
- return fn();
48
- } catch (promise) {
49
- if (typeof promise.then === 'function') {
50
- await promise;
51
- } else {
52
- throw promise;
53
- }
54
- }
55
- }
56
- }
42
+ // @gate experimental
43
+ it('can fetch text from a server component', async () => {
44
+ serverImpl = (req, res) => {
45
+ res.write('mango');
46
+ res.end();
47
+ };
48
+ const text = await waitForSuspense(() => {
49
+ return fetch(serverEndpoint).text();
50
+ });
51
+ expect(text).toEqual('mango');
52
+ });
53
54
// @gate experimental
59
- it('can read text', async () => {
55
+ it('can fetch json from a server component', async () => {
56
serverImpl = (req, res) => {
61
- res.write('ok');
57
+ res.write(JSON.stringify({name: 'Sema'}));
58
res.end();
59
};
64
- await waitForSuspense(() => {
65
- const response = fetch(serverEndpoint);
66
- expect(response.status).toBe(200);
67
- expect(response.statusText).toBe('OK');
68
- expect(response.ok).toBe(true);
69
- expect(response.text()).toEqual('ok');
70
- // Can read again:
71
- expect(response.text()).toEqual('ok');
60
+ const json = await waitForSuspense(() => {
61
+ return fetch(serverEndpoint).json();
62
});
63
+ expect(json).toEqual({name: 'Sema'});
64
});
65
66
// @gate experimental
76
- it('can read json', async () => {
67
+ it('provides response status', async () => {
68
serverImpl = (req, res) => {
69
res.write(JSON.stringify({name: 'Sema'}));
70
res.end();
71
};
81
- await waitForSuspense(() => {
82
- const response = fetch(serverEndpoint);
83
- expect(response.status).toBe(200);
84
- expect(response.statusText).toBe('OK');
85
- expect(response.ok).toBe(true);
86
- expect(response.json()).toEqual({
87
- name: 'Sema',
88
- });
89
- // Can read again:
90
- expect(response.json()).toEqual({
91
- name: 'Sema',
92
- });
72
+ const response = await waitForSuspense(() => {
73
+ return fetch(serverEndpoint);
74
+ });
75
+ expect(response).toMatchObject({
76
+ status: 200,
77
+ statusText: 'OK',
78
+ ok: true,
79
});
80
});
81
+
82
+ // @gate experimental
83
+ it('handles different paths', async () => {
84
+ serverImpl = (req, res) => {
85
+ switch (req.url) {
86
+ case '/banana':
87
+ res.write('banana');
88
+ break;
89
+ case '/mango':
90
+ res.write('mango');
91
+ break;
92
+ case '/orange':
93
+ res.write('orange');
94
+ break;
95
+ }
96
+ res.end();
97
+ };
98
+ const outputs = await waitForSuspense(() => {
99
+ return [
100
+ fetch(serverEndpoint + 'banana').text(),
101
+ fetch(serverEndpoint + 'mango').text(),
102
+ fetch(serverEndpoint + 'orange').text(),
103
+ ];
104
+ });
105
+ expect(outputs).toMatchObject(['banana', 'mango', 'orange']);
106
+ });
107
+
108
+ // @gate experimental
109
+ it('can produce an error', async () => {
110
+ serverImpl = (req, res) => {};
111
+
112
+ expect.assertions(1);
113
+ try {
114
+ await waitForSuspense(() => {
115
+ return fetch('BOOM');
116
+ });
117
+ } catch (err) {
118
+ expect(err.message).toEqual('Invalid URL: BOOM');
119
+ }
120
+ });
121
});