@equinor/fusion-framework-vitest-plugin-react-app 0.2.0-next.3 → 1.0.0-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +9 -6
- package/dist/esm/app-test.js +1 -0
- package/dist/esm/app-test.js.map +1 -1
- package/dist/esm/merge-env-config.js +37 -0
- package/dist/esm/merge-env-config.js.map +1 -0
- package/dist/esm/resolve-app-test-env.js +5 -5
- package/dist/esm/scope/resolve-app-scope.js +1 -1
- package/dist/esm/scope/resolve-app-scope.js.map +1 -1
- package/dist/esm/scope/resolve-fusion.js +15 -4
- package/dist/esm/scope/resolve-fusion.js.map +1 -1
- package/dist/esm/test-app.js +39 -6
- package/dist/esm/test-app.js.map +1 -1
- package/dist/esm/test.js +12 -5
- package/dist/esm/test.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/app-test.d.ts +1 -0
- package/dist/types/merge-env-config.d.ts +33 -0
- package/dist/types/resolve-app-test-env.d.ts +5 -5
- package/dist/types/scope/resolve-fusion.d.ts +13 -3
- package/dist/types/test-app.d.ts +44 -11
- package/dist/types/test.d.ts +25 -14
- package/dist/types/version.d.ts +1 -1
- package/docs/advanced.md +76 -12
- package/docs/migrating-an-existing-app.md +9 -9
- package/docs/module-mocks.md +2 -2
- package/package.json +5 -4
- package/src/__tests__/merge-env-config.test.ts +67 -0
- package/src/app-test.ts +1 -0
- package/src/merge-env-config.ts +58 -0
- package/src/resolve-app-test-env.ts +5 -5
- package/src/scope/resolve-app-scope.ts +1 -1
- package/src/scope/resolve-fusion.ts +21 -10
- package/src/test-app.tsx +49 -7
- package/src/test.tsx +12 -5
- package/src/version.ts +1 -1
- package/tsconfig.json +1 -0
package/dist/types/app-test.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { renderAppHook, type RenderAppHookOptions, type RenderAppHookResult, } from './render-app-hook';
|
|
2
2
|
export { renderAppComponent, type RenderAppComponentOptions, type RenderAppComponentResult, } from './render-app-component';
|
|
3
3
|
export { testApp } from './test-app';
|
|
4
|
+
export { mergeEnvConfig, type MergeEnvConfigOverrides } from './merge-env-config.js';
|
|
4
5
|
export type { AppMockConfigureFn } from '@equinor/fusion-framework-app/mock';
|
|
5
6
|
export { test } from './test';
|
|
6
7
|
export { render } from './render';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { AppConfig } from '@equinor/fusion-framework-module-app';
|
|
2
|
+
import type { ConfigEnvironment } from '@equinor/fusion-framework-module-app';
|
|
3
|
+
import type { AppEnv } from '@equinor/fusion-framework-app';
|
|
4
|
+
type EndpointOverride = Partial<NonNullable<AppEnv['config']>['endpoints'][string]>;
|
|
5
|
+
/**
|
|
6
|
+
* Overrides accepted by {@link mergeEnvConfig}.
|
|
7
|
+
*/
|
|
8
|
+
export type MergeEnvConfigOverrides<TConfig extends ConfigEnvironment = ConfigEnvironment> = {
|
|
9
|
+
environment?: Partial<TConfig>;
|
|
10
|
+
endpoints?: Record<string, EndpointOverride>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Merges `environment`/`endpoints` overrides into an `AppEnv`'s `config`.
|
|
14
|
+
*
|
|
15
|
+
* @remarks
|
|
16
|
+
* `AppConfig` stores both behind private fields exposed only through getters, so
|
|
17
|
+
* `{ ...env.config, endpoints: {...} }` silently drops everything it doesn't explicitly
|
|
18
|
+
* restate — a plain object spread copies no own enumerable properties off an `AppConfig`
|
|
19
|
+
* instance. Reach for this instead of hand-rolling that merge in a test fixture.
|
|
20
|
+
*
|
|
21
|
+
* @template TEnv - The `AppEnv` shape being merged into.
|
|
22
|
+
* @param env - The `AppEnv` to merge overrides into; left untouched, `config` may be omitted.
|
|
23
|
+
* @param overrides - Partial `environment`/`endpoints` values, merged over any existing config.
|
|
24
|
+
* @returns A new `AppEnv` with a new `AppConfig` reflecting the merge.
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* const test = testApp.extend('appEnv', ({ appEnv }) =>
|
|
28
|
+
* mergeEnvConfig(appEnv, { endpoints: { 'cpr-api': { url: backendBaseUrl } } }),
|
|
29
|
+
* );
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function mergeEnvConfig<TEnv extends AppEnv = AppEnv>(env: TEnv, overrides: MergeEnvConfigOverrides<TEnv['config'] extends AppConfig<infer TConfig> ? TConfig : ConfigEnvironment>): TEnv;
|
|
33
|
+
export default mergeEnvConfig;
|
|
@@ -31,11 +31,11 @@ export type ResolveAppTestEnvOptions = {
|
|
|
31
31
|
* back to an empty config if none exists.
|
|
32
32
|
*
|
|
33
33
|
* @remarks
|
|
34
|
-
* Intended to seed `@equinor/fusion-framework-vitest-plugin-react-app/test`'s `testApp` `
|
|
34
|
+
* Intended to seed `@equinor/fusion-framework-vitest-plugin-react-app/test`'s `testApp` `appEnv` fixture, so
|
|
35
35
|
* a test suite exercises the application's real manifest/config instead of a hand-maintained
|
|
36
36
|
* duplicate. Anything a specific test still needs faked (a missing endpoint, a different
|
|
37
|
-
* `appKey`) can be layered on top with `testApp.extend('
|
|
38
|
-
* `test.override('
|
|
37
|
+
* `appKey`) can be layered on top with `testApp.extend('appEnv', ...)` or a per-test
|
|
38
|
+
* `test.override('appEnv', ...)`.
|
|
39
39
|
*
|
|
40
40
|
* @param options - Resolution options; `entrypoint` defaults to the current working directory.
|
|
41
41
|
* @returns The resolved application manifest and config.
|
|
@@ -48,8 +48,8 @@ export type ResolveAppTestEnvOptions = {
|
|
|
48
48
|
* import { configure } from '../config';
|
|
49
49
|
*
|
|
50
50
|
* const test = testApp
|
|
51
|
-
* .extend('
|
|
52
|
-
* .extend('
|
|
51
|
+
* .extend('appEnv', { injected: true }, () => resolveAppTestEnv())
|
|
52
|
+
* .extend('configureApp', { injected: true }, () => configure);
|
|
53
53
|
* ```
|
|
54
54
|
*/
|
|
55
55
|
export declare const resolveAppTestEnv: (options?: ResolveAppTestEnvOptions) => Promise<AppTestEnv>;
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import type { AppEnv } from '@equinor/fusion-framework-app';
|
|
2
2
|
import type { Fusion } from '@equinor/fusion-framework';
|
|
3
|
+
import { type FrameworkMockConfigureFn } from '@equinor/fusion-framework/mock';
|
|
4
|
+
import type { AppModule } from '@equinor/fusion-framework-module-app';
|
|
5
|
+
import type { NavigationModule } from '@equinor/fusion-framework-module-navigation';
|
|
3
6
|
/**
|
|
4
7
|
* Resolves the parent Fusion instance backing an application module scope, building a
|
|
5
8
|
* fresh {@link mockFramework} instance with this app's own manifest served when none is
|
|
6
9
|
* given.
|
|
7
10
|
*
|
|
8
11
|
* @template TEnv - The application environment descriptor.
|
|
9
|
-
* @param env -
|
|
10
|
-
*
|
|
12
|
+
* @param options - `env` seeds the built-in app manifest mock; navigation defaults to real
|
|
13
|
+
* browser history, matching Browser Mode. `configure` runs afterwards on the same
|
|
14
|
+
* configurator — e.g. call `enableNavigation` again to override the history, or register
|
|
15
|
+
* extra modules and service discovery entries. `fusion`, an already-built parent instance,
|
|
16
|
+
* is reused as-is and skips `configure` entirely.
|
|
11
17
|
* @returns The given `fusion`, or a fresh mocked parent Fusion instance.
|
|
12
18
|
*/
|
|
13
|
-
export declare function resolveFusion<TEnv extends AppEnv = AppEnv>(
|
|
19
|
+
export declare function resolveFusion<TEnv extends AppEnv = AppEnv>(options?: {
|
|
20
|
+
env?: TEnv;
|
|
21
|
+
fusion?: Fusion;
|
|
22
|
+
configure?: FrameworkMockConfigureFn<[AppModule, NavigationModule]>;
|
|
23
|
+
}): Promise<Fusion>;
|
package/dist/types/test-app.d.ts
CHANGED
|
@@ -2,12 +2,15 @@ import type { ReactElement } from 'react';
|
|
|
2
2
|
import type { RenderOptions, RenderHookOptions } from 'vitest-browser-react';
|
|
3
3
|
import type { AppMockConfigureFn } from '@equinor/fusion-framework-app/mock';
|
|
4
4
|
import type { AppEnv } from '@equinor/fusion-framework-app';
|
|
5
|
+
import type { AppModule } from '@equinor/fusion-framework-module-app';
|
|
6
|
+
import type { NavigationModule } from '@equinor/fusion-framework-module-navigation';
|
|
7
|
+
import type { FrameworkMockConfigureFn } from '@equinor/fusion-framework/mock';
|
|
5
8
|
/**
|
|
6
9
|
* `vitest`'s `test`, extended with an application module scope fixture.
|
|
7
10
|
*
|
|
8
11
|
* @remarks
|
|
9
12
|
* An alternative to {@link renderAppComponent}/{@link renderAppHook} for a test file whose
|
|
10
|
-
* cases share seeded fixture defaults: `
|
|
13
|
+
* cases share seeded fixture defaults: `appEnv`/`configureApp` become suite-level concerns,
|
|
11
14
|
* overridden once per file (or per `describe` block) with `testApp.extend(...)`, rather than
|
|
12
15
|
* an options object repeated on every call. `fusion`/`app` are still instantiated fresh per
|
|
13
16
|
* test — only the seeded defaults are shared, not state between tests. They also resolve
|
|
@@ -18,6 +21,19 @@ import type { AppEnv } from '@equinor/fusion-framework-app';
|
|
|
18
21
|
* one-off test whose configuration is not shared by the rest of the file; reach for
|
|
19
22
|
* `testApp` when several cases in a file share one set of seeded fixture defaults.
|
|
20
23
|
*
|
|
24
|
+
* @remarks `configureApp`/`configureFusion` default to `undefined` here
|
|
25
|
+
* Unlike `@equinor/fusion-framework-vitest-plugin-react-app/test`'s `test`, this `testApp` does
|
|
26
|
+
* not resolve the app's real `src/config.ts` — it requires `appTestVitePlugin`'s Vite virtual
|
|
27
|
+
* modules to load that file as live code, which `testApp` (no Vite dependency) cannot do. Extend
|
|
28
|
+
* `test` from `/test` instead when a suite needs to compose with the app's real configuration.
|
|
29
|
+
*
|
|
30
|
+
* @remarks Overriding `fusion` bypasses `configureFusion`
|
|
31
|
+
* `fusion` and `configureFusion` are not independent: `fusion`'s default resolver is what
|
|
32
|
+
* calls `configureFusion`. `.override('fusion', ...)` replaces that resolver outright, so a
|
|
33
|
+
* `configureFusion` override on the same test/suite is silently never called. Use
|
|
34
|
+
* `configureFusion` to extend the base framework mock; use `fusion` only to replace it
|
|
35
|
+
* entirely (e.g. with a fully custom or non-mocked instance).
|
|
36
|
+
*
|
|
21
37
|
* @example
|
|
22
38
|
* ```tsx
|
|
23
39
|
* testApp('resolves current context', async ({ app, render }) => {
|
|
@@ -29,7 +45,7 @@ import type { AppEnv } from '@equinor/fusion-framework-app';
|
|
|
29
45
|
* @example Seed a module for every test in a suite
|
|
30
46
|
* ```tsx
|
|
31
47
|
* describe('with a seeded context module', () => {
|
|
32
|
-
* const test = testApp.extend('
|
|
48
|
+
* const test = testApp.extend('configureApp', { injected: true }, () =>
|
|
33
49
|
* (configurator) => enableContextMock(configurator, (mock) => mock.setCurrentContext(projectA)),
|
|
34
50
|
* );
|
|
35
51
|
*
|
|
@@ -39,30 +55,47 @@ import type { AppEnv } from '@equinor/fusion-framework-app';
|
|
|
39
55
|
* });
|
|
40
56
|
* });
|
|
41
57
|
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example Extend the parent framework mock with an application module
|
|
60
|
+
* ```tsx
|
|
61
|
+
* const test = testApp.extend('configureFusion', { injected: true }, () =>
|
|
62
|
+
* (configurator) => {
|
|
63
|
+
* enableFeatureFlagMock(configurator);
|
|
64
|
+
* configurator.serviceDiscovery.addServices([
|
|
65
|
+
* { key: 'people', uri: baseUrl('people') },
|
|
66
|
+
* { key: 'context', uri: baseUrl('context') },
|
|
67
|
+
* ]);
|
|
68
|
+
* },
|
|
69
|
+
* );
|
|
70
|
+
* ```
|
|
42
71
|
*/
|
|
43
|
-
export declare const testApp: import("vitest").TestAPI<Omit<Omit<Omit<Omit<Omit<Omit<object, "$__test"> & Record<"
|
|
72
|
+
export declare const testApp: import("vitest").TestAPI<Omit<Omit<Omit<Omit<Omit<Omit<Omit<object, "$__test"> & Record<"appEnv", AppEnv> & {
|
|
73
|
+
readonly $__worker?: object | undefined;
|
|
74
|
+
readonly $__file?: object | undefined;
|
|
75
|
+
readonly $__test?: (object & Record<"appEnv", AppEnv>) | undefined;
|
|
76
|
+
}, "$__test"> & Record<"configureApp", AppMockConfigureFn | undefined> & {
|
|
44
77
|
readonly $__worker?: object | undefined;
|
|
45
78
|
readonly $__file?: object | undefined;
|
|
46
|
-
readonly $__test?: (object & Record<"
|
|
47
|
-
}, "$__test"> & Record<"
|
|
79
|
+
readonly $__test?: (object & Record<"appEnv", AppEnv> & Record<"configureApp", AppMockConfigureFn | undefined>) | undefined;
|
|
80
|
+
}, "$__test"> & Record<"configureFusion", FrameworkMockConfigureFn<[AppModule, NavigationModule]> | undefined> & {
|
|
48
81
|
readonly $__worker?: object | undefined;
|
|
49
82
|
readonly $__file?: object | undefined;
|
|
50
|
-
readonly $__test?: (object & Record<"
|
|
83
|
+
readonly $__test?: (object & Record<"appEnv", AppEnv> & Record<"configureApp", AppMockConfigureFn | undefined> & Record<"configureFusion", FrameworkMockConfigureFn<[AppModule, NavigationModule]> | undefined>) | undefined;
|
|
51
84
|
}, "$__test"> & Record<"fusion", import("node_modules/@equinor/fusion-framework/src/types").Fusion<unknown>> & {
|
|
52
85
|
readonly $__worker?: object | undefined;
|
|
53
86
|
readonly $__file?: object | undefined;
|
|
54
|
-
readonly $__test?: (object & Record<"
|
|
55
|
-
}, "$__test"> & Record<"app", import("@equinor/fusion-framework-app").AppModulesInstance<unknown>> & {
|
|
87
|
+
readonly $__test?: (object & Record<"appEnv", AppEnv> & Record<"configureApp", AppMockConfigureFn | undefined> & Record<"configureFusion", FrameworkMockConfigureFn<[AppModule, NavigationModule]> | undefined> & Record<"fusion", import("node_modules/@equinor/fusion-framework/src/types").Fusion<unknown>>) | undefined;
|
|
88
|
+
}, "$__test"> & Record<"app", import("@equinor/fusion-framework-module-app").AppModulesInstance<unknown>> & {
|
|
56
89
|
readonly $__worker?: object | undefined;
|
|
57
90
|
readonly $__file?: object | undefined;
|
|
58
|
-
readonly $__test?: (object & Record<"
|
|
91
|
+
readonly $__test?: (object & Record<"appEnv", AppEnv> & Record<"configureApp", AppMockConfigureFn | undefined> & Record<"configureFusion", FrameworkMockConfigureFn<[AppModule, NavigationModule]> | undefined> & Record<"fusion", import("node_modules/@equinor/fusion-framework/src/types").Fusion<unknown>> & Record<"app", import("@equinor/fusion-framework-module-app").AppModulesInstance<unknown>>) | undefined;
|
|
59
92
|
}, "$__test"> & Record<"render", (ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderResult>> & {
|
|
60
93
|
readonly $__worker?: object | undefined;
|
|
61
94
|
readonly $__file?: object | undefined;
|
|
62
|
-
readonly $__test?: (object & Record<"
|
|
95
|
+
readonly $__test?: (object & Record<"appEnv", AppEnv> & Record<"configureApp", AppMockConfigureFn | undefined> & Record<"configureFusion", FrameworkMockConfigureFn<[AppModule, NavigationModule]> | undefined> & Record<"fusion", import("node_modules/@equinor/fusion-framework/src/types").Fusion<unknown>> & Record<"app", import("@equinor/fusion-framework-module-app").AppModulesInstance<unknown>> & Record<"render", (ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderResult>>) | undefined;
|
|
63
96
|
}, "$__test"> & Record<"renderHook", <Result, Props = undefined>(cb: (initialProps?: Props) => Result, options?: Omit<RenderHookOptions<Props>, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderHookResult<Result, Props>>> & {
|
|
64
97
|
readonly $__worker?: object | undefined;
|
|
65
98
|
readonly $__file?: object | undefined;
|
|
66
|
-
readonly $__test?: (object & Record<"
|
|
99
|
+
readonly $__test?: (object & Record<"appEnv", AppEnv> & Record<"configureApp", AppMockConfigureFn | undefined> & Record<"configureFusion", FrameworkMockConfigureFn<[AppModule, NavigationModule]> | undefined> & Record<"fusion", import("node_modules/@equinor/fusion-framework/src/types").Fusion<unknown>> & Record<"app", import("@equinor/fusion-framework-module-app").AppModulesInstance<unknown>> & Record<"render", (ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderResult>> & Record<"renderHook", <Result, Props = undefined>(cb: (initialProps?: Props) => Result, options?: Omit<RenderHookOptions<Props>, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderHookResult<Result, Props>>>) | undefined;
|
|
67
100
|
}>;
|
|
68
101
|
export default testApp;
|
package/dist/types/test.d.ts
CHANGED
|
@@ -7,8 +7,15 @@
|
|
|
7
7
|
* your `vitest.config.ts` `plugins`, which serves the virtual modules backing this fixture.
|
|
8
8
|
* Running the same test file without the plugin registered fails to resolve those imports.
|
|
9
9
|
*
|
|
10
|
-
* Per-test mocking still works exactly like the base `testApp`: `.extend('
|
|
11
|
-
* a per-case `test.override('
|
|
10
|
+
* Per-test mocking still works exactly like the base `testApp`: `.extend('configureApp', ...)` or
|
|
11
|
+
* a per-case `test.override('appEnv', ...)` layers on top of the resolved values.
|
|
12
|
+
*
|
|
13
|
+
* @remarks `.override('configureApp', ...)` replaces the app's real `configure`
|
|
14
|
+
* This fixture's default value *is* the app's real `src/config.ts` `configure` export.
|
|
15
|
+
* `.override('configureApp', ...)` replaces that default outright, so an override that doesn't
|
|
16
|
+
* itself call the real `configure(configurator, args)` skips the app's production module setup
|
|
17
|
+
* entirely, rather than composing with it. See [Advanced usage](../docs/advanced.md) for the
|
|
18
|
+
* compose-safely pattern.
|
|
12
19
|
*
|
|
13
20
|
* @example
|
|
14
21
|
* ```tsx
|
|
@@ -21,44 +28,48 @@
|
|
|
21
28
|
* });
|
|
22
29
|
* ```
|
|
23
30
|
*/
|
|
24
|
-
export declare const test: import("vitest").TestAPI<Omit<Omit<Omit<Omit<Omit<Omit<Omit<Omit<object, "$__test"> & Record<"
|
|
31
|
+
export declare const test: import("vitest").TestAPI<Omit<Omit<Omit<Omit<Omit<Omit<Omit<Omit<Omit<object, "$__test"> & Record<"appEnv", import("node_modules/@equinor/fusion-framework-app/src/types").AppEnv> & {
|
|
32
|
+
readonly $__worker?: object | undefined;
|
|
33
|
+
readonly $__file?: object | undefined;
|
|
34
|
+
readonly $__test?: (object & Record<"appEnv", import("node_modules/@equinor/fusion-framework-app/src/types").AppEnv>) | undefined;
|
|
35
|
+
}, "$__test"> & Record<"configureApp", import("node_modules/@equinor/fusion-framework-app/src/mock/mock-app-modules").AppMockConfigureFn | undefined> & {
|
|
25
36
|
readonly $__worker?: object | undefined;
|
|
26
37
|
readonly $__file?: object | undefined;
|
|
27
|
-
readonly $__test?: (object & Record<"
|
|
28
|
-
}, "$__test"> & Record<"
|
|
38
|
+
readonly $__test?: (object & Record<"appEnv", import("node_modules/@equinor/fusion-framework-app/src/types").AppEnv> & Record<"configureApp", import("node_modules/@equinor/fusion-framework-app/src/mock/mock-app-modules").AppMockConfigureFn | undefined>) | undefined;
|
|
39
|
+
}, "$__test"> & Record<"configureFusion", import("node_modules/@equinor/fusion-framework/src/mock/mock-framework").FrameworkMockConfigureFn<[import("node_modules/@equinor/fusion-framework-module-app/src/module").AppModule, import("node_modules/@equinor/fusion-framework-module-navigation/src/module").NavigationModule]> | undefined> & {
|
|
29
40
|
readonly $__worker?: object | undefined;
|
|
30
41
|
readonly $__file?: object | undefined;
|
|
31
|
-
readonly $__test?: (object & Record<"
|
|
42
|
+
readonly $__test?: (object & Record<"appEnv", import("node_modules/@equinor/fusion-framework-app/src/types").AppEnv> & Record<"configureApp", import("node_modules/@equinor/fusion-framework-app/src/mock/mock-app-modules").AppMockConfigureFn | undefined> & Record<"configureFusion", import("node_modules/@equinor/fusion-framework/src/mock/mock-framework").FrameworkMockConfigureFn<[import("node_modules/@equinor/fusion-framework-module-app/src/module").AppModule, import("node_modules/@equinor/fusion-framework-module-navigation/src/module").NavigationModule]> | undefined>) | undefined;
|
|
32
43
|
}, "$__test"> & Record<"fusion", import("node_modules/@equinor/fusion-framework/src/types").Fusion<unknown>> & {
|
|
33
44
|
readonly $__worker?: object | undefined;
|
|
34
45
|
readonly $__file?: object | undefined;
|
|
35
|
-
readonly $__test?: (object & Record<"
|
|
46
|
+
readonly $__test?: (object & Record<"appEnv", import("node_modules/@equinor/fusion-framework-app/src/types").AppEnv> & Record<"configureApp", import("node_modules/@equinor/fusion-framework-app/src/mock/mock-app-modules").AppMockConfigureFn | undefined> & Record<"configureFusion", import("node_modules/@equinor/fusion-framework/src/mock/mock-framework").FrameworkMockConfigureFn<[import("node_modules/@equinor/fusion-framework-module-app/src/module").AppModule, import("node_modules/@equinor/fusion-framework-module-navigation/src/module").NavigationModule]> | undefined> & Record<"fusion", import("node_modules/@equinor/fusion-framework/src/types").Fusion<unknown>>) | undefined;
|
|
36
47
|
}, "$__test"> & Record<"app", import("node_modules/@equinor/fusion-framework-module-app/src/types").AppModulesInstance<unknown>> & {
|
|
37
48
|
readonly $__worker?: object | undefined;
|
|
38
49
|
readonly $__file?: object | undefined;
|
|
39
|
-
readonly $__test?: (object & Record<"
|
|
50
|
+
readonly $__test?: (object & Record<"appEnv", import("node_modules/@equinor/fusion-framework-app/src/types").AppEnv> & Record<"configureApp", import("node_modules/@equinor/fusion-framework-app/src/mock/mock-app-modules").AppMockConfigureFn | undefined> & Record<"configureFusion", import("node_modules/@equinor/fusion-framework/src/mock/mock-framework").FrameworkMockConfigureFn<[import("node_modules/@equinor/fusion-framework-module-app/src/module").AppModule, import("node_modules/@equinor/fusion-framework-module-navigation/src/module").NavigationModule]> | undefined> & Record<"fusion", import("node_modules/@equinor/fusion-framework/src/types").Fusion<unknown>> & Record<"app", import("node_modules/@equinor/fusion-framework-module-app/src/types").AppModulesInstance<unknown>>) | undefined;
|
|
40
51
|
}, "$__test"> & Record<"render", (ui: import("node_modules/@types/react").ReactElement, options?: Omit<import("node_modules/vitest-browser-react/dist").RenderOptions, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderResult>> & {
|
|
41
52
|
readonly $__worker?: object | undefined;
|
|
42
53
|
readonly $__file?: object | undefined;
|
|
43
|
-
readonly $__test?: (object & Record<"
|
|
54
|
+
readonly $__test?: (object & Record<"appEnv", import("node_modules/@equinor/fusion-framework-app/src/types").AppEnv> & Record<"configureApp", import("node_modules/@equinor/fusion-framework-app/src/mock/mock-app-modules").AppMockConfigureFn | undefined> & Record<"configureFusion", import("node_modules/@equinor/fusion-framework/src/mock/mock-framework").FrameworkMockConfigureFn<[import("node_modules/@equinor/fusion-framework-module-app/src/module").AppModule, import("node_modules/@equinor/fusion-framework-module-navigation/src/module").NavigationModule]> | undefined> & Record<"fusion", import("node_modules/@equinor/fusion-framework/src/types").Fusion<unknown>> & Record<"app", import("node_modules/@equinor/fusion-framework-module-app/src/types").AppModulesInstance<unknown>> & Record<"render", (ui: import("node_modules/@types/react").ReactElement, options?: Omit<import("node_modules/vitest-browser-react/dist").RenderOptions, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderResult>>) | undefined;
|
|
44
55
|
}, "$__test"> & Record<"renderHook", <Result, Props = undefined>(cb: (initialProps?: Props) => Result, options?: Omit<import("node_modules/vitest-browser-react/dist").RenderHookOptions<Props>, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderHookResult<Result, Props>>> & {
|
|
45
56
|
readonly $__worker?: object | undefined;
|
|
46
57
|
readonly $__file?: object | undefined;
|
|
47
|
-
readonly $__test?: (object & Record<"
|
|
48
|
-
}, "$__test"> & Record<"
|
|
58
|
+
readonly $__test?: (object & Record<"appEnv", import("node_modules/@equinor/fusion-framework-app/src/types").AppEnv> & Record<"configureApp", import("node_modules/@equinor/fusion-framework-app/src/mock/mock-app-modules").AppMockConfigureFn | undefined> & Record<"configureFusion", import("node_modules/@equinor/fusion-framework/src/mock/mock-framework").FrameworkMockConfigureFn<[import("node_modules/@equinor/fusion-framework-module-app/src/module").AppModule, import("node_modules/@equinor/fusion-framework-module-navigation/src/module").NavigationModule]> | undefined> & Record<"fusion", import("node_modules/@equinor/fusion-framework/src/types").Fusion<unknown>> & Record<"app", import("node_modules/@equinor/fusion-framework-module-app/src/types").AppModulesInstance<unknown>> & Record<"render", (ui: import("node_modules/@types/react").ReactElement, options?: Omit<import("node_modules/vitest-browser-react/dist").RenderOptions, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderResult>> & Record<"renderHook", <Result, Props = undefined>(cb: (initialProps?: Props) => Result, options?: Omit<import("node_modules/vitest-browser-react/dist").RenderHookOptions<Props>, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderHookResult<Result, Props>>>) | undefined;
|
|
59
|
+
}, "$__test"> & Record<"appEnv", {
|
|
49
60
|
manifest: import("@equinor/fusion-framework-cli/app").AppManifest;
|
|
50
61
|
config: import("node_modules/@equinor/fusion-framework-module-app/src/AppConfig").AppConfig<import("node_modules/@equinor/fusion-framework-module-app/src/types").ConfigEnvironment> | undefined;
|
|
51
62
|
}> & {
|
|
52
63
|
readonly $__worker?: object | undefined;
|
|
53
64
|
readonly $__file?: object | undefined;
|
|
54
|
-
readonly $__test?: (object & Record<"
|
|
65
|
+
readonly $__test?: (object & Record<"appEnv", import("node_modules/@equinor/fusion-framework-app/src/types").AppEnv> & Record<"configureApp", import("node_modules/@equinor/fusion-framework-app/src/mock/mock-app-modules").AppMockConfigureFn | undefined> & Record<"configureFusion", import("node_modules/@equinor/fusion-framework/src/mock/mock-framework").FrameworkMockConfigureFn<[import("node_modules/@equinor/fusion-framework-module-app/src/module").AppModule, import("node_modules/@equinor/fusion-framework-module-navigation/src/module").NavigationModule]> | undefined> & Record<"fusion", import("node_modules/@equinor/fusion-framework/src/types").Fusion<unknown>> & Record<"app", import("node_modules/@equinor/fusion-framework-module-app/src/types").AppModulesInstance<unknown>> & Record<"render", (ui: import("node_modules/@types/react").ReactElement, options?: Omit<import("node_modules/vitest-browser-react/dist").RenderOptions, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderResult>> & Record<"renderHook", <Result, Props = undefined>(cb: (initialProps?: Props) => Result, options?: Omit<import("node_modules/vitest-browser-react/dist").RenderHookOptions<Props>, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderHookResult<Result, Props>>> & Record<"appEnv", {
|
|
55
66
|
manifest: import("@equinor/fusion-framework-cli/app").AppManifest;
|
|
56
67
|
config: import("node_modules/@equinor/fusion-framework-module-app/src/AppConfig").AppConfig<import("node_modules/@equinor/fusion-framework-module-app/src/types").ConfigEnvironment> | undefined;
|
|
57
68
|
}>) | undefined;
|
|
58
|
-
}, "$__test"> & Record<"
|
|
69
|
+
}, "$__test"> & Record<"configureApp", import("node_modules/@equinor/fusion-framework-app/src/mock/mock-app-modules").AppMockConfigureFn | undefined> & {
|
|
59
70
|
readonly $__worker?: object | undefined;
|
|
60
71
|
readonly $__file?: object | undefined;
|
|
61
|
-
readonly $__test?: (object & Record<"
|
|
72
|
+
readonly $__test?: (object & Record<"appEnv", import("node_modules/@equinor/fusion-framework-app/src/types").AppEnv> & Record<"configureApp", import("node_modules/@equinor/fusion-framework-app/src/mock/mock-app-modules").AppMockConfigureFn | undefined> & Record<"configureFusion", import("node_modules/@equinor/fusion-framework/src/mock/mock-framework").FrameworkMockConfigureFn<[import("node_modules/@equinor/fusion-framework-module-app/src/module").AppModule, import("node_modules/@equinor/fusion-framework-module-navigation/src/module").NavigationModule]> | undefined> & Record<"fusion", import("node_modules/@equinor/fusion-framework/src/types").Fusion<unknown>> & Record<"app", import("node_modules/@equinor/fusion-framework-module-app/src/types").AppModulesInstance<unknown>> & Record<"render", (ui: import("node_modules/@types/react").ReactElement, options?: Omit<import("node_modules/vitest-browser-react/dist").RenderOptions, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderResult>> & Record<"renderHook", <Result, Props = undefined>(cb: (initialProps?: Props) => Result, options?: Omit<import("node_modules/vitest-browser-react/dist").RenderHookOptions<Props>, 'wrapper'>) => Promise<import("node_modules/vitest-browser-react/dist").RenderHookResult<Result, Props>>> & Record<"appEnv", {
|
|
62
73
|
manifest: import("@equinor/fusion-framework-cli/app").AppManifest;
|
|
63
74
|
config: import("node_modules/@equinor/fusion-framework-module-app/src/AppConfig").AppConfig<import("node_modules/@equinor/fusion-framework-module-app/src/types").ConfigEnvironment> | undefined;
|
|
64
75
|
}>) | undefined;
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "0.
|
|
1
|
+
export declare const version = "1.0.0-next.4";
|
package/docs/advanced.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Advanced Fusion app testing
|
|
2
2
|
|
|
3
|
-
The `/test` entry point extends Vitest's test context with `
|
|
4
|
-
`render`, and `renderHook`. Fixture declarations are reusable, while each test
|
|
5
|
-
framework and app module instances.
|
|
3
|
+
The `/test` entry point extends Vitest's test context with `appEnv`, `configureApp`, `configureFusion`,
|
|
4
|
+
`fusion`, `app`, `render`, and `renderHook`. Fixture declarations are reusable, while each test
|
|
5
|
+
receives fresh framework and app module instances.
|
|
6
6
|
|
|
7
|
-
This guide covers composing and overriding those
|
|
7
|
+
This guide covers composing and overriding those Fusion fixture values; see Vitest's own
|
|
8
8
|
[Test Context](https://vitest.dev/guide/test-context) documentation for fixture scope, cleanup,
|
|
9
9
|
and the general `test.extend`/`test.override` mechanics Fusion builds on.
|
|
10
10
|
|
|
@@ -24,7 +24,11 @@ module instances consumed by the rendered subject.
|
|
|
24
24
|
|
|
25
25
|
## Extend app configuration
|
|
26
26
|
|
|
27
|
-
Create one reusable extended test when several cases need the same deterministic modules
|
|
27
|
+
Create one reusable extended test when several cases need the same deterministic modules.
|
|
28
|
+
This must extend `test` from `/test`, not `testApp` from the main entry point:
|
|
29
|
+
`testApp`'s `configureApp` defaults to `undefined` (no Vite dependency, so no way to load the
|
|
30
|
+
real `src/config.ts` as live code), while `/test`'s `test` seeds it with the app's real
|
|
31
|
+
`configure` export via `appTestVitePlugin`'s virtual modules.
|
|
28
32
|
|
|
29
33
|
```tsx
|
|
30
34
|
import { enableContextMock } from '@equinor/fusion-framework-module-context/mock';
|
|
@@ -37,13 +41,13 @@ const project = {
|
|
|
37
41
|
value: {},
|
|
38
42
|
};
|
|
39
43
|
|
|
40
|
-
export const test = baseTest.extend('
|
|
41
|
-
|
|
44
|
+
export const test = baseTest.extend('configureApp', ({ configureApp }) => (configurator, args) => {
|
|
45
|
+
configureApp?.(configurator, args);
|
|
42
46
|
enableContextMock(configurator, (mock) => mock.setCurrentContext(project));
|
|
43
47
|
});
|
|
44
48
|
```
|
|
45
49
|
|
|
46
|
-
Composing the original `
|
|
50
|
+
Composing the original `configureApp` fixture preserves the application's production module
|
|
47
51
|
configuration. See [Module mocks](module-mocks.md) for authentication, context, bookmark,
|
|
48
52
|
feature-flag, HTTP, analytics, and telemetry boundaries.
|
|
49
53
|
|
|
@@ -51,6 +55,22 @@ feature-flag, HTTP, analytics, and telemetry boundaries.
|
|
|
51
55
|
*files* need the same fixture default. Within one file, prefer `test.override(...)` (below):
|
|
52
56
|
it replaces a fixture in place, so every test in that file keeps importing the same `test`.
|
|
53
57
|
|
|
58
|
+
## Fake an endpoint URL with `mergeEnvConfig`
|
|
59
|
+
|
|
60
|
+
`appEnv`'s `config` is an `AppConfig` instance — its `environment`/`endpoints` live behind
|
|
61
|
+
private fields exposed only through getters, so `{ ...appEnv.config, endpoints: {...} }` copies
|
|
62
|
+
nothing and silently drops the rest of the config. Use `mergeEnvConfig` to fake one endpoint's
|
|
63
|
+
URL (e.g. the app's real backend, resolved from `app.config.ts`) while keeping every other
|
|
64
|
+
endpoint and environment variable intact:
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { mergeEnvConfig, test as baseTest } from '@equinor/fusion-framework-vitest-plugin-react-app/test';
|
|
68
|
+
|
|
69
|
+
export const test = baseTest.extend('appEnv', ({ appEnv }) =>
|
|
70
|
+
mergeEnvConfig(appEnv, { endpoints: { 'cpr-api': { url: backendBaseUrl } } }),
|
|
71
|
+
);
|
|
72
|
+
```
|
|
73
|
+
|
|
54
74
|
## Override a fixture for one test or a `describe` block
|
|
55
75
|
|
|
56
76
|
`test.override('name', ...)` replaces a fixture's resolved value without creating a new `test`
|
|
@@ -59,6 +79,11 @@ and does not leak to sibling blocks or other files — each `describe` starts fr
|
|
|
59
79
|
base `test` again. Called at the top of the file (outside any `describe`), it applies to every
|
|
60
80
|
test in that file.
|
|
61
81
|
|
|
82
|
+
**`configureApp`'s default value, from `/test`, *is* the app's real `src/config.ts` `configure`
|
|
83
|
+
export.** `test.override('configureApp', ...)` replaces that default outright — an override
|
|
84
|
+
that doesn't call the real `configure(configurator, args)` itself, as below, skips the app's
|
|
85
|
+
production module setup entirely rather than composing with it.
|
|
86
|
+
|
|
62
87
|
```tsx
|
|
63
88
|
import { test } from '@equinor/fusion-framework-vitest-plugin-react-app/test';
|
|
64
89
|
import { enableContextMock } from '@equinor/fusion-framework-module-context/mock';
|
|
@@ -69,7 +94,7 @@ import { configure } from '../config'; // the app's own, real module configurato
|
|
|
69
94
|
const project = { id: 'project-a', title: 'Project A', type: { id: 'ProjectMaster' }, value: {} };
|
|
70
95
|
|
|
71
96
|
describe('with an initial project', () => {
|
|
72
|
-
test.override('
|
|
97
|
+
test.override('configureApp', { injected: true }, () => (configurator, args) => {
|
|
73
98
|
configure(configurator, args); // compose the app's real configure, same as `.extend`
|
|
74
99
|
enableContextMock(configurator, (mock) => mock.setCurrentContext(project));
|
|
75
100
|
});
|
|
@@ -82,13 +107,13 @@ describe('with an initial project', () => {
|
|
|
82
107
|
```
|
|
83
108
|
|
|
84
109
|
`fusion` itself can be overridden the same way, when a case needs a differently configured
|
|
85
|
-
parent framework instance rather than a change to the app's own `
|
|
110
|
+
parent framework instance rather than a change to the app's own `configureApp`:
|
|
86
111
|
|
|
87
112
|
```tsx
|
|
88
113
|
describe('with a parent framework context', () => {
|
|
89
|
-
test.override('fusion', async ({
|
|
114
|
+
test.override('fusion', async ({ appEnv }) =>
|
|
90
115
|
mockFramework<[AppModule, ContextModule]>((configurator) => {
|
|
91
|
-
enableAppManifestMock(configurator,
|
|
116
|
+
enableAppManifestMock(configurator, appEnv);
|
|
92
117
|
enableContextMock(configurator, (mock) => mock.setCurrentContext(project));
|
|
93
118
|
}),
|
|
94
119
|
);
|
|
@@ -119,6 +144,45 @@ Use [`enableAppManifestMock`](../../../app/docs/testing.md#enableappmanifestmock
|
|
|
119
144
|
when the custom parent must serve the app's manifest and config. Use
|
|
120
145
|
[`mockFramework`](../../../framework/docs/testing.md) to seed the parent modules.
|
|
121
146
|
|
|
147
|
+
## Extend the parent framework mock with `configureFusion`
|
|
148
|
+
|
|
149
|
+
`fusion` (built by [`resolveFusion`](../src/scope/resolve-fusion.ts)) always carries a mocked
|
|
150
|
+
`app` module (serving this app's manifest) and a `navigation` module with real browser history,
|
|
151
|
+
matching Browser Mode. `configureFusion` runs on the same configurator afterwards, so a test can
|
|
152
|
+
register extra framework-level modules or override that setup, without reimplementing it:
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
import { enableFeatureFlagMock } from '@equinor/fusion-framework-module-feature-flag/mock';
|
|
156
|
+
|
|
157
|
+
const test = baseTest.extend('configureFusion', { injected: true }, () => (configurator) => {
|
|
158
|
+
enableFeatureFlagMock(configurator);
|
|
159
|
+
configurator.serviceDiscovery.addServices([{ key: 'people', uri: baseUrl('people') }]);
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Note this is a **framework-scope** module set, distinct from the app-scope one `configureApp`
|
|
164
|
+
seeds. A typical app registers its own `navigation` module independently, inside its own
|
|
165
|
+
`config.ts`'s `configure` callback (what `configureApp` composes with) — so overriding history
|
|
166
|
+
through `configureFusion` only affects framework-scope consumers, such as
|
|
167
|
+
`useFramework<[NavigationModule]>().modules.navigation` or `useBookmarkNavigate`, not a
|
|
168
|
+
rendered app's own router:
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
import { enableNavigation, createHistory } from '@equinor/fusion-framework-module-navigation';
|
|
172
|
+
|
|
173
|
+
test.override('configureFusion', { injected: true }, () => (configurator) =>
|
|
174
|
+
enableNavigation(configurator, {
|
|
175
|
+
configure: (config) => config.setHistory(createHistory('memory')),
|
|
176
|
+
}),
|
|
177
|
+
);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**`.override('fusion', ...)` bypasses `configureFusion` entirely** — it replaces the resolver
|
|
181
|
+
that calls it, so a `configureFusion` override on the same test/suite is silently never called.
|
|
182
|
+
Reach for `configureFusion` to extend the base mock; reach for `fusion` only to replace it
|
|
183
|
+
outright (e.g. with a fully custom or non-mocked instance) — see
|
|
184
|
+
[Supply a custom parent framework](#supply-a-custom-parent-framework) above.
|
|
185
|
+
|
|
122
186
|
## Test routes and app lifecycle
|
|
123
187
|
|
|
124
188
|
Render the complete `App` when assertions depend on route loaders, navigation, app
|
|
@@ -26,7 +26,7 @@ Browser Mode by providing its own renderer. See
|
|
|
26
26
|
| `@testing-library/react`'s `render`/`renderHook`/`waitFor`/`act`, on `jsdom` or `happy-dom` | `vitest-browser-react`'s `render`/`renderHook` and `vitest`'s `waitFor`/`act`, on real Chromium (Vitest Browser Mode) |
|
|
27
27
|
| `vi.mock('@equinor/fusion-framework-react/hooks', ...)`, `vi.mock('.../feature-flag', ...)`, and similar hand-rolled Fusion hook mocks | The owning module's `enable*Mock` from its own `/mock` entry point. See [Module mocks](module-mocks.md) |
|
|
28
28
|
| A hand-written mock HTTP server (MirageJS, `msw/node`, `nock`) answering every backend call | `configurator.http.addMiddleware(...)` with a hand-written `HttpMiddleware`, or `createRouterMiddleware` for several routes under one base URI. See [HTTP testing](../../../modules/http/docs/testing.md) |
|
|
29
|
-
| A hand-rolled test wrapper composing a router, context providers, and error boundaries around every render | `test.extend(...)` fixtures stacked on the base `render`/`
|
|
29
|
+
| A hand-rolled test wrapper composing a router, context providers, and error boundaries around every render | `test.extend(...)` fixtures stacked on the base `render`/`configureApp` fixtures. See [Compose a router and a domain fixture](#compose-a-router-and-a-domain-fixture) below |
|
|
30
30
|
| Synchronous assertions (`expect(screen.getByText(...))`) | Browser locators and `await expect.element(screen.getByText(...)).toBeVisible()` |
|
|
31
31
|
|
|
32
32
|
## Step 1: install Browser Mode dependencies
|
|
@@ -71,8 +71,8 @@ bookmark modules:
|
|
|
71
71
|
+import { enableFeatureFlagMock } from '@equinor/fusion-framework-module-feature-flag/mock';
|
|
72
72
|
+import { test as baseTest } from '@equinor/fusion-framework-vitest-plugin-react-app/test';
|
|
73
73
|
+
|
|
74
|
-
+export const test = baseTest.extend('
|
|
75
|
-
+
|
|
74
|
+
+export const test = baseTest.extend('configureApp', ({ configureApp }) => (configurator, args) => {
|
|
75
|
+
+ configureApp?.(configurator, args);
|
|
76
76
|
+ configurator.msal.setAccount(null); // was: useCurrentUser returning undefined
|
|
77
77
|
+ enableFeatureFlagMock(configurator, (mock) => mock.addFeature({ key: 'new-search', enabled: true }));
|
|
78
78
|
+});
|
|
@@ -113,7 +113,7 @@ Use `createRouterMiddleware` for a mock server that handles several routes under
|
|
|
113
113
|
+});
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
Register the result with `configurator.http.addMiddleware(activityRoutes)` inside a `
|
|
116
|
+
Register the result with `configurator.http.addMiddleware(activityRoutes)` inside a `configureApp`
|
|
117
117
|
fixture (see step 4). Port one route file at a time. Each ported file is independently testable.
|
|
118
118
|
An unported route can fall through to the real network, so keep the old interceptor
|
|
119
119
|
for tests that have not migrated yet or add a final fail-closed middleware; do not rely on a
|
|
@@ -128,7 +128,7 @@ router for the base URI used by the real client.
|
|
|
128
128
|
## Compose a router and a domain fixture
|
|
129
129
|
|
|
130
130
|
Use a `render` extension for JSX wrappers such as routers and app-owned React providers. Use a
|
|
131
|
-
`
|
|
131
|
+
`configureApp` extension for Fusion module state. Stack both extensions when a test needs both:
|
|
132
132
|
|
|
133
133
|
```tsx
|
|
134
134
|
import type { ReactElement } from 'react';
|
|
@@ -143,9 +143,9 @@ const testWithRouter = baseTest.extend('render', () => (ui: ReactElement) => {
|
|
|
143
143
|
return baseTest.render(<Router routes={routes} />);
|
|
144
144
|
});
|
|
145
145
|
|
|
146
|
-
// The domain fixture uses the same shape as any other `
|
|
147
|
-
export const test = testWithRouter.extend('
|
|
148
|
-
|
|
146
|
+
// The domain fixture uses the same shape as any other `configureApp` extension.
|
|
147
|
+
export const test = testWithRouter.extend('configureApp', ({ configureApp }) => (configurator, args) => {
|
|
148
|
+
configureApp?.(configurator, args);
|
|
149
149
|
enableContextMock(configurator, (mock) => mock.setCurrentContext(projectA));
|
|
150
150
|
});
|
|
151
151
|
```
|
|
@@ -153,7 +153,7 @@ export const test = testWithRouter.extend('configure', ({ configure }) => (confi
|
|
|
153
153
|
A test importing this `test` gets both the router wrapper and seeded Fusion context.
|
|
154
154
|
|
|
155
155
|
Keep app-owned React providers, such as authorization, schema, or snackbar providers, in the
|
|
156
|
-
`render` extension. Move only Fusion module state to `
|
|
156
|
+
`render` extension. Move only Fusion module state to `configureApp` and `enable*Mock`.
|
|
157
157
|
|
|
158
158
|
## Step 4: update renders and assertions
|
|
159
159
|
|
package/docs/module-mocks.md
CHANGED
|
@@ -93,8 +93,8 @@ const project = {
|
|
|
93
93
|
value: {},
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
-
export const test = baseTest.extend('
|
|
97
|
-
|
|
96
|
+
export const test = baseTest.extend('configureApp', ({ configureApp }) => (configurator, args) => {
|
|
97
|
+
configureApp?.(configurator, args);
|
|
98
98
|
configurator.msal.setAccount({ name: 'Ada Lovelace' });
|
|
99
99
|
enableContextMock(configurator, (mock) => mock.setCurrentContext(project));
|
|
100
100
|
enableFeatureFlagMock(configurator, (mock) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@equinor/fusion-framework-vitest-plugin-react-app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-next.4",
|
|
4
4
|
"description": "Vite plugin resolving an application's manifest, config, and module-configurator as virtual modules for testing.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -47,13 +47,14 @@
|
|
|
47
47
|
"access": "public"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@equinor/fusion-framework-cli": "15.2.8-next.2",
|
|
51
50
|
"@equinor/fusion-framework": "8.1.0-next.1",
|
|
51
|
+
"@equinor/fusion-framework-cli": "15.2.8-next.2",
|
|
52
|
+
"@equinor/fusion-framework-module": "6.1.3-next.0",
|
|
52
53
|
"@equinor/fusion-framework-module-app": "8.1.0-next.0",
|
|
54
|
+
"@equinor/fusion-framework-module-navigation": "7.0.8-next.0",
|
|
53
55
|
"@equinor/fusion-framework-react": "9.0.0-next.0",
|
|
54
|
-
"@equinor/fusion-framework-react-module": "4.0.3-next.0",
|
|
55
|
-
"@equinor/fusion-framework-module": "6.1.3-next.0",
|
|
56
56
|
"@equinor/fusion-framework-app": "14.0.0-next.1",
|
|
57
|
+
"@equinor/fusion-framework-react-module": "4.0.3-next.0",
|
|
57
58
|
"@equinor/fusion-imports": "2.0.3-next.0"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|