import { beforeEach, describe, expect, it, vi } from 'vitest'; import { ERROR_CODES } from '@insforge/shared-schemas'; const { mockClient, mockPool } = vi.hoisted(() => ({ mockClient: { query: vi.fn(), release: vi.fn(), }, mockPool: { connect: vi.fn(), }, })); vi.mock('../../src/infra/database/database.manager', () => ({ DatabaseManager: { getInstance: () => ({ getPool: () => mockPool, }), }, })); import { StripeCheckoutService } from '../../src/services/payments/stripe/checkout.service'; describe('StripeCheckoutService', () => { beforeEach(() => { vi.clearAllMocks(); mockClient.query.mockReset(); mockClient.release.mockReset(); mockPool.connect.mockResolvedValue(mockClient); }); it('rejects reused idempotency keys when the metadata differs', async () => { mockClient.query.mockImplementation(async (sql: string) => { if ( sql === 'BEGIN' || sql === 'ROLLBACK' || sql === 'RESET ROLE' || sql.startsWith('SET LOCAL ROLE') || sql === 'SELECT set_config($1, $2, true)' ) { return { rows: [], rowCount: 0 }; } if (/INSERT INTO payments\.stripe_checkout_sessions/i.test(sql)) { return { rows: [], rowCount: 0 }; } if (/FROM payments\.stripe_checkout_sessions/i.test(sql)) { return { rows: [], rowCount: 0 }; } throw new Error(`Unexpected query: ${sql}`); }); const service = StripeCheckoutService.getInstance(); await expect( service.insertInitializedCheckoutSession( { environment: 'test', mode: 'payment', lineItems: [{ priceId: 'price_123', quantity: 1 }], successUrl: 'https://example.com/success', cancelUrl: 'https://example.com/cancel', customerEmail: 'buyer@example.com', subject: { type: 'team', id: 'team_123' }, idempotencyKey: 'checkout_123', }, { plan: 'pro', source: 'agent' }, { id: '00000000-0000-4000-8000-000000000001', email: 'buyer@example.com', role: 'authenticated', } ) ).rejects.toMatchObject({ statusCode: 409, code: ERROR_CODES.PAYMENT_CHECKOUT_ALREADY_EXISTS, }); expect( mockClient.query.mock.calls.some(([sql]) => /request_hash = \$3/.test(String(sql))) ).toBe(true); expect( mockClient.query.mock.calls.some(([sql]) => /metadata - \$11::TEXT = \$12::JSONB/.test(String(sql)) ) ).toBe(true); const insertCall = mockClient.query.mock.calls.find(([sql]) => /INSERT INTO payments\.stripe_checkout_sessions/i.test(String(sql)) ); const lookupCall = mockClient.query.mock.calls.find(([sql]) => /FROM payments\.stripe_checkout_sessions/i.test(String(sql)) ); expect(insertCall?.[1]?.[9]).toBe('checkout_123'); expect(insertCall?.[1]?.[10]).toEqual(expect.stringMatching(/^[a-f0-9]{64}$/)); expect(insertCall?.[1]?.[11]).toBe(JSON.stringify({ plan: 'pro', source: 'agent' })); expect(lookupCall?.[1]?.[2]).toBe(insertCall?.[1]?.[10]); expect(lookupCall?.[1]?.[10]).toBe('insforge_checkout_session_id'); expect(lookupCall?.[1]?.[11]).toBe(JSON.stringify({ plan: 'pro', source: 'agent' })); expect(mockClient.release).toHaveBeenCalled(); }); });