65 lines
2.9 KiB
TypeScript
65 lines
2.9 KiB
TypeScript
import { TabsService } from './tabs.service';
|
|
import { createFakePrisma } from '../testing/fake-prisma';
|
|
|
|
const at = (minutes: number) => new Date(Date.UTC(2026, 9, 27, 20, minutes));
|
|
|
|
function setup() {
|
|
const prisma = createFakePrisma();
|
|
prisma.device.rows.push({ id: 'd1', venueId: 'v1', name: 'Bar tablet' });
|
|
const service = new TabsService(prisma as any, { notify: jest.fn() } as any);
|
|
|
|
const settle = (id: string, customerName: string, minutes: number, extra: Record<string, unknown> = {}) =>
|
|
prisma.settlement.create({
|
|
data: {
|
|
id, venueId: 'v1', tabId: `tab-${id}`, customerName, settledAt: at(minutes), paymentMethod: 'cash',
|
|
amountInCents: 500, deviceId: 'd1', requestedBy: null,
|
|
lines: [{
|
|
id: 'l1', productId: 'cola', productName: 'Cola', unitPriceInCents: 250, quantity: 2,
|
|
units: [
|
|
{ id: 'u1', addedAt: at(0).toISOString(), removedAt: null },
|
|
{ id: 'u2', addedAt: at(0).toISOString(), removedAt: null },
|
|
{ id: 'u3', addedAt: at(0).toISOString(), removedAt: at(1).toISOString() },
|
|
],
|
|
}],
|
|
...extra,
|
|
},
|
|
});
|
|
|
|
return { prisma, service, settle };
|
|
}
|
|
|
|
describe('TabsService.history', () => {
|
|
it('lists paid tabs newest first, with their lines and who settled them', async () => {
|
|
const { service, settle } = setup();
|
|
await settle('s1', 'Alice', 1);
|
|
await settle('s2', 'Bob', 5, { deviceId: null, requestedBy: 'manager@bar.be', paymentMethod: 'payconiq' });
|
|
await settle('other', 'Eve', 9, { venueId: 'v2' });
|
|
|
|
const result = await service.history('v1', { limit: 50, offset: 0 });
|
|
|
|
expect(result.total).toBe(2);
|
|
expect(result.totalAmountInCents).toBe(1000);
|
|
expect(result.settlements.map((s) => s.id)).toEqual(['s2', 's1']);
|
|
expect(result.settlements[0]).toMatchObject({ settledBy: 'manager@bar.be', onDashboard: true, paymentMethod: 'payconiq' });
|
|
expect(result.settlements[1]).toMatchObject({ settledBy: 'Bar tablet', onDashboard: false, itemCount: 2 });
|
|
expect(result.settlements[1].items).toEqual([{ productName: 'Cola', quantity: 2, unitPriceInCents: 250, removed: 1 }]);
|
|
});
|
|
|
|
it('filters by part of the name and payment method, and pages', async () => {
|
|
const { service, settle } = setup();
|
|
await settle('s1', 'Alice', 1);
|
|
await settle('s2', 'alicia', 2, { paymentMethod: 'payconiq' });
|
|
await settle('s3', 'Bob', 3);
|
|
|
|
const byName = await service.history('v1', { search: ' ALI ', limit: 50, offset: 0 });
|
|
expect(byName.settlements.map((s) => s.id)).toEqual(['s2', 's1']);
|
|
|
|
const byMethod = await service.history('v1', { search: 'ali', paymentMethod: 'cash', limit: 50, offset: 0 });
|
|
expect(byMethod.settlements.map((s) => s.id)).toEqual(['s1']);
|
|
|
|
const secondPage = await service.history('v1', { limit: 2, offset: 2 });
|
|
expect(secondPage.total).toBe(3);
|
|
expect(secondPage.settlements.map((s) => s.id)).toEqual(['s1']);
|
|
});
|
|
});
|