1+ import Fastify from 'fastify' ;
12import { describe , it , expect , beforeEach , afterEach , vi } from 'vitest' ;
2- import Fastify , { FastifyInstance } from 'fastify' ;
3- import { PrismaClient } from '@prisma/client' ;
3+
44import { eventRoutes } from '../routes/event' ;
55
6+ import type { PrismaClient } from '@prisma/client' ;
7+ import type { FastifyInstance } from 'fastify' ;
8+
69// ─── Shared mock data ────────────────────────────────────────────────────────
710
811const MOCK_USER_ID = 'user-uuid-001' ;
@@ -64,7 +67,7 @@ const prismaMock = {
6467//
6568// This mirrors the real app setup without touching a real DB or real JWT keys.
6669
67- let mockJwtVerify = vi . fn ( ) ;
70+ const mockJwtVerify = vi . fn ( ) ;
6871
6972async function buildApp ( ) : Promise < FastifyInstance > {
7073 const app = Fastify ( { logger : false } ) ;
@@ -77,7 +80,14 @@ async function buildApp(): Promise<FastifyInstance> {
7780 app . decorateRequest ( 'jwtVerify' , function ( ) {
7881 return mockJwtVerify ( ) ;
7982 } ) ;
80-
83+ app . decorate ( 'authenticate' , async function ( request , reply ) {
84+ try {
85+ const payload = await request . jwtVerify ( ) ;
86+ if ( payload ) { request . user = payload as typeof request . user ; }
87+ } catch {
88+ return reply . status ( 401 ) . send ( { error : 'Unauthorized' } ) ;
89+ }
90+ } ) ;
8191 // Register with the same prefix used in production (app.ts) so that
8292 // tests exercise routes at their real paths — /api/events, /api/events/:slug, etc.
8393 await app . register ( eventRoutes , { prefix : '/api/events' } ) ;
@@ -251,14 +261,15 @@ describe('Events API', () => {
251261 it ( '200 — returns event info with attendee count' , async ( ) => {
252262 prismaMock . event . findUnique . mockResolvedValue ( {
253263 ...MOCK_EVENT ,
264+ organizer : { username : 'johndoe' , displayName : 'John Doe' } ,
254265 _count : { attendees : 42 } ,
255266 } ) ;
256267
257268 const res = await app . inject ( {
258269 method : 'GET' ,
259270 url : '/api/events/devcard-conf-2025' ,
260271 } ) ;
261-
272+ console . log ( JSON . stringify ( res . json ( ) , null , 2 ) ) ;
262273 expect ( res . statusCode ) . toBe ( 200 ) ;
263274 const body = res . json ( ) ;
264275 expect ( body . slug ) . toBe ( 'devcard-conf-2025' ) ;
@@ -275,7 +286,7 @@ describe('Events API', () => {
275286 method : 'GET' ,
276287 url : '/api/events/ghost-event' ,
277288 } ) ;
278-
289+
279290 expect ( res . statusCode ) . toBe ( 404 ) ;
280291 expect ( res . json ( ) ) . toMatchObject ( { error : 'Event not found' } ) ;
281292 } ) ;
@@ -285,6 +296,7 @@ describe('Events API', () => {
285296 mockJwtVerify . mockRejectedValue ( new Error ( 'Should not be called' ) ) ;
286297 prismaMock . event . findUnique . mockResolvedValue ( {
287298 ...MOCK_EVENT ,
299+ organizer : { username : 'johndoe' , displayName : 'John Doe' } ,
288300 _count : { attendees : 0 } ,
289301 } ) ;
290302
@@ -495,6 +507,7 @@ describe('Events API', () => {
495507 prismaMock . event . findUnique . mockResolvedValue ( {
496508 ...MOCK_EVENT ,
497509 attendees : attendeeRows ,
510+ _count : { attendees : 2 } ,
498511 } ) ;
499512
500513 const res = await app . inject ( {
@@ -523,6 +536,7 @@ describe('Events API', () => {
523536 prismaMock . event . findUnique . mockResolvedValue ( {
524537 ...MOCK_EVENT ,
525538 attendees : [ makeAttendeeRow ( MOCK_OTHER_USER_PROFILE ) ] ,
539+ _count : { attendees : 1 } ,
526540 } ) ;
527541
528542 const res = await app . inject ( {
@@ -545,6 +559,7 @@ describe('Events API', () => {
545559 prismaMock . event . findUnique . mockResolvedValue ( {
546560 ...MOCK_EVENT ,
547561 attendees : [ ] ,
562+ _count : { attendees : 0 } ,
548563 } ) ;
549564
550565 const res = await app . inject ( {
@@ -561,6 +576,7 @@ describe('Events API', () => {
561576 prismaMock . event . findUnique . mockResolvedValue ( {
562577 ...MOCK_EVENT ,
563578 attendees : [ ] ,
579+ _count : { attendees : 0 } ,
564580 } ) ;
565581
566582 const res = await app . inject ( {
@@ -577,6 +593,7 @@ describe('Events API', () => {
577593 prismaMock . event . findUnique . mockResolvedValue ( {
578594 ...MOCK_EVENT ,
579595 attendees : [ ] ,
596+ _count : { attendees : 0 } ,
580597 } ) ;
581598
582599 const res = await app . inject ( {
@@ -594,6 +611,7 @@ describe('Events API', () => {
594611 prismaMock . event . findUnique . mockResolvedValue ( {
595612 ...MOCK_EVENT ,
596613 attendees : [ makeAttendeeRow ( MOCK_USER_PROFILE ) ] ,
614+ _count : { attendees : 1 } ,
597615 } ) ;
598616
599617 const res = await app . inject ( {
0 commit comments