> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fanfare.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Testing Your Integration

> Test public journey states, callbacks, and customization without depending on private internals.

Test your integration from the public contract:

* The right UI renders for each public journey state.
* Buttons call the actions exposed by the current `JourneyView`.
* Gates show generic, customer-safe messaging.
* A granted handoff sends the consumer to the next app step.
* Sensitive runtime values are not sent to third-party logs.

<img src="https://mintcdn.com/fanfare/oKzL5u1gWepNCXYO/images/sdk/testing-workflow.webp?fit=max&auto=format&n=oKzL5u1gWepNCXYO&q=85&s=6afb0a4e133ea2e0d7637a46d55014db" alt="SDK testing workflow showing setup, simulated public states, rendered behavior verification, and full-flow release testing." width="1774" height="887" data-path="images/sdk/testing-workflow.webp" />

## Recommended coverage

| Scenario                     | What to verify                                                                                                                                |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| Ready                        | Start CTA appears and calls `start()`.                                                                                                        |
| Routing                      | Loading state appears without offering invalid actions.                                                                                       |
| Gated auth                   | Auth UI completes, then reroutes.                                                                                                             |
| Gated access code            | Code submission calls `reroute({ accessCode })`.                                                                                              |
| Routed upgrade offer         | `submitAccessCode(code)` returns `advanced` (moves to the offered sequence), `unchanged` (no offer matched), or `gated` (gate UI takes over). |
| Reroute / downgrade          | A downgrade emits a `reroute` event with severity `"warning"` and message `"Sequence downgraded"`.                                            |
| Scheduled                    | Timing renders without invalid actions.                                                                                                       |
| Enterable                    | Enter, bid, or booking action is available for the mechanism.                                                                                 |
| Participating                | Participation status renders and valid actions are available.                                                                                 |
| Settling (draw/auction only) | Pending-result copy renders without actions.                                                                                                  |
| Granted                      | Checkout handoff runs and does not leak the grant.                                                                                            |
| Ended                        | Outcome copy is clear and generic.                                                                                                            |
| Error                        | Retry or support path is visible.                                                                                                             |

## Run against the public harness

The `@fanfare-io/fanfare-sdk-core/harness` subpath ships an in-browser, fetch-intercepting mock of the Fanfare consumer API. It lets you run and verify a real integration end to end without a live Fanfare environment: queue positions count down per poll, draws resolve, and gates accept the test OTP and access codes.

```ts theme={null}
import { useEffect, useState } from "react";
import initFanfare from "@fanfare-io/fanfare-sdk-core";
import { installHarnessMockServer } from "@fanfare-io/fanfare-sdk-core/harness";

function useHarnessSdk() {
  const [sdk, setSdk] = useState<Awaited<ReturnType<typeof initFanfare>> | null>(null);

  useEffect(() => {
    const harness = installHarnessMockServer({ scenario: "queue" });

    let active = true;
    void initFanfare({
      organizationId: "org_demo",
      publishableKey: "pk_test_demo",
      environment: "development",
      apiUrl: harness.apiBaseUrl,
    }).then((instance) => {
      if (active) setSdk(instance);
    });

    return () => {
      active = false;
      harness.stop();
    };
  }, []);

  return sdk;
}
```

`installHarnessMockServer(options?)` returns:

| Property        | Purpose                                                              |
| --------------- | -------------------------------------------------------------------- |
| `apiBaseUrl`    | Point the SDK's `apiUrl` at this value.                              |
| `stop()`        | Removes the `window.fetch` interception. Call it on teardown.        |
| `getRequests()` | Returns the recorded `api` and `beacon` request logs for assertions. |

<Note>
  The harness intercepts `window.fetch`, so it is browser-only. Install it from a client effect, never during SSR. Pair it with `environment: "development"` and point `apiUrl` at the returned `apiBaseUrl`.
</Note>

Choose a scenario with the `scenario` option (or install several with `scenarios`). The available `HarnessScenarioKey` values are:

* `"queue"`, `"auth-queue"`, `"access-code-queue"`, `"admission-cycle"`, `"queue-denied"`
* `"waitlist-queue"`, `"waitlist-lifecycle"`
* `"upgrade-offer-queue"`, `"upgrade-offer-multi-queue"`
* `"draw"`, `"auth-draw"`, `"draw-denied"`
* `"timed-release"`, `"timed-release-completion"`
* `"appointment"`
* `"auction"`

Auth-gated scenarios accept the default test OTP code `"424242"` (overridable via the `otpCode` option). Access-code scenarios accept `"VIP123"`; the multi-tier upgrade scenario additionally accepts `"SUPER123"`.

## Component integration tests

For React custom UI, wrap your Fanfare usage behind a small app-level component boundary so tests can provide controlled journey states.

```tsx theme={null}
export function LaunchExperience({ experienceId }: { experienceId: string }) {
  const { view, start, error } = useExperienceJourney(experienceId);

  return <LaunchExperienceView view={view} start={start} error={error} />;
}
```

Test `LaunchExperienceView` with representative `JourneyView` values (one per `journeyStage`, and per `sequence.phase` for routed). Keep SDK network behavior in a smaller number of integration tests.

## Manual QA checklist

* Start from a clean browser profile.
* Repeat with an existing session.
* Open the same experience in two tabs.
* Verify loading, gated, participating, granted, ended, and error copy.
* Confirm checkout receives only the values it needs.
* Confirm analytics use high-level outcomes rather than raw grants or snapshots.
