Skip to content

Commit

Permalink
[wb1733.1.adddocsfixdocslinks] Add docs for new WB Testing and fix li…
Browse files Browse the repository at this point in the history
…nks (#2276)

## Summary:
This adds docs for the new `boundary` adapter and the new `renderHookStatic` call to the Wonder Blocks Testing package. It also updates the overview to explain some things about Wonder Blocks Testing Core.

In addition, I discovered that most of the intra-story links in MDX files were not working. After some investigation and discussion with @jandrade, it was determined that the markdown link format just doesn't currently work properly and that converting to `<a>` links with slightly changed href works as needed.

I used some regexp to convert from the markdown version to the markup version.

### 1. Markdown to markup
Find: `\[((?:[^\[\]])+)\]\((/docs/[^\)]+)\)`
Replace: `<a href="./?path=$2">$1</a>`

### 2. Add the missing leading `packages-` to the links
Seems that we reorganized the docs so that there's now a new top-level grouping that the URL needs to include when using the anchor approach.
Find: `<a href="./\?path=/docs/(?!packages)`
Replace: `<a href="./?path=/docs/packages-`

Issue: WB-1733

## Test plan:
`yarn start:storybook` and check the new docs and changed links are working

Author: somewhatabstract

Reviewers: somewhatabstract, jandrade

Required Reviewers:

Approved By: jandrade

Checks: ✅ codecov/project, ✅ Chromatic - Get results on regular PRs (ubuntu-latest, 20.x), ✅ Test (ubuntu-latest, 20.x, 2/2), ✅ Lint (ubuntu-latest, 20.x), ✅ Test (ubuntu-latest, 20.x, 1/2), ✅ Check build sizes (ubuntu-latest, 20.x), ✅ Chromatic - Build on regular PRs / chromatic (ubuntu-latest, 20.x), ✅ Publish npm snapshot (ubuntu-latest, 20.x), ⏭️  Chromatic - Skip on Release PR (changesets), ✅ Prime node_modules cache for primary configuration (ubuntu-latest, 20.x), ✅ gerald, ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ⏭️  dependabot

Pull Request URL: #2276
  • Loading branch information
somewhatabstract authored Jul 17, 2024
1 parent 4bebd48 commit f2e11af
Show file tree
Hide file tree
Showing 85 changed files with 171 additions and 531 deletions.
4 changes: 0 additions & 4 deletions __docs__/wonder-blocks-accordion/accessibility.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ import {
canvas: {hidden: true},
},
viewMode: "docs",
chromatic: {
// Disables chromatic testing for these stories.
disableSnapshot: true,
},
}}
/>

Expand Down
5 changes: 0 additions & 5 deletions __docs__/wonder-blocks-core/_overview_.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Core / Overview"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# Core
Expand Down
5 changes: 0 additions & 5 deletions __docs__/wonder-blocks-core/exports.use-force-update.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Core / Exports / useForceUpdate()"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# useForceUpdate()
Expand Down
5 changes: 0 additions & 5 deletions __docs__/wonder-blocks-core/exports.use-is-mounted.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Core / Exports / useIsMounted()"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# useIsMounted()
Expand Down
5 changes: 0 additions & 5 deletions __docs__/wonder-blocks-core/exports.use-latest-ref.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ import {color, spacing} from "@khanacademy/wonder-blocks-tokens";

<Meta
title="Packages / Core / Exports / useLatestRef()"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# useLatestRef()
Expand Down
5 changes: 0 additions & 5 deletions __docs__/wonder-blocks-core/exports.use-on-mount-effect.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Core / Exports / useOnMountEffect()"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# useOnMountEffect()
Expand Down
5 changes: 0 additions & 5 deletions __docs__/wonder-blocks-core/exports.use-online.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Core / Exports / useOnline()"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# useOnline()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Core / Exports / usePreHydrationEffect()"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# usePreHydrationEffect()
Expand Down
5 changes: 0 additions & 5 deletions __docs__/wonder-blocks-core/exports.use-render-state.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Core / Exports / useRenderState()"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# useRenderState()
Expand Down
11 changes: 3 additions & 8 deletions __docs__/wonder-blocks-data/_overview_.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,12 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Data / Overview"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# Wonder Blocks Data

Wonder Blocks Data provides components, hooks, and additional APIs to make working with asynchronous requests easier, both client-side and server-side.

- [GraphQL](/docs/data-graphql--page)
- [Server-Side Rendering and Hydration](/docs/data-server-side-rendering-and-hydration--page)
- [Testing](/docs/data-testing--page)
- <a href="./?path=/docs/packages-data-graphql--docs">GraphQL</a>
- <a href="./?path=/docs/packages-data-server-side-rendering-and-hydration--docs">Server-Side Rendering and Hydration</a>
- <a href="./?path=/docs/packages-data-testing--docs">Testing</a>
15 changes: 5 additions & 10 deletions __docs__/wonder-blocks-data/_overview_graphql.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,17 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Data / GraphQL"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# GraphQL in Wonder Blocks Data

Wonder Blocks Data provides some utility types and functionality to assist in performing GraphQL requests. To use them, your React app should include the [`GqlRouter`](/docs/data-exports-gqlrouter--page) component to specify the method responsible for actually making the GraphQL requests, as well as any default context that requests should include.
Wonder Blocks Data provides some utility types and functionality to assist in performing GraphQL requests. To use them, your React app should include the <a href="./?path=/docs/packages-data-exports-gqlrouter--docs">`GqlRouter`</a> component to specify the method responsible for actually making the GraphQL requests, as well as any default context that requests should include.

The [`GqlRouter`](/docs/data-exports-gqlrouter--page) component uses React context to convey this information to the [`useGql`](/docs/data-exports-usegql--page) hook, which provides a wrapper to the fetch function, allowing for simplified invocation of requests that can merge context changes with the default context as well as only provide context and variables when needed.
The <a href="./?path=/docs/packages-data-exports-gqlrouter--docs">`GqlRouter`</a> component uses React context to convey this information to the <a href="./?path=/docs/packages-data-exports-usegql--docs">`useGql`</a> hook, which provides a wrapper to the fetch function, allowing for simplified invocation of requests that can merge context changes with the default context as well as only provide context and variables when needed.

## Testing

By using the [`GqlRouter`](/docs/data-exports-gqlrouter--page) in combination with the [`mockGqlFetch()`](/docs/testing-exports-mockgqlfetch) API from Wonder Blocks Testing, you can easily mock your GraphQL responses in tests and stories.
By using the <a href="./?path=/docs/packages-data-exports-gqlrouter--docs">`GqlRouter`</a> in combination with the <a href="./?path=/docs/packages-testing-exports-mockgqlfetch">`mockGqlFetch()`</a> API from Wonder Blocks Testing, you can easily mock your GraphQL responses in tests and stories.

```tsx
const mockFetch = mockGqlFetch()
Expand All @@ -30,6 +25,6 @@ const mockFetch = mockGqlFetch()

## Server-side rendering and hydration of GraphQL

Server-side rendering and hydration of GraphQL data can be achieved by combining the [`useGql`](/docs/data-exports-usegql--page) hook with the [`useHydrationEffect`](/docs/data-exports/usehydrationeffect--page) hook.
Server-side rendering and hydration of GraphQL data can be achieved by combining the <a href="./?path=/docs/packages-data-exports-usegql--docs">`useGql`</a> hook with the <a href="./?path=/docs/packages-data-exports/usehydrationeffect--docs">`useHydrationEffect`</a> hook.

More details about server-side rendering with Wonder Blocks Data can be found in the [relevant overview section](/docs/data-server-side-rendering-and-hydration--page).
More details about server-side rendering with Wonder Blocks Data can be found in the <a href="./?path=/docs/packages-data-server-side-rendering-and-hydration--docs">relevant overview section</a>.
19 changes: 7 additions & 12 deletions __docs__/wonder-blocks-data/_overview_ssr_.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,22 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Data / Server-side Rendering and Hydration"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# Server-side Rendering (SSR)

Wonder Blocks Data provides components, hooks, and additional APIs to make server-side rendering and hydration of asynchronous requests easier.

The [`Data`](/docs/data-exports-data--page) component and the [`useHydratableEffect`](/docs/data-exports-usehydratableeffect--page) hook (which [`Data`](/docs/data-exports-data--page) uses internally) both
The <a href="./?path=/docs/packages-data-exports-data--docs">`Data`</a> component and the <a href="./?path=/docs/packages-data-exports-usehydratableeffect--docs">`useHydratableEffect`</a> hook (which <a href="./?path=/docs/packages-data-exports-data--docs">`Data`</a> uses internally) both
support server-side rendering and hydration.

These APIs have been designed to make it easy for everyday development. The developer does not need to consider the server-side process nor hydration when requiring asynchronous data. Instead, they use [`Data`](/docs/data-exports-data--page) or [`useHydratableEffect`](/docs/data-exports-usehydratableeffect--page) to get the data they need.
These APIs have been designed to make it easy for everyday development. The developer does not need to consider the server-side process nor hydration when requiring asynchronous data. Instead, they use <a href="./?path=/docs/packages-data-exports-data--docs">`Data`</a> or <a href="./?path=/docs/packages-data-exports-usehydratableeffect--docs">`useHydratableEffect`</a> to get the data they need.

## Integrating into server-side rendering

Generally, server-side rendering has a loop that renders the page, determines what asynchronous activity needs to be resolved, resolves and caches that activity, then renders again, ensuring that as much of the page as possible has been rendered.

In order for the requests made through [`Data`](/docs/data-exports-data--page) and [`useHydratableEffect`](/docs/data-exports-usehydratableeffect--page) use to be fulfilled on the server and subsequently hydrated on the client, the server responsible for rendering the page must be modified to track and capture the requests and their responses.
In order for the requests made through <a href="./?path=/docs/packages-data-exports-data--docs">`Data`</a> and <a href="./?path=/docs/packages-data-exports-usehydratableeffect--docs">`useHydratableEffect`</a> use to be fulfilled on the server and subsequently hydrated on the client, the server responsible for rendering the page must be modified to track and capture the requests and their responses.

First, Wonder Blocks Data has to be told to work in server-side mode:

Expand All @@ -36,13 +31,13 @@ By setting Wonder Blocks into server mode, requests will not be fulfilled during

### Tracking and fulfilling requests

To track the requests, the React node being rendered must be wrapped in the [`TrackData`](/docs/data-exports-trackdata--page) component.
To track the requests, the React node being rendered must be wrapped in the <a href="./?path=/docs/packages-data-exports-trackdata--docs">`TrackData`</a> component.

```tsx
const trackedElement = <TrackData>{theNodeTheClientNormallyRenders}</TrackData>;
```

The [`TrackData`](/docs/data-exports-trackdata--page) component is responsible for capturing the requests that were made during a render of the given React node. Of course to do that, we have to render the node. Rendering is usually performed by `renderToString` from the `react-dom/server` import.
The <a href="./?path=/docs/packages-data-exports-trackdata--docs">`TrackData`</a> component is responsible for capturing the requests that were made during a render of the given React node. Of course to do that, we have to render the node. Rendering is usually performed by `renderToString` from the `react-dom/server` import.

```ts
import {renderToString} from "react-dom/server";
Expand All @@ -52,7 +47,7 @@ renderToString(trackedElement);

After each render, we want to see if there are any tracked requests needing to be fulfilled. If there are, we will want to fulfill them and render again; if there are not, we are ready to finish the page rendering and move on.

To determine which path to take, we can use [`hasTrackedRequestsToBeFetched`](/docs/data-exports-hastrackedrequeststobefetched--page), and then based off that result, either fulfill the requests, or finish rendering our page.
To determine which path to take, we can use <a href="./?path=/docs/packages-data-exports-hastrackedrequeststobefetched--docs">`hasTrackedRequestsToBeFetched`</a>, and then based off that result, either fulfill the requests, or finish rendering our page.

```ts
if (hasTrackedRequestsToBeFetched()) {
Expand Down Expand Up @@ -177,4 +172,4 @@ React.hydrate(
);
```

That's it! The client-side hydration is complete. Underneath the hood, the hydration cache is used to hydrate the responses that the server used to render the page. And if you render a page that was not server-side rendered, the [`Data`](/docs/data-exports-data--page) and [`useHydratableEffect`](/docs/data-exports-usehydratableeffect--page) know exactly what to do and will make the requests client-side instead.
That's it! The client-side hydration is complete. Underneath the hood, the hydration cache is used to hydrate the responses that the server used to render the page. And if you render a page that was not server-side rendered, the <a href="./?path=/docs/packages-data-exports-data--docs">`Data`</a> and <a href="./?path=/docs/packages-data-exports-usehydratableeffect--docs">`useHydratableEffect`</a> know exactly what to do and will make the requests client-side instead.
19 changes: 7 additions & 12 deletions __docs__/wonder-blocks-data/_overview_testing_.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Data / Testing"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# Testing Support
Expand All @@ -15,21 +10,21 @@ Wonder Blocks Data has been designed to support testing in a variety of environm

## Spies

If you are writing unit tests, you may just want to spy on the methods you are calling using `jest.spyOn` or similar. This can be a really easy way to intercept the request handler passed to the [`useCachedEffect`](/docs/data-exports-usecachedeffect--page) hook, for example, and check that it is the handler you expect.
If you are writing unit tests, you may just want to spy on the methods you are calling using `jest.spyOn` or similar. This can be a really easy way to intercept the request handler passed to the <a href="./?path=/docs/packages-data-exports-usecachedeffect--docs">`useCachedEffect`</a> hook, for example, and check that it is the handler you expect.

## Interceptors

Each request used by Wonder Blocks Data has to have an identifier. The [`InterceptRequests`](/docs/data-exports-interceptrequests--page) component allows you to wrap the code under test with an interceptor. Interceptors are given the request identifier and get to choose, based off that identifier, if they want to provide their own response rather than let the original request handler deal with it.
Each request used by Wonder Blocks Data has to have an identifier. The <a href="./?path=/docs/packages-data-exports-interceptrequests--docs">`InterceptRequests`</a> component allows you to wrap the code under test with an interceptor. Interceptors are given the request identifier and get to choose, based off that identifier, if they want to provide their own response rather than let the original request handler deal with it.

Multiple interceptors can be registered by nesting the [`InterceptRequests`](/docs/data-exports-interceptrequests--page) component as is necessary. Registered interceptors are invoked in ancestral order, with the nearest ancestor to the intercepted request being invoked first.
Multiple interceptors can be registered by nesting the <a href="./?path=/docs/packages-data-exports-interceptrequests--docs">`InterceptRequests`</a> component as is necessary. Registered interceptors are invoked in ancestral order, with the nearest ancestor to the intercepted request being invoked first.

When hooks like [`useServerEffect`](/docs/data-exports-useservereffect--page), [`useCachedEffect`](/docs/data-exports-usecachedeffect--page), or [`useHydratedEffect`](/docs/data-exports-usehydratedeffect--page) run, they get the chain of registered interceptors and chain those with the original handler in order to determine what to actually do when executing the request.
When hooks like <a href="./?path=/docs/packages-data-exports-useservereffect--docs">`useServerEffect`</a>, <a href="./?path=/docs/packages-data-exports-usecachedeffect--docs">`useCachedEffect`</a>, or <a href="./?path=/docs/packages-data-exports-usehydratedeffect--docs">`useHydratedEffect`</a> run, they get the chain of registered interceptors and chain those with the original handler in order to determine what to actually do when executing the request.

This allows you to mock out requests in unit tests, stories, and other scenarios.

## GqlRouter, mockGqlFetch, and RespondWith

If you are testing GraphQL operations, you can configure [`GqlRouter`](/docs/data-exports-gqlrouter--page) with your own function for the `fetch` prop. However, crafting the right response to give
If you are testing GraphQL operations, you can configure <a href="./?path=/docs/packages-data-exports-gqlrouter--docs">`GqlRouter`</a> with your own function for the `fetch` prop. However, crafting the right response to give
the result you want is a bit tricky.

```tsx
Expand Down Expand Up @@ -65,7 +60,7 @@ const myFakeGqlFetch = (
</GqlRouter>
```

As shown above, you can interrogate parts of the requested operation to decide how to respond. However, this can get cumbersome if you have GraphQL requests nested in more complex components as each test has to mock out suitable responses for each one. To help with this the Wonder Blocks Testing package provides a [`RespondWith`](/docs/testing-exports-respondwith--page) type for defining responses that fit a specific scenario, and the [`mockGqlFetch()`](/docs/testing-exports-mockgqlfetch--page) API.
As shown above, you can interrogate parts of the requested operation to decide how to respond. However, this can get cumbersome if you have GraphQL requests nested in more complex components as each test has to mock out suitable responses for each one. To help with this the Wonder Blocks Testing package provides a <a href="./?path=/docs/packages-testing-exports-respondwith--docs">`RespondWith`</a> type for defining responses that fit a specific scenario, and the <a href="./?path=/docs/packages-testing-exports-mockgqlfetch--docs">`mockGqlFetch()`</a> API.

```tsx
const myFakeGqlFetch = mockGqlFetch().mockOperationOnce(
Expand Down Expand Up @@ -119,4 +114,4 @@ const myFakeGqlFetch = mockMyQuery(mockGqlFetch());

Now, using a compose function, multiple mocks can be setup on the same `mockGqlFetch` instance.

For more details on this and other testing utilities, see the [Wonder Blocks Testing documentation](/docs/testing-overview--page).
For more details on this and other testing utilities, see the <a href="./?path=/docs/packages-testing-overview--docs">Wonder Blocks Testing documentation</a>.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Data / Exports / abortInflightRequests()"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# abortInflightRequests()
Expand All @@ -15,6 +10,6 @@ import {Meta} from "@storybook/blocks";
abortInflightRequests(): void;
```

Aborts all inflight requests that were started via [`useCachedEffect`](/docs/data-exports-usecachedeffect--page), [`useHydratableEffect`](/docs/data-exports-usehydratableeffect--page), or [`fetchTrackedRequests()`](/docs/data-exports-fetchtrackedrequests--page).
Aborts all inflight requests that were started via <a href="./?path=/docs/packages-data-exports-usecachedeffect--docs">`useCachedEffect`</a>, <a href="./?path=/docs/packages-data-exports-usehydratableeffect--docs">`useHydratableEffect`</a>, or <a href="./?path=/docs/packages-data-exports-fetchtrackedrequests--docs">`fetchTrackedRequests()`</a>.

NOTE: Full abort signalling is not currently implemented. The effect of this call is to remove any inflight requests from our inflight request tracking such that a new matching request will cause a new fetch to occur rather than sharing any existing one.
7 changes: 1 addition & 6 deletions __docs__/wonder-blocks-data/exports.data-error.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Data / Exports / DataError"
parameters={{
chromatic: {
disableSnapshot: true,
},
}}
/>

# DataError
Expand All @@ -19,4 +14,4 @@ new DataError(
);
```

The `DataError` class is a derivation of the Wonder Blocks Core `KindError` (which is itself a derivation of `Error`). It is used by the Wonder Blocks Data framework to encapsulate errors that can occur when using its API. The different kinds of errors supported are defined by the [`DataErrors`](/docs/data-exports-dataerrors--page) export.
The `DataError` class is a derivation of the Wonder Blocks Core `KindError` (which is itself a derivation of `Error`). It is used by the Wonder Blocks Data framework to encapsulate errors that can occur when using its API. The different kinds of errors supported are defined by the <a href="./?path=/docs/packages-data-exports-dataerrors--docs">`DataErrors`</a> export.
Loading

0 comments on commit f2e11af

Please sign in to comment.