aboutsummaryrefslogtreecommitdiff
path: root/src/lib/server/services/references.test.ts
blob: 1f5d172f75fee51e207dce5d075601a1dc37b28c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

import { describe, it, expect, beforeEach } from 'vitest';
import { groceries, references } from '$lib/server/db/schema';
import { eq } from 'drizzle-orm';
import { createTestDb, type TestDb } from '$lib/server/db/test-helper';
import { ReferencesService } from './references';

describe('references service', () => {
	let db: TestDb['db'];
	let service: ReferencesService;

	beforeEach(async () => {
		db = (await createTestDb()).db;
		service = new ReferencesService(db);
	});

	it('loadForGrocery returns refs for the given grocery', async () => {
		const now = Temporal.Now.instant().toString({
			smallestUnit: 'millisecond',
		});
		const [g1] = await db
			.insert(groceries)
			.values({ name: 'coffee', checked: false, createdAt: now })
			.returning();
		const [g2] = await db
			.insert(groceries)
			.values({ name: 'tea', checked: false, createdAt: now })
			.returning();

		await db.insert(references).values([
			{ groceryId: g1.id, reference: 'Brand A' },
			{ groceryId: g2.id, reference: 'Brand B' },
		]);

		const refs = await service.loadForGrocery(g1.id);
		expect(refs).toHaveLength(1);
		expect(refs[0].reference).toBe('Brand A');
	});

	it('loadForGrocery orders refs by score desc, then insertion', async () => {
		const now = Temporal.Now.instant().toString({
			smallestUnit: 'millisecond',
		});
		const [g] = await db
			.insert(groceries)
			.values({ name: 'coffee', checked: false, createdAt: now })
			.returning();
		await db.insert(references).values([
			{ groceryId: g.id, reference: 'A' },
			{ groceryId: g.id, reference: 'B', qualityScore: 50 },
			{ groceryId: g.id, reference: 'C' },
			{ groceryId: g.id, reference: 'D', qualityScore: 50 },
		]);

		const refs = await service.loadForGrocery(g.id);
		expect(refs.map((r) => r.reference)).toEqual(['B', 'D', 'A', 'C']);
	});

	it('add creates a reference', async () => {
		const now = Temporal.Now.instant().toString({
			smallestUnit: 'millisecond',
		});
		const [g] = await db
			.insert(groceries)
			.values({ name: 'pasta', checked: false, createdAt: now })
			.returning();

		const ref = await service.add(g.id, 'Barilla', 2.5, '€/kg', 85);
		expect(ref.reference).toBe('Barilla');
		expect(ref.price).toBe(2.5);

		const rows = await db
			.select()
			.from(references)
			.where(eq(references.groceryId, g.id));
		expect(rows).toHaveLength(1);
	});

	it('promote puts the ref first and clears any sibling primary', async () => {
		const now = Temporal.Now.instant().toString({
			smallestUnit: 'millisecond',
		});
		const [g] = await db
			.insert(groceries)
			.values({ name: 'coffee', checked: false, createdAt: now })
			.returning();
		const [a] = await db
			.insert(references)
			.values({ groceryId: g.id, reference: 'A', qualityScore: 90 })
			.returning();
		const [b] = await db
			.insert(references)
			.values({ groceryId: g.id, reference: 'B' })
			.returning();

		await service.promote(b.id);
		let refs = await service.loadForGrocery(g.id);
		expect(refs.map((r) => r.reference)).toEqual(['B', 'A']);

		await service.promote(a.id);
		refs = await service.loadForGrocery(g.id);
		expect(refs.map((r) => r.reference)).toEqual(['A', 'B']);

		const rows = await db
			.select()
			.from(references)
			.where(eq(references.groceryId, g.id));
		expect(rows.filter((r) => r.isPrimary)).toHaveLength(1);
		expect(rows.find((r) => r.id === a.id)?.isPrimary).toBe(true);
	});

	it('deleteReference removes the ref', async () => {
		const now = Temporal.Now.instant().toString({
			smallestUnit: 'millisecond',
		});
		const [g] = await db
			.insert(groceries)
			.values({ name: 'rice', checked: false, createdAt: now })
			.returning();
		const [ref] = await db
			.insert(references)
			.values({ groceryId: g.id, reference: 'Brand X' })
			.returning();

		await service.deleteReference(ref.id);

		const rows = await db.select().from(references);
		expect(rows).toHaveLength(0);
	});
});