import { identityApp, type IdentityApp } from './helpers/identity-app'; import { checkoutFixture } from './helpers/checkout'; import { secondActor, seedProduct } from './helpers/commerce'; describe('private versioned carts', () => { let ctx: IdentityApp; beforeAll(async () => { ctx = await identityApp(); }); afterAll(async () => { await ctx.close(); }); beforeEach(async () => { await ctx.clearLimits(); }); it('isolates carts, rejects stale edits and removes lines', async () => { const f = await checkoutFixture(ctx); const other = await secondActor(ctx); const own = await ctx .api() .get('/api/v1/cart') .auth(f.actor.token, { type: 'bearer' }) .expect(200); expect(own.body.lines).toHaveLength(1); const empty = await ctx .api() .get('/api/v1/cart') .auth(other.token, { type: 'bearer' }) .expect(200); expect(empty.body).toEqual({ version: 0, lines: [] }); const stale = await ctx .api() .put('/api/v1/cart/lines/' + f.variant.id) .auth(f.actor.token, { type: 'bearer' }) .send({ quantity: 3, version: 0 }) .expect(409); expect(stale.body.code).toBe('CART_CHANGED'); await ctx .api() .put('/api/v1/cart/lines/' + f.variant.id) .auth(f.actor.token, { type: 'bearer' }) .send({ quantity: 3, version: 1 }) .expect(200); await ctx .api() .delete('/api/v1/cart/lines/' + f.variant.id) .auth(f.actor.token, { type: 'bearer' }) .send({ version: 2 }) .expect(200); const result = await ctx .api() .get('/api/v1/cart') .auth(f.actor.token, { type: 'bearer' }) .expect(200); expect(result.body).toEqual({ version: 3, lines: [] }); await ctx.api().get('/api/v1/cart').expect(401); }); it('rejects draft, foreign and mixed-currency items and mass assignment', async () => { const f = await checkoutFixture(ctx); const draft = await seedProduct(ctx); await ctx .api() .put('/api/v1/cart/lines/' + draft.variant.id) .auth(f.actor.token, { type: 'bearer' }) .send({ quantity: 1, version: 1 }) .expect(409); const foreign = await secondActor(ctx, false); await ctx .api() .put('/api/v1/cart/lines/' + f.variant.id) .auth(foreign.token, { type: 'bearer' }) .send({ quantity: 1, version: 0 }) .expect(409); const usd = await seedProduct(ctx, true); await ctx.db.productVariant.update({ where: { id: usd.variant.id }, data: { currency: 'USD' }, }); const response = await ctx .api() .put('/api/v1/cart/lines/' + usd.variant.id) .auth(f.actor.token, { type: 'bearer' }) .send({ quantity: 1, version: 1 }) .expect(409); expect(response.body.code).toBe('CART_CURRENCY'); await ctx .api() .put('/api/v1/cart/lines/' + f.variant.id) .auth(f.actor.token, { type: 'bearer' }) .send({ quantity: 1, version: 1, price: '0.01' }) .expect(400); }); });