From fdc2d1aa8b82991e897a11b1bd97dd2f21e8258f Mon Sep 17 00:00:00 2001 From: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com> Date: Mon, 10 Aug 2026 12:58:28 +0200 Subject: [PATCH 1/2] test: mock chargeback API dates as ISO strings, matching JSON transport The unit tests for the pending-chargeback screen and hook mocked the API payload with Date instances, but over JSON transport these fields arrive as ISO strings. The rendering path handles both, yet the tests could stay green through a regression that only breaks on string input. Introduce a transport-shaped payload type (dates as strings, mirroring the e2e spec fixtures) and cast once at the mock boundary, so the tests exercise the same data shape the real backend delivers. --- .../compliance-chargeback-list.screen.test.tsx | 16 +++++++++++----- .../compliance-pending-chargebacks.hook.test.ts | 12 +++++++++--- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/__tests__/compliance-chargeback-list.screen.test.tsx b/src/__tests__/compliance-chargeback-list.screen.test.tsx index 501d9deee..542d8584f 100644 --- a/src/__tests__/compliance-chargeback-list.screen.test.tsx +++ b/src/__tests__/compliance-chargeback-list.screen.test.tsx @@ -42,10 +42,16 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { ChargebackBlockReason, PendingChargebackEntry } from 'src/dto/chargeback.dto'; import ComplianceChargebackListScreen from 'src/screens/compliance-chargeback-list.screen'; -const REQUESTED = new Date('2026-01-15T10:00:00.000Z'); -const DATE = new Date('2026-01-15T12:00:00.000Z'); +type PendingChargebackPayload = Omit & { + requestedDate: string; + date: string; + chargebackDate?: string; +}; -function baseEntry(overrides: Partial = {}): PendingChargebackEntry { +const REQUESTED = '2026-01-15T10:00:00.000Z'; +const DATE = '2026-01-15T12:00:00.000Z'; + +function baseEntry(overrides: Partial = {}): PendingChargebackEntry { return { txId: 9001, uid: 'T-9001', @@ -61,7 +67,7 @@ function baseEntry(overrides: Partial = {}): PendingChar requestedDate: REQUESTED, date: DATE, ...overrides, - }; + } as unknown as PendingChargebackEntry; } interface Deferred { @@ -194,7 +200,7 @@ describe('ComplianceChargebackListScreen', () => { entityId: 1005, blockReasons: [ChargebackBlockReason.MISSING_CREDITOR_DATA], userName: 'Sentinel User', - chargebackDate: new Date('2026-02-01T00:00:00.000Z'), + chargebackDate: '2026-02-01T00:00:00.000Z', }); const multiReason = baseEntry({ diff --git a/src/__tests__/compliance-pending-chargebacks.hook.test.ts b/src/__tests__/compliance-pending-chargebacks.hook.test.ts index e0c59b7e3..4cded60e8 100644 --- a/src/__tests__/compliance-pending-chargebacks.hook.test.ts +++ b/src/__tests__/compliance-pending-chargebacks.hook.test.ts @@ -36,6 +36,12 @@ jest.mock('../hooks/navigation.hook', () => ({ import { useCompliance } from '../hooks/compliance.hook'; import { ChargebackBlockReason, PendingChargebackEntry } from '../dto/chargeback.dto'; +type PendingChargebackPayload = Omit & { + requestedDate: string; + date: string; + chargebackDate?: string; +}; + describe('useCompliance().getPendingChargebacks', () => { beforeEach(() => { // react-scripts sets resetMocks:true, which wipes implementations before each test @@ -43,7 +49,7 @@ describe('useCompliance().getPendingChargebacks', () => { }); it('issues GET support/pending-chargebacks and returns the payload', async () => { - const payload: PendingChargebackEntry[] = [ + const payload: PendingChargebackPayload[] = [ { txId: 9001, uid: 'T-9001', @@ -56,8 +62,8 @@ describe('useCompliance().getPendingChargebacks', () => { chargebackAmount: 100, chargebackAsset: 'EUR', blockReasons: [ChargebackBlockReason.MISSING_CHARGEBACK_AMOUNT], - requestedDate: new Date('2026-01-15T10:00:00.000Z'), - date: new Date('2026-01-15T10:00:00.000Z'), + requestedDate: '2026-01-15T10:00:00.000Z', + date: '2026-01-15T10:00:00.000Z', }, ]; mockCall.mockResolvedValue(payload); From 80db5d7636ce727837ecd2291ad80f0509573f1e Mon Sep 17 00:00:00 2001 From: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:14:26 +0200 Subject: [PATCH 2/2] test: simulate JSON transport at the mock boundary Route every successful mock payload through a JSON round-trip helper. This mirrors what response.json() actually delivers: keys set to undefined are dropped instead of being present, and the resolved value is no longer the same object reference as the fixture, so an in-place mutation inside the hook chain can no longer hide behind toEqual. Also assert the raw ISO string on the hook result explicitly. --- ...compliance-chargeback-list.screen.test.tsx | 37 +++++++++++-------- ...ompliance-pending-chargebacks.hook.test.ts | 8 +++- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/__tests__/compliance-chargeback-list.screen.test.tsx b/src/__tests__/compliance-chargeback-list.screen.test.tsx index 542d8584f..16435eebc 100644 --- a/src/__tests__/compliance-chargeback-list.screen.test.tsx +++ b/src/__tests__/compliance-chargeback-list.screen.test.tsx @@ -48,6 +48,11 @@ type PendingChargebackPayload = Omit(value: T): T { + return JSON.parse(JSON.stringify(value)) as T; +} + const REQUESTED = '2026-01-15T10:00:00.000Z'; const DATE = '2026-01-15T12:00:00.000Z'; @@ -96,7 +101,7 @@ describe('ComplianceChargebackListScreen', () => { beforeEach(() => { jest.clearAllMocks(); mockIsLoggedIn = true; - mockGetPendingChargebacks.mockResolvedValue([]); + mockGetPendingChargebacks.mockResolvedValue(asTransport([])); }); it('does not fetch when not logged in', () => { @@ -117,7 +122,7 @@ describe('ComplianceChargebackListScreen', () => { expect(screen.queryByRole('table')).not.toBeInTheDocument(); expect(screen.queryByTestId('error-hint')).not.toBeInTheDocument(); - deferred.resolve([]); + deferred.resolve(asTransport([])); await waitFor(() => { expect(screen.queryByTestId('loading-spinner')).not.toBeInTheDocument(); }); @@ -138,7 +143,7 @@ describe('ComplianceChargebackListScreen', () => { }); it('shows the empty-state row when the response is a successful empty list', async () => { - mockGetPendingChargebacks.mockResolvedValue([]); + mockGetPendingChargebacks.mockResolvedValue(asTransport([])); render(); @@ -223,15 +228,17 @@ describe('ComplianceChargebackListScreen', () => { userName: 'No Reasons User', }); - mockGetPendingChargebacks.mockResolvedValue([ - plainMissing, - nameMismatch, - nameMismatchMissingNames, - userNotReleased, - sentinel, - multiReason, - noBlockReasons, - ]); + mockGetPendingChargebacks.mockResolvedValue( + asTransport([ + plainMissing, + nameMismatch, + nameMismatchMissingNames, + userNotReleased, + sentinel, + multiReason, + noBlockReasons, + ]), + ); render(); @@ -330,7 +337,7 @@ describe('ComplianceChargebackListScreen', () => { blockReasons: [ChargebackBlockReason.MISSING_CHARGEBACK_AMOUNT], }); - mockGetPendingChargebacks.mockResolvedValue([withAsset, withoutAsset, nullAmounts, zeroAmount]); + mockGetPendingChargebacks.mockResolvedValue(asTransport([withAsset, withoutAsset, nullAmounts, zeroAmount])); render(); @@ -374,7 +381,7 @@ describe('ComplianceChargebackListScreen', () => { userName: 'Empty Uid', }); - mockGetPendingChargebacks.mockResolvedValue([withUid, emptyUid]); + mockGetPendingChargebacks.mockResolvedValue(asTransport([withUid, emptyUid])); render(); @@ -392,7 +399,7 @@ describe('ComplianceChargebackListScreen', () => { entityId: 1301, userName: 'Clickable User', }); - mockGetPendingChargebacks.mockResolvedValue([entry]); + mockGetPendingChargebacks.mockResolvedValue(asTransport([entry])); render(); diff --git a/src/__tests__/compliance-pending-chargebacks.hook.test.ts b/src/__tests__/compliance-pending-chargebacks.hook.test.ts index 4cded60e8..59f4567b5 100644 --- a/src/__tests__/compliance-pending-chargebacks.hook.test.ts +++ b/src/__tests__/compliance-pending-chargebacks.hook.test.ts @@ -42,6 +42,11 @@ type PendingChargebackPayload = Omit(value: T): T { + return JSON.parse(JSON.stringify(value)) as T; +} + describe('useCompliance().getPendingChargebacks', () => { beforeEach(() => { // react-scripts sets resetMocks:true, which wipes implementations before each test @@ -66,7 +71,7 @@ describe('useCompliance().getPendingChargebacks', () => { date: '2026-01-15T10:00:00.000Z', }, ]; - mockCall.mockResolvedValue(payload); + mockCall.mockResolvedValue(asTransport(payload)); const { result } = renderHook(() => useCompliance()); @@ -78,5 +83,6 @@ describe('useCompliance().getPendingChargebacks', () => { method: 'GET', }); expect(entries).toEqual(payload); + expect(entries[0].requestedDate).toBe('2026-01-15T10:00:00.000Z'); }); });