use-swr-server.test.tsx


Overview

This file contains test cases designed to validate the behavior of the useSWR React hook in server-side rendering (SSR) environments, specifically targeting scenarios involving React versions less than or equal to 17 and SSR contexts. It focuses on ensuring that the useSWR hook correctly handles suspense mode without a fallback during SSR, by verifying that appropriate errors are thrown and caught.

The tests simulate a server environment by manipulating the global window object and leveraging Jest's module isolation features. It also utilizes React's Suspense and an ErrorBoundary from react-error-boundary to test the hook's error handling mechanisms during SSR.


Detailed Explanation

Imports


Function: withServer

async function withServer(runner: () => Promise<void>)

Purpose

A utility function to run a test case inside an isolated module environment using Jest's isolateModulesAsync. This ensures that module state does not leak between tests, which is critical for testing server-side rendering behaviors where modules may behave differently depending on environment globals.

Parameters

Usage Example

await withServer(async () => {
  // test logic inside isolated module environment
});

Return Value


Test Suite: 'useSWR - SSR'

This suite contains tests related to the useSWR hook's behavior during SSR.

beforeAll Hook

Sets up the global environment to simulate a server context by:

afterAll Hook

Cleans up after tests by removing the added Deno property from the global window object, restoring the environment.


Test Case: 'should enable the IS_SERVER flag - suspense on server without fallback'

This test validates that when useSWR is used with suspense mode enabled during SSR without providing a fallback, it triggers the expected error.

Test Flow

  1. Uses withServer to run the test in an isolated module environment.

  2. Mocks console.error to suppress error logs during the test.

  3. Dynamically imports useSWR from the swr package.

  4. Defines a unique key using Math.random().toString().

  5. Defines a React component Page that uses useSWR with suspense enabled.

  6. Renders the Page component wrapped in:

    • ErrorBoundary with a fallback renderer that logs errors and displays the error message.

    • Suspense to support suspense mode rendering.

  7. Asserts that the error message "Fallback data is required when using Suspense in SSR." is rendered, confirming that the hook correctly enforces fallback requirements in SSR suspense mode.

Key Implementation Details


Implementation Details and Algorithms


Interaction with Other System Components


Example Usage in Test

await withServer(async () => {
  const useSWR = (await import('swr')).default;
  const key = 'my-key';

  function Page() {
    const { data } = useSWR(key, () => 'data', { suspense: true });
    return <div>{data || 'empty'}</div>;
  }

  render(
    <ErrorBoundary fallbackRender={({ error }) => <div>{error.message}</div>}>
      <Suspense>
        <Page />
      </Suspense>
    </ErrorBoundary>
  );

  await screen.findByText('Fallback data is required when using Suspense in SSR.');
});

Visual Diagram

flowchart TD
    A[Start Test Suite: 'useSWR - SSR'] --> B[beforeAll: Mock Global Window Environment]
    B --> C[Run Test: 'should enable IS_SERVER flag']

    C --> D[withServer: isolateModulesAsync]
    D --> E[Import useSWR dynamically]
    E --> F[Define Page component using useSWR with suspense]
    F --> G[Render Page inside Suspense and ErrorBoundary]
    G --> H[ErrorBoundary catches error thrown by useSWR]
    H --> I[Assert error message "Fallback data is required..."]

    I --> J[afterAll: Clean up global environment]

Summary

This file is crucial for maintaining stable SSR support in the swr library, preventing common pitfalls when suspense mode is used incorrectly on the server side.