import { CartStore } from '../src/checkout/cart.store'; import { CheckoutStore } from '../src/checkout/checkout.store'; import { holdOrderStock } from '../src/checkout/stock-allocation'; import { orderView } from '../src/checkout/order-view'; import type { AccessStore } from '../src/identity/access.store'; import type { Principal } from '../src/identity/identity.types'; import { Prisma, type Order } from '../src/generated/prisma/client'; const actor = { userId: 'user', organizationId: 'org' } as Principal; function accessFor(tx: unknown) { return { mutate: ( _actor: unknown, _permission: unknown, work: (tx: unknown) => unknown, ) => work(tx), } as AccessStore; } describe('checkout resource limits and expiration', () => { it('rejects a 21st cart line before writing', async () => { const tx = { cart: { upsert: jest.fn().mockResolvedValue({ id: 'cart', version: 1 }) }, productVariant: { findFirst: jest.fn().mockResolvedValue({ currency: 'INR' }), }, cartLine: { findMany: jest.fn().mockResolvedValue( Array.from({ length: 20 }, (_, index) => ({ variantId: String(index), variant: { currency: 'INR' }, })), ), upsert: jest.fn(), }, }; await expect( new CartStore(accessFor(tx)).set(actor, 'new', 1, 1), ).rejects.toMatchObject({ code: 'CART_LIMIT' }); expect(tx.cartLine.upsert).not.toHaveBeenCalled(); }); it('rejects an eleventh active order before creating an order or stock hold', async () => { const tx = { order: { findUnique: jest.fn().mockResolvedValue(null), count: jest.fn().mockResolvedValue(10), create: jest.fn(), }, }; await expect( new CheckoutStore(accessFor(tx)).create(actor, { cartVersion: 1, addressId: 'address', idempotencyKey: 'key', }), ).rejects.toMatchObject({ code: 'ORDER_LIMIT' }); expect(tx.order.create).not.toHaveBeenCalled(); }); it('bounds stock allocation work before acquiring locks', async () => { const tx = { stockItem: { findMany: jest.fn().mockResolvedValue(Array(201).fill({})) }, $queryRaw: jest.fn(), }; await expect( holdOrderStock( tx as unknown as Prisma.TransactionClient, actor, 'order', new Date(), [], ), ).rejects.toMatchObject({ code: 'STOCK_ALLOCATION_LIMIT' }); expect(tx.$queryRaw).not.toHaveBeenCalled(); }); it('exposes expiry without pretending an unfinalized order is payable', () => { const order: Order & { lines: [] } = { id: 'order', organizationId: 'org', userId: 'user', status: 'PENDING_PAYMENT', currency: 'INR', subtotal: new Prisma.Decimal(1), discount: new Prisma.Decimal(0), merchandiseTotal: new Prisma.Decimal(1), addressSnapshot: {}, couponSnapshot: null, couponId: null, idempotencyKey: 'key', requestHash: 'hash', createdAt: new Date(0), expiresAt: new Date(1), lines: [], }; expect(orderView(order)).toMatchObject({ status: 'EXPIRED', payableTotal: null, paymentAvailable: false, }); expect(orderView({ ...order, status: 'CANCELLED' }).status).toBe( 'CANCELLED', ); }); });