Files
insforge--insforge/backend/tests/unit/stripe-checkout.service.test.ts
wehub-resource-sync 3a28426bf4
Lint and Format Check / lint-and-format (push) Failing after 0s
Check Migrations / Check for duplicate migration numbers (push) Failing after 1s
CI Pre-merge Check / CI Pre-merge Check (push) Failing after 2m17s
chore: import upstream snapshot with attribution
2026-07-13 12:23:40 +08:00

104 lines
3.3 KiB
TypeScript

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();
});
});