Skip to content

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

Description

@odinr

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

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 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions