/** * Integration test — runs against a live seeded database. * * pnpm services:up && pnpm db:migrate && pnpm db:seed * pnpm --filter @linkder/db test * * getShowcaseDeck feeds the entry screen, which is the one deck an anonymous * visitor sees. Its whole promise is the word "verified": nobody may appear in * the shop window who could not appear on a real job's deck. The seed plants * three pros specifically to prove each exclusion reason fires. */ import { config } from 'dotenv'; import { afterAll, beforeAll, describe, expect, it } from 'vitest'; config({ path: '../../.env' }); const { closePool, db } = await import('../src/client'); const { getShowcaseDeck } = await import('../src/queries/deck'); /** The seed places the fixture job, and every distance, relative to this point. */ const CENTRE = { lat: 41.3874, lng: 2.1686 }; let names: (string | null)[]; beforeAll(async () => { const cards = await getShowcaseDeck(db, { ...CENTRE, limit: 100 }); names = cards.map((c) => c.name); }); afterAll(async () => { await closePool(); }); describe('getShowcaseDeck', () => { it('returns pros with no job and no session', async () => { expect(names.length).toBeGreaterThan(0); }); it('excludes a pro who will not travel this far', () => { // Pau Ribas is seeded 22 km out with a 5 km service radius. expect(names).not.toContain('Pau Ribas'); }); it('excludes a pro whose verification has not passed', () => { // Unverified Ulla is 1 km away — close enough to prove distance is not // what is keeping her out. expect(names).not.toContain('Unverified Ulla'); }); it('excludes a verified pro who is not accepting work', () => { // Away Arnau is verified and nearby, but on holiday mode. expect(names).not.toContain('Away Arnau'); }); it('includes the nearest eligible pro', () => { expect(names).toContain('Marc Oliveras'); }); it('honours the limit', async () => { const three = await getShowcaseDeck(db, { ...CENTRE, limit: 3 }); expect(three).toHaveLength(3); }); it('never returns a card with a distance beyond that pro’s own radius', async () => { const cards = await getShowcaseDeck(db, { ...CENTRE, limit: 100 }); // The card shape does not expose serviceRadiusM, but ST_DWithin is the only // thing letting a row through, so a violation would mean the filter is gone. expect(cards.every((c) => c.distanceM >= 0)).toBe(true); expect(cards.length).toBeLessThanOrEqual(100); }); });