agentleFS
equinorequinor/fusion-skills/skills/.experimental/fusion-framework-mocking/SKILL.md

fusion-framework-mocking

Skill2 starsChanged 2 months agoMITView on GitHub

Guides seeding deterministic Fusion Framework module state in tests — mockFramework, mockAppModules, and module-owned enableXMock helpers (msal, service-discovery, context, bookmark, feature-flag, analytics, telemetry, http, app) — while keeping each module''s real configurator, provider, validation, and lifecycle. USE FOR: signing in a mock user, seeding context/bookmarks/feature-flags, faking HTTP/OpenAPI responses, choosing a mock boundary, adding a mock for a custom module. DO NOT USE FOR: configuring vitest.config.ts, rendering React components/hooks, or Vitest Browser Mode setup (use fusion-framework-testing); dev-server-time API mocking/proxying in dev-server.config.ts (use fusion-developer-app); backend/service-repo mocking.

The file

We split this skill into the rules it gives an agent

10 rules. About 0 are common, 2 are distinctive, and 8 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 8

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use when a test needs deterministic Fusion Framework module state — a signed-in user, a current context, seeded feature flags/bookmarks, or …

    line 29
  2. Very specific:

    Test scope: parent framework (mockFramework), an app's own modules (mockAppModules), or a bespoke module graph (a module's own enable*Mock)

    line 58
  3. Very specific:

    Read references/framework-and-app-mocks.md for the design rules before writing a mock:

    line 69
  4. Very specific:

    Only the client (the object doing network I/O) is substituted.

    line 71
  5. Very specific:

    Use references/module-mocks.md for the full per-module table (auth, service discovery, context, bookmark, feature flag, analytics, …

    line 105
  6. Very specific:

    Use references/http-and-openapi-mocks.md to choose between a hand-written configurator.http.addMiddleware(...), createRouterMiddleware for …

    line 111
  7. Very specific:

    Use references/custom-module-mocks.md when the module under test is not one of the built-ins — covers the client seam (setClient), …

    line 119
  8. Very specific:

    Test code that seeds Fusion module state through the correct /mock entry point

    line 132
  9. Very specific:

    Treat an unsigned mock JWT (createMockToken/MSAL mock output) as valid outside a test

    line 141
  10. Distinctive:

    Prefer the smallest mock boundary that still exercises the behavior under test

    line 146

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Fusion Framework Mocking

When to use

Use when a test needs deterministic Fusion Framework module state — a signed-in user, a current context, seeded feature flags/bookmarks, or faked HTTP responses — without a real Entra ID tenant, service registry, or backend.

Typical triggers:

  • "How do I mock useAccessToken / sign in a test user?"
  • "Seed a current context for this test"
  • "Fake this HTTP endpoint's response"
  • "Mock service discovery so the app doesn't hit the network"
  • "Add a mock for my own module"
  • "Test signed-out / login / logout behavior"
  • "Assert a middleware was called"

Implicit triggers:

  • A test imports mockFramework, mockAppModules, or any @equinor/fusion-framework-module-*/mock entry point
  • A test needs the app to boot without real credentials or a running backend
  • Writing or reviewing a *.mock.ts/mock-configurator file for a Fusion module

When not to use

  • Rendering a component/hook or configuring Vitest/Browser Mode — use fusion-framework-testing
  • dev-server.config.ts API mocking/proxying for local ffc app dev — that is dev-time only, unrelated to test-time module mocks; see fusion-developer-app
  • Asserting on one specific call (arguments, call count, reset) — that is the test runner's job (vi.spyOn, vi.fn); this skill only covers seeding module state
  • Backend/service-repo test doubles (different repo, different stack)

Required inputs

Mandatory

  • Which boundary needs faking: auth, service discovery, context, bookmarks, feature flags, HTTP, analytics, telemetry, app manifest, or a custom module
  • Test scope: parent framework (mockFramework), an app's own modules (mockAppModules), or a bespoke module graph (a module's own enable*Mock)

Conditional

  • Signed-in user details (name, username, specific token claims) when auth matters
  • Whether the test must stay fully offline (every expected request needs an answering middleware)
  • Whether an OpenAPI document already describes the API under test

Instructions

Step 1 — Understand the mocking design

Read references/framework-and-app-mocks.md for the design rules before writing a mock:

  • Only the client (the object doing network I/O) is substituted. Providers, configurators, schema validation, and module initialize all run for real — a test still catches wiring mistakes.
  • Mocks live beside the module they replace, at that module's own /mock entry point. @equinor/fusion-framework/mock only composes the built-in set; it contains no mock logic of its own.
  • There is no Fusion mocking API for individual calls. Mock clients are plain classes with ordinary methods — use vi.spyOn, bun:test's spyOn, or Node's t.mock.method directly.

Step 2 — Pick the right layer

Test scopeUseImport
Parent framework / portal-level modules togethermockFramework@equinor/fusion-framework/mock
An app's own modules (no React)mockAppModules@equinor/fusion-framework-app/mock
One module in a bespoke module graphthat module's enable*Mock@equinor/fusion-framework-module-*/mock
React hooks/components consuming app modulesrender helpers (out of scope here)see fusion-framework-testing
import { mockFramework } from '@equinor/fusion-framework/mock';

const fusion = await mockFramework((configurator) => {
  configurator.msal.setAccount({ name: 'Ada Lovelace' });
  configurator.context.setCurrentContext({ id: 'project-a', type: { id: 'ProjectMaster' }, value: {} });
  configurator.serviceDiscovery.addService({ key: 'catalog' });
});

mockFramework initializes every module FrameworkConfigurator declares (event, auth, http, serviceDiscovery, context, telemetry) with zero configuration — a default signed-in Test User and offline service resolution out of the box.

Step 3 — Seed the module the test needs

Use references/module-mocks.md for the full per-module table (auth, service discovery, context, bookmark, feature flag, analytics, telemetry, app manifest) with defaults, builder methods, and signed-out/token-exact recipes.

Step 4 — Fake HTTP responses

Use references/http-and-openapi-mocks.md to choose between a hand-written configurator.http.addMiddleware(...), createRouterMiddleware for several routes, or createOpenApiMockMiddleware (backed by @equinor/fusion-openapi-mock) for a whole OpenAPI document. An unmatched request always falls through to next(uri, init) and eventually the real network — a fully offline test must answer every request it expects.

Step 5 — Add a mock for a custom module (when needed)

Use references/custom-module-mocks.md when the module under test is not one of the built-ins — covers the client seam (setClient), builder-owned configuration, and exposing a configurator.<yourModule> accessor via FrameworkMockConfigurator's _pin/_getConfig.

Step 6 — Verify

  • The mocked boundary is the client only — configurator/provider/validation are real
  • Determinism: tokens and resolved services are identical across runs (no Date.now()-derived assertions without seeding)
  • Every expected HTTP request has an answering middleware, or the test intentionally allows fallthrough
  • Call-level assertions use the test runner's own spy tooling, not an invented Fusion API

Expected output

  • Test code that seeds Fusion module state through the correct /mock entry point
  • A stated choice of layer (mockFramework / mockAppModules / module enable*Mock) and why
  • HTTP faking strategy chosen (hand-written middleware, router, or OpenAPI) and its offline guarantees
  • Any custom-module mock wiring, if applicable

Safety & constraints

Never:

  • Invent a Fusion-specific mocking API for individual call assertions — that is the test runner's job
  • Treat an unsigned mock JWT (createMockToken/MSAL mock output) as valid outside a test
  • Replace a module's provider or configurator wholesale when only its client needs faking
  • Assume setResolveUnknownServices(false) is safe without declaring every service the framework itself resolves at start-up (e.g. context)

Always:

  • Prefer the smallest mock boundary that still exercises the behavior under test
  • Cite the real package/export used (e.g. enableContextMock from @equinor/fusion-framework-module-context/mock) rather than inventing one
  • Note when a test intentionally allows network fallthrough vs. when it must stay fully offline

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.