equinor / equinor/fusion-framework

FrameworkMockConfigurator: real enableX helpers can silently un-mock a pinned module

Open
#5,247 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
10
Forks
10
Avg merge
19h 40m
Merged PRs (30d)
150

Description

## Problem

`FrameworkMockConfigurator._pin` wraps a built-in module's `configure` factory so it always returns the same instance, then registers it via `this.addConfig({ module: pinned })`. `ModulesConfigurator.addConfig` re-registers modules by name on a last-write-wins basis: when a later `addConfig` call arrives for the same module name (e.g. an application calling the module's *real* `enableX`/`configureX` helper — not its mock-specific counterpart — against a `FrameworkMockConfigurator`), it removes the pinned module's callbacks and installs the real, unpinned `configure` factory instead.

The result: initialization builds a fresh, real (unmocked) configurator instance for that module, while the corresponding accessor on `FrameworkMockConfigurator` (e.g. `.telemetry`, `.msal`, `.http`) keeps returning the stale pinned mock — configuration and reads silently drift apart.

This affects every module pinned by `FrameworkMockConfigurator`: `msal`, `serviceDiscovery`, `http`, `services`, `context`, and `telemetry`.

## Reproduction sketch

```typescript
const fusion = await mockFramework((configurator) => {
// enableTelemetry is the REAL helper, not enableTelemetryMock
enableTelemetry(configurator, (builder) => builder.setMetadata({ app: 'demo' }));
});

// configurator.telemetry.adapter still refers to the pinned mock,
// but fusion.modules.telemetry is now backed by a real, unmocked configurator.
```

## Discussion

Raised as a [review comment](https://github.com/equinor/fusion-framework/pull/5246#discussion_r3748647630) on #5246. A fix was drafted there (a `#pinnedDescriptors` map plus an `addConfig` override redirecting same-name registrations back to the pinned descriptor) but reverted as too much bookkeeping for a single-PR fix, since this is a pre-existing, generic risk of the `_pin` mechanism rather than something specific to the telemetry mock.

## Suggested direction

Fix this once, generically, in `FrameworkMockConfigurator`/`_pin` (or in `ModulesConfigurator.addConfig`'s re-registration semantics) rather than per-module. Whatever shape it takes, add a regression test that calls a built-in module's real `enableX` helper against `FrameworkMockConfigurator` and asserts the pinned accessor still reflects the mock after initialization.

Contributor guide

Open the contributing guide

Research direction

Start in FrameworkMockConfigurator._pin and ModulesConfigurator.addConfig, then trace how same-name registrations replace pinned callbacks. Add a regression test using a built-in module’s real enableX/configureX helper with FrameworkMockConfigurator; done means initialization preserves the pinned mock and its accessor stays consistent with the module instance.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.