import { describe, it, expect, vi } from 'vitest'; import { commitGroupRide } from '../lib/create-group-ride'; import type { WebGroupRideInput } from '../lib/group-ride-payload'; const baseRide: WebGroupRideInput = { id: 'ride-temp', title: 'Canyon Dawn Patrol', description: 'Fast sweepers', region: 'Santa Cruz Mountains', scheduledDate: '', scheduledTime: '', paceClassification: 'Brisk Pace', discipline: 'Sport / Canyon', formationProfile: 'Staggered Dual Column [B]', joinPolicy: 'requestToJoin', leadHandle: 'You (Organizer)', leadAvatarText: 'YOU', participantCount: 1, participantLimit: 12, distance: '50.0 Miles', meetingPoint: 'Alice’s Restaurant', routeSnippet: 'Skyline > Hwy 9', userStatus: 'joined', status: 'scheduled', }; function makeDeps(overrides: Partial[1]> = {}) { const setSpy = vi.fn(); const commitSpy = vi.fn().mockResolvedValue(undefined); const deps = { uid: 'rider-uid-1' as string | null | undefined, firestore: {} as unknown, leadDisplayName: 'Rider One', leadHandle: 'rider_one', now: new Date('2026-10-14T12:00:00.000Z'), writeBatch: () => ({ set: setSpy, commit: commitSpy }), docRef: (_fs: any, ...segments: string[]) => ({ path: segments.join('/') }), ...overrides, }; return { deps, setSpy, commitSpy }; } describe('commitGroupRide (WEB Phase 1 — persisted ride creation)', () => { it('refuses to create for an unauthenticated user (no uid) and never writes', async () => { const { deps, commitSpy } = makeDeps({ uid: undefined }); const res = await commitGroupRide(baseRide, deps); expect(res).toEqual({ ok: false, reason: 'unauthenticated' }); expect(commitSpy).not.toHaveBeenCalled(); }); it('reports unavailable when Firestore is missing and never writes', async () => { const { deps, commitSpy } = makeDeps({ firestore: null }); const res = await commitGroupRide(baseRide, deps); expect(res).toEqual({ ok: false, reason: 'unavailable' }); expect(commitSpy).not.toHaveBeenCalled(); }); it('persists the ride and participant, then returns the real rideId as the join code', async () => { const { deps, setSpy, commitSpy } = makeDeps(); const res = await commitGroupRide(baseRide, deps); expect(res.ok).toBe(true); if (!res.ok) return; expect(res.rideId).toMatch(/^ride_\d+_rider-/); // Two writes: the ride document and the organizer participant. expect(setSpy).toHaveBeenCalledTimes(2); expect(commitSpy).toHaveBeenCalledTimes(1); // The persisted payload never fabricates coordinates. const mp = (res.payload as any).meetingPoint; expect('latitude' in mp).toBe(false); expect('longitude' in mp).toBe(false); expect(mp.displayName).toBe('Alice’s Restaurant'); expect((res.payload as any).organizerUid).toBe('rider-uid-1'); }); it('returns commit-failed (and does not throw) when the Firestore write rejects', async () => { const boom = new Error('network down'); const { deps } = makeDeps({ writeBatch: () => ({ set: vi.fn(), commit: vi.fn().mockRejectedValue(boom) }), }); const res = await commitGroupRide(baseRide, deps); expect(res).toEqual({ ok: false, reason: 'commit-failed', error: boom }); }); });