Skip to content

test(e2e): mock signature-insights to remove from allowlist (MMQA-1779)#29601

Merged
chrisleewilcox merged 1 commit into
mainfrom
MMQA-1779-tier-3-signature-insights-mocks
May 1, 2026
Merged

test(e2e): mock signature-insights to remove from allowlist (MMQA-1779)#29601
chrisleewilcox merged 1 commit into
mainfrom
MMQA-1779-tier-3-signature-insights-mocks

Conversation

@chrisleewilcox

@chrisleewilcox chrisleewilcox commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Description

Tier 3 of MMQA-1364 (allowlist reduction), scoped to the signature-insights endpoint only. NFT API entries (/users/.../tokens, /collections, /explore/sites, prod/dev/uat hosts) are deferred to follow-up tickets in the same tier.

Matcher Method Response
^https://signature-insights\.api\.cx\.metamask\.io/v1/signature\?chainId=0x[0-9a-fA-F]+$ POST { stateChanges: null, error: { message: 'Unsupported signature.', type: 'UNSUPPORTED_SIGNATURE' } }

Why this response shape. The SDK's own decodeSignature (@metamask/signature-controller/utils/decoding-api) returns this exact shape (type: 'UNSUPPORTED_SIGNATURE') when the signature method is anything other than SignTypedDataV3/V4. The wallet's TypedSignV3V4Simulation (app/components/Views/confirmations/components/info/typed-sign-v3v4/simulation/simulation.tsx:18-22) checks decodingData?.error and falls through to either the permit fallback or the "simulation unavailable" placeholder in DecodedSimulation. Returning the same shape keeps the wallet on a known-graceful code path with no errors logged.

Why regex, not exact URLs. Same rationale as Tier 2: covers any future chainId without re-introducing live requests when a new chain is added to default fixtures. Sanity-checked against the 3 chainIds in the previous allowlist (0x1, 0x539, 0xaa36a7), plus mixed-case hex, plus rejection cases (non-hex, extra query params, different host).

Spec audit. Grepped E2E specs that exercise SignTypedDataV3/V4:

  • tests/smoke/confirmations/signatures/signatures-typed.spec.ts — V3/V4 cases on chainId=0x539. Will trigger the mock. Assertions are on row components (AccountNetwork, Message, OriginInfo); no asserts on decoded simulation content. Safe.
  • tests/smoke/confirmations/signatures/alert-system.spec.ts — V1 only on Sepolia (0xaa36a7). V1 doesn't call the API per SDK code. Unrelated.
  • Snap and api-spec tests — peripheral, no decoded-content asserts.

No spec asserts on decodingData.stateChanges rendering, so the default mock is safe across the codebase.

Files changed

  • tests/api-mocking/mock-responses/defaults/signature-insights.ts — new
  • tests/api-mocking/mock-responses/defaults/index.ts — import + spread into DEFAULT_MOCKS.POST
  • tests/api-mocking/mock-e2e-allowlist.ts — removed 3 entries

Out of scope

  • NFT API entries (/users/tokens, /collections, /explore/sites, prod/dev/uat hosts) — deferred to separate Tier 3 tickets

Changelog

CHANGELOG entry: null

Related issues

MMQA-1779 — parent epic MMQA-1364

Manual testing steps

Feature: signature-insights default mock for E2E tests

  Scenario: SignTypedDataV4 confirmation does not hit live signature-insights
    Given the E2E mock server is running with default mocks loaded
    And a dapp is connected on any EVM chain
    When the user triggers an eth_signTypedData_v4 request
    Then mockttp returns the UNSUPPORTED_SIGNATURE error shape
    And the wallet renders the "simulation unavailable" placeholder
    And validateLiveRequests() does not record a live request to signature-insights

Screenshots/Recordings

Before

Every eth_signTypedData_v3 / _v4 exercised by smoke specs fired a live POST to signature-insights.api.cx.metamask.io. The 3 chainId-specific allowlist entries silenced validateLiveRequests(), but the call still reached the live decoding API and whatever it returned was rendered as decoded state changes in the wallet UI.

After

mockttp intercepts the POST and returns the SDK's own UNSUPPORTED_SIGNATURE error shape. The wallet's TypedSignV3V4Simulation checks decodingData?.error and falls through to the confirm.simulation.unavailable placeholder in DecodedSimulation — the same path the wallet takes when the API errors live. Spec assertions on row components (origin, message, account/network) continue to pass. validateLiveRequests() records zero leaks for signature-insights.

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Low Risk
Low risk: test-only changes that replace live signature-insights requests with a deterministic mock and tighten the E2E allowlist.

Overview
E2E tests no longer rely on live calls to signature-insights.api.cx.metamask.io: the PR removes the chainId-specific allowlisted URLs and adds a default POST mock that matches any hex chainId and returns an UNSUPPORTED_SIGNATURE error shape.

The new SIGNATURE_INSIGHTS_MOCKS is wired into DEFAULT_MOCKS.POST, reducing network leakage during signature-related smoke tests.

Reviewed by Cursor Bugbot for commit 8335a5e. Bugbot is set up for automated code reviews on this repo. Configure here.

Adds a default POST mock for the signature decoding API used by
@metamask/signature-controller during SignTypedDataV3/V4 flows, then
removes the three corresponding allowlist entries.

- POST signature-insights.api.cx.metamask.io/v1/signature?chainId=0x...
  → returns the SDK's own UNSUPPORTED_SIGNATURE error shape, which the
  wallet handles by rendering the simulation "unavailable" placeholder

Regex matcher covers any chainId, so adding new chains to default
fixtures won't reintroduce live requests.

Tier 3 of MMQA-1364, scoped to signature-insights only. NFT API entries
are deferred to follow-up tickets.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbotv2 metamaskbotv2 Bot added the team-qa QA team label Apr 30, 2026
@chrisleewilcox chrisleewilcox marked this pull request as ready for review May 1, 2026 00:20
@chrisleewilcox chrisleewilcox requested a review from a team as a code owner May 1, 2026 00:20
@chrisleewilcox chrisleewilcox added no-changelog no-changelog Indicates no external facing user changes, therefore no changelog documentation needed no changelog required No changelog entry is required for this change skip-e2e-flakiness-detection Skips the E2E flakiness detection (extra runs on new and modified E2E files) skip-smart-e2e-selection Skip Smart E2E selection, i.e. select all E2E tests to run and removed skip-e2e-flakiness-detection Skips the E2E flakiness detection (extra runs on new and modified E2E files) labels May 1, 2026
@codecov-commenter

codecov-commenter commented May 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.92%. Comparing base (51b6bbd) to head (8335a5e).
⚠️ Report is 26 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #29601      +/-   ##
==========================================
- Coverage   82.15%   81.92%   -0.24%     
==========================================
  Files        5178     5184       +6     
  Lines      137450   137830     +380     
  Branches    31079    31193     +114     
==========================================
- Hits       112924   112919       -5     
- Misses      16875    17237     +362     
- Partials     7651     7674      +23     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@chrisleewilcox chrisleewilcox removed the skip-smart-e2e-selection Skip Smart E2E selection, i.e. select all E2E tests to run label May 1, 2026
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeConfirmations
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: low
  • AI Confidence: 88%
click to see 🤖 AI reasoning details

E2E Test Selection:
The three changed files are all in the E2E test infrastructure (api-mocking layer):

  1. signature-insights.ts (NEW): Creates a default mock for signature-insights.api.cx.metamask.io/v1/signature using a regex pattern matching any chainId. Returns a standard UNSUPPORTED_SIGNATURE response (200 OK).

  2. defaults/index.ts: Imports and spreads SIGNATURE_INSIGHTS_MOCKS into the DEFAULT_MOCKS.POST array, making this mock active for ALL E2E tests by default (via FixtureHelper.ts which uses DEFAULT_MOCKS).

  3. mock-e2e-allowlist.ts: Removes three specific signature-insights URLs from the allowlist (chainId=0x539, 0x1, 0xaa36a7). These were previously allowed to make live network requests; now they are properly mocked.

Why SmokeConfirmations: The signature-insights.api.cx.metamask.io endpoint is used during signature confirmation flows (personal_sign, EIP-712 typed data signing, SIWE). SmokeConfirmations tests these exact flows. The change from live requests to mocked responses could affect test behavior if any confirmation test was relying on the live response or the allowlist behavior.

Risk is LOW because:

  • This is a test infrastructure improvement (mocking > live calls = more deterministic)
  • The mock returns a valid, expected response (UNSUPPORTED_SIGNATURE is the standard response for test scenarios)
  • The regex covers all chainIds, so no test should be left without a mock
  • No app code was changed

No performance tests needed: These are purely test infrastructure changes with no impact on app rendering, data loading, or runtime performance.

Performance Test Selection:
These changes are purely in the E2E test mocking infrastructure (api-mocking layer). No app code was modified, so there is no impact on app performance, rendering, or runtime behavior. Performance tests are not warranted.

View GitHub Actions results

@sonarqubecloud

sonarqubecloud Bot commented May 1, 2026

Copy link
Copy Markdown

@chrisleewilcox chrisleewilcox enabled auto-merge May 1, 2026 04:38
@chrisleewilcox chrisleewilcox added this pull request to the merge queue May 1, 2026
Merged via the queue into main with commit 4e72f3f May 1, 2026
501 of 507 checks passed
@chrisleewilcox chrisleewilcox deleted the MMQA-1779-tier-3-signature-insights-mocks branch May 1, 2026 15:01
@github-actions github-actions Bot locked and limited conversation to collaborators May 1, 2026
@metamaskbotv2 metamaskbotv2 Bot added the release-7.77.0 Issue or pull request that will be included in release 7.77.0 label May 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

no changelog required No changelog entry is required for this change no-changelog no-changelog Indicates no external facing user changes, therefore no changelog documentation needed release-7.77.0 Issue or pull request that will be included in release 7.77.0 size-S team-qa QA team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants