Files
a6276c536c tests(web): implement new testing strategy phases (#7420)
* tests(web): implement testing strategy phases 1-5

Phase 1 — Extract pure logic from large untested components:
- GlobalPushNotifications: 13 functions → utils.ts (43 tests)
- FirstSteps: calculateProgress → utils.ts (6 tests)
- ReviewStep: 7 functions → utils.ts (27 tests)
- NestedSafesPopover: 7 functions → utils.ts (23 tests)

Phase 2 — Unified mock infrastructure:
- createTestServer() factory in config/test/msw/testServer.ts
- renderWithScenario() utility in scenario-utils.tsx
- Bridges Jest and Storybook mock ecosystems (9 tests)

Phase 3 — API contract tests:
- Fixture-schema validation with ajv against OpenAPI schema (22 tests)
- Auto-generated types sync check with hash-based script (1 test)

Phase 4 — Component test coverage:
- TxNonce component tests (18 tests)
- FirstSteps component tests (15 tests)
- AssetsTable component tests (8 tests)

Phase 5 — Feature flag matrix tests:
- 15 features verified for disabled/loading/enabled states (77 tests)

Total: ~141 new tests, 0 regressions, 0 type errors.

* tests(web): remove unused imports in TxNonce test

* tests(web): address PR review comments

- Fix typo: _shouldUnregsiterSelectedSafes → _shouldUnregisterSelectedSafes
- Improve convertNullable type safety with destructuring
- Clarify MSW first-match behavior in testServer comment
- Document _resetFeatureRegistry cleanup rationale
- Use explicit return (acc + length) instead of acc += mutation
- Add instancePath to schema validation error messages
- Document 'empty' scenario fallback in renderWithScenario

* chore(store): regenerate AUTO_GENERATED files from staging API

Upstream API changes: relay task status endpoint, updated gasLimit
description, deadlock analysis types in safe-shield.

* tests(web): address PR review - revert PushNotifications refactor, use MSW fixtures in AssetsTable test

- Revert GlobalPushNotifications utils extraction (should be a separate PR)
- Refactor AssetsTable test to use shared MSW fixtures and test builders
  instead of inline mock data

---------

Co-authored-by: Hanzo Dev <[email protected]>
2026-03-18 11:40:00 +01:00

76 lines
2.8 KiB
TypeScript

import { setupServer } from 'msw/node'
import type { RequestHandler } from 'msw'
import { handlers as baseHandlers } from './handlers'
import {
fixtureHandlers,
createChainHandlersFromFixture,
createBalanceHandlersFromFixture,
createPositionHandlersFromFixture,
createPortfolioHandlersFromFixture,
createSafeAppsHandlersFromFixture,
} from './handlers/fromFixtures'
import type { FixtureScenario } from './fixtures'
import { FEATURES } from '@safe-global/utils/utils/chains'
const DEFAULT_GATEWAY_URL = process.env.NEXT_PUBLIC_GATEWAY_URL_STAGING || 'https://safe-client.staging.5afe.dev'
/**
* Options for createTestServer
*/
export interface TestServerOptions {
/**
* Fixture scenario to add on top of the base handlers.
* When provided, scenario handlers are prepended so they take precedence over base handlers
* for the same endpoints (MSW matches the first registered handler).
* @default undefined — only base handlers are used
*/
scenario?: FixtureScenario
/**
* Additional MSW handlers prepended before all others (highest priority, can override anything)
*/
handlers?: RequestHandler[]
}
/**
* Creates an MSW server that wraps the standard test handler baseline.
*
* The base `handlers` from `config/test/msw/handlers.ts` are always included to maintain
* backward compatibility with existing tests. Optionally, fixture-scenario handlers can be
* added for richer data in new tests (they take precedence over the base handlers).
*
* Extra handlers are added last and take the highest priority.
*
* @example
* // Default — identical to the existing global server, backward-compatible
* const server = createTestServer()
*
* @example
* // Fixture scenario for richer data
* const server = createTestServer({ scenario: 'efSafe' })
*
* @example
* // Override a single handler per test
* server.use(http.get(/\/v1\/chains/, () => HttpResponse.error()))
*/
export function createTestServer(options: TestServerOptions = {}) {
const { scenario, handlers: extraHandlers = [] } = options
const gatewayUrl = DEFAULT_GATEWAY_URL
const scenarioHandlers: RequestHandler[] =
scenario === 'empty'
? [
...createChainHandlersFromFixture(gatewayUrl, [FEATURES.POSITIONS, FEATURES.PORTFOLIO_ENDPOINT]),
...createBalanceHandlersFromFixture('empty', gatewayUrl),
...createPositionHandlersFromFixture('empty', gatewayUrl),
...createPortfolioHandlersFromFixture('empty', gatewayUrl),
...createSafeAppsHandlersFromFixture(gatewayUrl, true),
]
: scenario
? fixtureHandlers[scenario](gatewayUrl)
: []
// MSW uses first-match: extraHandlers override scenario & base, scenario overrides base
return setupServer(...extraHandlers, ...scenarioHandlers, ...baseHandlers(gatewayUrl))
}