import { randomUUID } from 'node:crypto'; import { identityApp, type IdentityApp } from './helpers/identity-app'; import { checkoutFixture } from './helpers/checkout'; import * as audit from '../src/identity/audit'; describe('checkout allocation and final-write rollback', () => { let ctx: IdentityApp; beforeAll(async () => { ctx = await identityApp(); }, 60000); afterAll(async () => { await ctx.close(); }); beforeEach(async () => { await ctx.clearLimits(); }); afterEach(() => { jest.restoreAllMocks(); }); it('rolls back order, holds and cart clearing when the audit write fails', async () => { const f = await checkoutFixture(ctx); jest .spyOn(audit, 'recordAudit') .mockRejectedValueOnce(new Error('Synthetic audit failure')); const result = await ctx .api() .post('/api/v1/checkout') .auth(f.actor.token, { type: 'bearer' }) .send(f.input) .expect(500); expect(result.body.code).toBe('INTERNAL_FAILURE'); expect(JSON.stringify(result.body)).not.toContain('Synthetic'); expect( await ctx.db.order.count({ where: { userId: f.actor.userId } }), ).toBe(0); expect( await ctx.db.stockReservation.count({ where: { userId: f.actor.userId }, }), ).toBe(0); const cart = await ctx .api() .get('/api/v1/cart') .auth(f.actor.token, { type: 'bearer' }) .expect(200); expect(cart.body.version).toBe(1); expect(cart.body.lines).toHaveLength(1); await ctx .api() .post('/api/v1/checkout') .auth(f.actor.token, { type: 'bearer' }) .send(f.input) .expect(201); }); it('splits a line across warehouses without consuming on-hand stock', async () => { const f = await checkoutFixture(ctx, 1); const warehouse = await ctx.db.warehouse.create({ data: { organizationId: f.actor.organizationId, name: randomUUID() }, }); const stock = await ctx.db.stockItem.create({ data: { organizationId: f.actor.organizationId, warehouseId: warehouse.id, variantId: f.variant.id, }, }); await ctx .api() .post('/api/v1/inventory/adjustments') .auth(ctx.token, { type: 'bearer' }) .send({ stockItemId: stock.id, delta: 1, reason: 'Opening balance', idempotencyKey: randomUUID(), }) .expect(201); const result = await ctx .api() .post('/api/v1/checkout') .auth(f.actor.token, { type: 'bearer' }) .send(f.input) .expect(201); const holds = await ctx.db.stockReservation.findMany({ where: { orderId: result.body.id }, }); expect(holds).toHaveLength(2); expect(holds.map((hold) => hold.quantity)).toEqual([1, 1]); }); it('revalidates product availability and currency when checking out a saved cart', async () => { const f = await checkoutFixture(ctx); await ctx.db.productVariant.update({ where: { id: f.variant.id }, data: { active: false }, }); const response = await ctx .api() .post('/api/v1/checkout') .auth(f.actor.token, { type: 'bearer' }) .send(f.input) .expect(409); expect(response.body.code).toBe('CART_ITEM_UNAVAILABLE'); expect( await ctx.db.order.count({ where: { userId: f.actor.userId } }), ).toBe(0); }); });