|
10 | 10 | 'use strict';
|
11 | 11 |
|
12 | 12 | describe('ReactFetchNode', () => {
|
13 |
| - let ReactCache; |
14 |
| - let ReactFetchNode; |
15 | 13 | let http;
|
16 | 14 | let fetch;
|
| 15 | + let waitForSuspense; |
17 | 16 | let server;
|
18 | 17 | let serverEndpoint;
|
19 | 18 | let serverImpl;
|
20 | 19 |
|
21 | 20 | beforeEach(done => {
|
22 | 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; |
30 | 24 | http = require('http');
|
| 25 | + waitForSuspense = require('react-suspense-test-utils').waitForSuspense; |
31 | 26 |
|
32 | 27 | server = http.createServer((req, res) => {
|
33 | 28 | serverImpl(req, res);
|
34 | 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 | + }); |
37 | 35 | });
|
38 | 36 |
|
39 | 37 | afterEach(done => {
|
40 | 38 | server.close(done);
|
41 | 39 | server = null;
|
42 | 40 | });
|
43 | 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 | + }); |
57 | 53 |
|
58 | 54 | // @gate experimental
|
59 |
| - it('can read text', async () => { |
| 55 | + it('can fetch json from a server component', async () => { |
60 | 56 | serverImpl = (req, res) => {
|
61 |
| - res.write('ok'); |
| 57 | + res.write(JSON.stringify({name: 'Sema'})); |
62 | 58 | res.end();
|
63 | 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(); |
72 | 62 | });
|
| 63 | + expect(json).toEqual({name: 'Sema'}); |
73 | 64 | });
|
74 | 65 |
|
75 | 66 | // @gate experimental
|
76 |
| - it('can read json', async () => { |
| 67 | + it('provides response status', async () => { |
77 | 68 | serverImpl = (req, res) => {
|
78 | 69 | res.write(JSON.stringify({name: 'Sema'}));
|
79 | 70 | res.end();
|
80 | 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, |
93 | 79 | });
|
94 | 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 | + }); |
95 | 121 | });
|
0 commit comments