Skip to content

Commit b3d46e0

Browse files
authored
Rename testApp/test fixture configure to configureApp, add configureFusion (#5324)
* Rename testApp/test fixtures: configure -> configureApp, add configureFusion Renames the app-scope mock-configuration fixture from 'configure' to 'configureApp', for symmetry with the new 'configureFusion' fixture that composes with the parent framework mock (app manifest + navigation). Updates all cookbook and package consumers, docs (README, advanced.md, migrating-an-existing-app.md, module-mocks.md), and adds changesets. * Rename testApp/test fixture 'env' to 'appEnv', add mergeEnvConfig Renames the base env fixture to appEnv for symmetry with configureApp/ configureFusion, and exposes mergeEnvConfig (from the /test entry point) for overriding one endpoint or environment value on an AppEnv's AppConfig without dropping the rest of it -- a plain object spread over AppConfig copies nothing, since it stores environment/endpoints behind private fields exposed only through getters. * Address review: fix renderAppComponent option name, add configureFusion test - docs/advanced.md: the 'choose a rendering API' table row for renderAppComponent still said configureApp, but that imperative helper's own option was never renamed -- it's still configure. - testApp.test.tsx: add coverage for the configureFusion fixture, asserting a memory history pushed onto ahead of framework initialization is observable from a rendered component, proving configureFusion ran before the framework finished resolving.
1 parent 5013a1f commit b3d46e0

25 files changed

Lines changed: 460 additions & 159 deletions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@equinor/fusion-framework-cookbook-app-react-context": patch
3+
---
4+
5+
Internal: update the test suite for `@equinor/fusion-framework-vitest-plugin-react-app`'s `configure``configureApp` and `env``appEnv` fixture renames; no behavior changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@equinor/fusion-framework-cookbook-app-react-module": patch
3+
---
4+
5+
Internal: update the test suite for `@equinor/fusion-framework-vitest-plugin-react-app`'s `configure``configureApp` fixture rename; no behavior changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@equinor/fusion-framework-cookbook-app-react-msal": patch
3+
---
4+
5+
Internal: update the test suite for `@equinor/fusion-framework-vitest-plugin-react-app`'s `configure``configureApp` fixture rename; no behavior changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@equinor/fusion-framework-cookbook-app-react-router": patch
3+
---
4+
5+
Internal: update the test suite for `@equinor/fusion-framework-vitest-plugin-react-app`'s `configure``configureApp` fixture rename; no behavior changes.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
"@equinor/fusion-framework-vitest-plugin-react-app": major
3+
---
4+
5+
Rename the `testApp`/`test` fixtures for extending the mocked application and parent framework
6+
configuration: `configure` is now `configureApp`, the new `configureFramework` fixture
7+
introduced alongside it is now `configureFusion`, and `env` is now `appEnv`.
8+
9+
```diff
10+
-const test = testApp.extend('configure', { injected: true }, () => ...);
11+
+const test = testApp.extend('configureApp', { injected: true }, () => ...);
12+
13+
-test.override('fusion', async ({ env }) => ...);
14+
+test.override('fusion', async ({ appEnv }) => ...);
15+
```
16+
17+
`configureFusion` composes with the base parent-framework mock (app manifest and navigation) the same way `configureApp` composes with the base app-module mock — see [Advanced usage](docs/advanced.md#extend-the-parent-framework-mock-with-configurefusion) for extending framework-scope modules such as feature flags, service discovery, or navigation history.
18+
19+
Also adds `mergeEnvConfig`, a new utility exported from the `/test` entry point for overriding one endpoint's URL (or an `environment` value) on `appEnv` without dropping the rest of the app's `AppConfig` — a plain object spread over `AppConfig` copies nothing, since it stores `environment`/`endpoints` behind private fields exposed only through getters. See [Advanced usage](docs/advanced.md#fake-an-endpoint-url-with-mergeenvconfig).
20+
21+
```ts
22+
const test = baseTest.extend('appEnv', ({ appEnv }) =>
23+
mergeEnvConfig(appEnv, { endpoints: { 'cpr-api': { url: backendBaseUrl } } }),
24+
);
25+
```
26+

cookbooks/app-react-context/src/App.test.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const withSeededContext =
4343
enableContextMock(configurator, seed);
4444
};
4545

46-
// --- test setup: each variant seeds a different context scenario via the `configure` fixture ---
46+
// --- test setup: each variant seeds a different context scenario via the `configureApp` fixture ---
4747

4848
// --- tests ---
4949

@@ -59,7 +59,7 @@ test('renders the current and related context sections once the app configuratio
5959
});
6060

6161
describe('with an initial project', () => {
62-
test.override('configure', { injected: true }, () =>
62+
test.override('configureApp', { injected: true }, () =>
6363
withSeededContext((mock) => {
6464
mock.setCurrentContext(project);
6565
}),
@@ -75,7 +75,7 @@ describe('with an initial project', () => {
7575
});
7676

7777
describe('with related contexts', () => {
78-
test.override('configure', { injected: true }, () =>
78+
test.override('configureApp', { injected: true }, () =>
7979
withSeededContext((mock) => {
8080
// a realistic pool: related items are a different type than the current context, never the same
8181
mock.setContexts([project, facility, discipline]);
@@ -98,7 +98,7 @@ describe('with related contexts', () => {
9898
});
9999

100100
describe('when the app context changes', () => {
101-
test.override('configure', { injected: true }, () =>
101+
test.override('configureApp', { injected: true }, () =>
102102
withSeededContext((mock) => {
103103
mock.setContexts([project, facility]);
104104
mock.setCurrentContext(project);
@@ -129,14 +129,14 @@ describe('when the app context changes', () => {
129129

130130
describe('with a parent framework context', () => {
131131
// the app mirrors the parent's context, while its local mock pool resolves mirrored items without a network request
132-
test.override('configure', { injected: true }, () =>
132+
test.override('configureApp', { injected: true }, () =>
133133
withSeededContext((mock) => {
134134
mock.setContexts([project, facility]);
135135
}),
136136
);
137-
test.override('fusion', async ({ env }) =>
137+
test.override('fusion', async ({ appEnv }) =>
138138
mockFramework<[AppModule, ContextModule]>((configurator) => {
139-
enableAppManifestMock(configurator, env);
139+
enableAppManifestMock(configurator, appEnv);
140140
enableContextMock(configurator, (mock) => {
141141
mock.setContexts([project, facility]);
142142
mock.setCurrentContext(project);

cookbooks/app-react-module/src/App.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ test("renders the demo module's resolved foo/bar values", async ({ render }) =>
3333
});
3434

3535
describe('with an overridden demo configuration', () => {
36-
test.override('configure', { injected: true }, () => withDemoConfig('https://example.com', 7));
36+
test.override('configureApp', { injected: true }, () => withDemoConfig('https://example.com', 7));
3737

3838
test('renders the overridden foo/bar values instead of the app defaults', async ({ render }) => {
3939
const { getByText, unmount } = await render(<App />);

cookbooks/app-react-msal/src/App.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { App } from './App';
77
/**
88
* Sets a named mock account instead of the msal mock's default "Test User" —
99
* signed in before the msal provider initializes, so the provider's own
10-
* start-up path observes it. The cookbook registers no `configure` of its own,
10+
* start-up path observes it. The cookbook registers no `configureApp` of its own,
1111
* so this is the test's entire configuration, not a composition with one.
1212
*/
1313
const withMockAccount =
@@ -33,7 +33,7 @@ test('renders the default signed-in mock user once the app configuration has ini
3333
});
3434

3535
describe('with a configured account', () => {
36-
test.override('configure', { injected: true }, () =>
36+
test.override('configureApp', { injected: true }, () =>
3737
withMockAccount({ name: 'Ada Lovelace', username: 'ada@equinor.com' }),
3838
);
3939

cookbooks/app-react-router/src/__tests__/test-with-api-mock.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ import { apiMock } from '../mocks/api-mock';
2323
* });
2424
* ```
2525
*/
26-
export const testWithApiMock = baseTest.extend('configure', ({ configure }) => {
26+
export const testWithApiMock = baseTest.extend('configureApp', ({ configureApp }) => {
2727
const withApiMock: AppMockConfigureFn = (configurator, args) => {
28-
configure?.(configurator, args);
28+
configureApp?.(configurator, args);
2929
configurator.http.addMiddleware(createOpenApiMockMiddleware(apiMock));
3030
};
3131
return withApiMock;

packages/react/app/src/__tests__/testApp.test.tsx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { describe, expect } from 'vitest';
33
import { enableContextMock } from '@equinor/fusion-framework-module-context/mock';
44
import type { ContextItem } from '@equinor/fusion-framework-module-context';
55
import { useCurrentContext } from '@equinor/fusion-framework-react-app/context';
6+
import { useFramework } from '@equinor/fusion-framework-react';
7+
import { createHistory, enableNavigation } from '@equinor/fusion-framework-module-navigation';
8+
import type { NavigationModule } from '@equinor/fusion-framework-module-navigation';
69

710
import { testApp } from '@equinor/fusion-framework-vitest-plugin-react-app/test';
811

@@ -33,7 +36,7 @@ describe('testApp', () => {
3336

3437
describe('with a seeded context module', () => {
3538
const test = testApp.extend(
36-
'configure',
39+
'configureApp',
3740
{ injected: true },
3841
() => (configurator) =>
3942
enableContextMock(configurator, (mock) => mock.setCurrentContext(projectA)),
@@ -44,4 +47,30 @@ describe('testApp', () => {
4447
await expect.element(screen.getByText(projectA.title as string)).toBeVisible();
4548
});
4649
});
50+
51+
describe('with a configured parent framework', () => {
52+
const NavigationLocation = () => {
53+
const { navigation } = useFramework<[NavigationModule]>().modules;
54+
return <p>{navigation.history.location.pathname}</p>;
55+
};
56+
57+
// pushed on the history instance itself, before it's handed to the framework configurator,
58+
// so a passing assertion also proves `configureFusion` ran ahead of framework initialization
59+
const history = createHistory('memory');
60+
history.push('/configured-by-configure-fusion');
61+
62+
const test = testApp.extend(
63+
'configureFusion',
64+
{ injected: true },
65+
() => (configurator) =>
66+
enableNavigation(configurator, { configure: (config) => config.setHistory(history) }),
67+
);
68+
69+
test('resolves the fusion instance with the configured navigation history', async ({
70+
render,
71+
}) => {
72+
const screen = await render(<NavigationLocation />);
73+
await expect.element(screen.getByText('/configured-by-configure-fusion')).toBeVisible();
74+
});
75+
});
4776
});

0 commit comments

Comments
 (0)