diff --git a/src/components/Claim/Claim.tsx b/src/components/Claim/Claim.tsx index 88c9452358..2fc5ea0bb1 100644 --- a/src/components/Claim/Claim.tsx +++ b/src/components/Claim/Claim.tsx @@ -179,7 +179,10 @@ export const Claim = ({}) => { initials: getInitialsFromName(recipientName), memo: claimLinkData.textContent, attachmentUrl: claimLinkData.fileUrl, - cancelledDate: status === 'cancelled' ? new Date(claimLinkData.events[0]?.timestamp) : undefined, + cancelledDate: + status === 'cancelled' && claimLinkData.events?.[0] + ? new Date(claimLinkData.events[0].timestamp) + : undefined, txHash: claimLinkData.claim?.txHash, extraDataForDrawer: { isLinkTransaction: true, diff --git a/src/components/Claim/__tests__/claim-states.test.tsx b/src/components/Claim/__tests__/claim-states.test.tsx index 231b20f5e2..944e23dcfc 100644 --- a/src/components/Claim/__tests__/claim-states.test.tsx +++ b/src/components/Claim/__tests__/claim-states.test.tsx @@ -385,6 +385,36 @@ describe('GROUP 3: Already Claimed / Cancelled', () => { }) }) + // GET /send-links/:pubKey answers a cache hit with the raw Prisma row, which + // carries `intents` instead of the projected `claim` + `events`. Claim.tsx read + // `events[0]` unguarded and took the whole page down (PEANUT-UI-SJ0). + test('CANCELLED link renders when the API omits claim/events (cache-hit shape)', async () => { + mockUseAuth.mockReturnValue({ + user: { user: { userId: 'sender-123' } }, + isFetchingUser: false, + fetchUser: jest.fn(), + }) + + const { + events: _events, + claim: _claim, + ...unprojected + } = makeSendLink({ + status: 'CANCELLED', + sender: { userId: 'sender-123', username: 'alice' }, + }) + mockSendLinksApi.get.mockResolvedValue(unprojected) + + renderClaim() + + // Gates on the receipt, which only renders once the transaction memo has + // produced a value — asserting on ClaimedView settles too early to catch + // a throw inside the memo. + await waitFor(() => { + expect(screen.getByTestId('transaction-details-receipt')).toBeInTheDocument() + }) + }) + test('CLAIMING link (in progress) shows as already claimed', async () => { const link = makeSendLink({ status: 'CLAIMING' }) mockSendLinksApi.get.mockResolvedValue(link) diff --git a/src/services/services.types.ts b/src/services/services.types.ts index 4cc97869fe..99be569dcc 100644 --- a/src/services/services.types.ts +++ b/src/services/services.types.ts @@ -374,7 +374,8 @@ export type SendLink = { }[] } } - events: { + /** Absent post-ledger-collapse: the API no longer selects the `events` relation. */ + events?: { timestamp: Date status: SendLinkStatus reason?: string