From 1769f4bc3f4a0b705d70747f1c8129685f5222a5 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Mon, 6 Feb 2023 14:17:00 -0500 Subject: [PATCH] Add test for the actual AsyncLocalStorage behavior --- .../src/__tests__/ReactFetchEdge-test.js | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 packages/react/src/__tests__/ReactFetchEdge-test.js diff --git a/packages/react/src/__tests__/ReactFetchEdge-test.js b/packages/react/src/__tests__/ReactFetchEdge-test.js new file mode 100644 index 0000000000000..10484b853bf50 --- /dev/null +++ b/packages/react/src/__tests__/ReactFetchEdge-test.js @@ -0,0 +1,80 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @emails react-core + */ + +'use strict'; + +// Polyfills for test environment +global.ReadableStream = + require('web-streams-polyfill/ponyfill/es6').ReadableStream; +global.TextEncoder = require('util').TextEncoder; +global.TextDecoder = require('util').TextDecoder; +global.Headers = require('node-fetch').Headers; +global.Request = require('node-fetch').Request; +global.Response = require('node-fetch').Response; +// Patch for Edge environments for global scope +global.AsyncLocalStorage = require('async_hooks').AsyncLocalStorage; + +let fetchCount = 0; +async function fetchMock(resource, options) { + fetchCount++; + const request = new Request(resource, options); + return new Response( + request.method + + ' ' + + request.url + + ' ' + + JSON.stringify(Array.from(request.headers.entries())), + ); +} + +let React; +let ReactServerDOMServer; +let ReactServerDOMClient; +let use; + +describe('ReactFetch', () => { + beforeEach(() => { + jest.resetModules(); + fetchCount = 0; + global.fetch = fetchMock; + + if (gate(flags => !flags.www)) { + jest.mock('react', () => require('react/react.shared-subset')); + } + + React = require('react'); + ReactServerDOMServer = require('react-server-dom-webpack/server.edge'); + ReactServerDOMClient = require('react-server-dom-webpack/client'); + use = React.use; + }); + + async function render(Component) { + const stream = ReactServerDOMServer.renderToReadableStream(); + return ReactServerDOMClient.createFromReadableStream(stream); + } + + // @gate enableFetchInstrumentation && enableCache + it('can dedupe fetches separately in interleaved renders', async () => { + async function getData() { + const r1 = await fetch('hi'); + const t1 = await r1.text(); + const r2 = await fetch('hi'); + const t2 = await r2.text(); + return t1 + ' ' + t2; + } + function Component() { + return use(getData()); + } + const render1 = render(Component); + const render2 = render(Component); + expect(await render1).toMatchInlineSnapshot(`"GET hi [] GET hi []"`); + expect(await render2).toMatchInlineSnapshot(`"GET hi [] GET hi []"`); + expect(fetchCount).toBe(2); + }); +});