srs-api/src/services/orderEdit.test.ts
Aswin Biju 61514fb82f
All checks were successful
deploy / test (push) Successful in 1m33s
deploy / deploy (push) Successful in 18s
feat(users): added a wizard to reset a password and supporting services for the srs PWA
2026-11-04 20:44:36 +05:30

88 lines
3.3 KiB
TypeScript

import { beforeEach, describe, expect, it } from 'vitest';
import type { Db } from '../db';
import { makeDb, seedFixture, seedOrder, type Fixture } from '../testing/helpers';
import { RuleError } from './accountRules';
import { cancelOrder, removeLine, setLineQty } from './orderEdit';
import { getUserById } from './users';
let db: Db;
let f: Fixture;
let orderId: number;
const shopUser = () => getUserById(db, f.shopUser.id)!;
const lines = () =>
db.prepare('SELECT ending, qty FROM order_lines WHERE order_id = ? ORDER BY ending').all(orderId) as Array<{ ending: string; qty: number }>;
const order = () =>
db.prepare('SELECT status, edited_at FROM orders WHERE id = ?').get(orderId) as { status: string; edited_at: string | null };
beforeEach(() => {
db = makeDb();
f = seedFixture(db);
orderId = seedOrder(db, { shopId: f.shops.a, userId: f.shopUser.id, date: '2026-11-02', lines: [['1234', 2], ['1234', 3], ['5678', 1]] });
});
describe('changing a quantity', () => {
it('replaces every line of that ending with one and marks the order edited', () => {
setLineQty(db, shopUser(), orderId, '1234', 7);
expect(lines()).toEqual([{ ending: '1234', qty: 7 }, { ending: '5678', qty: 1 }]);
expect(order().edited_at).not.toBeNull();
});
it('refuses a quantity outside 1 to 999', () => {
for (const qty of [0, -1, 1000, 1.5]) expect(() => setLineQty(db, shopUser(), orderId, '1234', qty)).toThrow(RuleError);
expect(order().edited_at).toBeNull();
});
it('refuses an ending that is not in the order', () => {
expect(() => setLineQty(db, shopUser(), orderId, '9999', 1)).toThrow(RuleError);
});
});
describe('removing an ending', () => {
it('removes every line of it', () => {
removeLine(db, shopUser(), orderId, '1234');
expect(lines()).toEqual([{ ending: '5678', qty: 1 }]);
expect(order()).toMatchObject({ status: 'confirmed' });
});
it('cancels the order when its last ending goes', () => {
removeLine(db, shopUser(), orderId, '1234');
removeLine(db, shopUser(), orderId, '5678');
expect(order().status).toBe('cancelled');
});
});
describe('cancelling an order', () => {
it('cancels it and keeps the record', () => {
cancelOrder(db, shopUser(), orderId);
expect(order().status).toBe('cancelled');
expect(lines()).toHaveLength(3);
});
it('cannot be done twice', () => {
cancelOrder(db, shopUser(), orderId);
expect(() => cancelOrder(db, shopUser(), orderId)).toThrow(RuleError);
});
});
describe('who may edit', () => {
it('lets an admin edit any order', () => {
cancelOrder(db, getUserById(db, f.admin.id)!, orderId);
expect(order().status).toBe('cancelled');
});
it('refuses a user of another shop, as if the order did not exist', () => {
const other = seedOrder(db, { shopId: f.shops.b, userId: f.multiUser.id, date: '2026-11-02', lines: [['0001', 1]] });
expect(() => cancelOrder(db, shopUser(), other)).toThrow(/order not found/);
});
it('refuses an inactive user', () => {
expect(() => cancelOrder(db, getUserById(db, f.disabledUser.id)!, orderId)).toThrow(RuleError);
});
it('still lets a user edit an order of a shop that was switched off', () => {
db.prepare('UPDATE shops SET active = 0 WHERE id = ?').run(f.shops.a);
setLineQty(db, shopUser(), orderId, '5678', 4);
expect(lines()).toContainEqual({ ending: '5678', qty: 4 });
});
});