import { describe, it, expect, vi, beforeEach } from 'vitest' const { mockBoardPostExists } = vi.hoisted(() => ({ mockBoardPostExists: vi.fn() })) vi.mock('../../../server/utils/auth.js', () => ({ requireAuth: vi.fn() })) vi.mock('../../../server/utils/mongoose.js', () => ({ connectDB: vi.fn() })) vi.mock('../../../server/models/boardPost.js', () => ({ default: { exists: mockBoardPostExists } })) import { requireAuth } from '../../../server/utils/auth.js' import handler from '../../../server/api/onboarding/status.get.js' import { createMockEvent } from '../helpers/createMockEvent.js' describe('GET /api/onboarding/status', () => { beforeEach(() => { vi.clearAllMocks() mockBoardPostExists.mockResolvedValue(null) }) // 1.1: Default state for new member — all false, completedAt null it('returns all goals false for a new member with no data', async () => { requireAuth.mockResolvedValue({ _id: 'member-1', craftTags: [], onboarding: { completedAt: null, eventPageVisited: false, boardPageVisited: false, wikiClicked: false, }, }) const event = createMockEvent({ method: 'GET', path: '/api/onboarding/status' }) const result = await handler(event) expect(result).toEqual({ goals: { hasProfileTags: false, hasVisitedEvent: false, hasEngagedBoard: false, hasClickedWiki: false, }, completedAt: null, }) }) // 1.2: hasProfileTags true when craft tags present it('hasProfileTags is true when member has craft tags', async () => { requireAuth.mockResolvedValue({ _id: 'member-1', craftTags: ['game-design'], onboarding: { completedAt: null, eventPageVisited: false, boardPageVisited: false, wikiClicked: false, }, }) const event = createMockEvent({ method: 'GET', path: '/api/onboarding/status' }) const result = await handler(event) expect(result.goals.hasProfileTags).toBe(true) }) // 1.3: hasProfileTags false when no craft tags it('hasProfileTags is false when member has no craft tags', async () => { requireAuth.mockResolvedValue({ _id: 'member-1', craftTags: [], onboarding: { completedAt: null, eventPageVisited: false, boardPageVisited: false, wikiClicked: false, }, }) const event = createMockEvent({ method: 'GET', path: '/api/onboarding/status' }) const result = await handler(event) expect(result.goals.hasProfileTags).toBe(false) }) // 1.5: hasEngagedBoard true when visited AND has a BoardPost it('hasEngagedBoard is true when page visited and member has posted', async () => { requireAuth.mockResolvedValue({ _id: 'member-1', craftTags: [], onboarding: { completedAt: null, eventPageVisited: false, boardPageVisited: true, wikiClicked: false, }, }) mockBoardPostExists.mockResolvedValue({ _id: 'post-1' }) const event = createMockEvent({ method: 'GET', path: '/api/onboarding/status' }) const result = await handler(event) expect(result.goals.hasEngagedBoard).toBe(true) expect(mockBoardPostExists).toHaveBeenCalledWith({ author: 'member-1' }) }) // 1.6: hasEngagedBoard false when visited but no posts it('hasEngagedBoard is false when page visited but member has no posts', async () => { requireAuth.mockResolvedValue({ _id: 'member-1', craftTags: [], onboarding: { completedAt: null, eventPageVisited: false, boardPageVisited: true, wikiClicked: false, }, }) mockBoardPostExists.mockResolvedValue(null) const event = createMockEvent({ method: 'GET', path: '/api/onboarding/status' }) const result = await handler(event) expect(result.goals.hasEngagedBoard).toBe(false) }) // 1.9: Maps stored booleans directly it('maps stored onboarding booleans directly for visit and wiki goals', async () => { requireAuth.mockResolvedValue({ _id: 'member-1', craftTags: [], onboarding: { completedAt: null, eventPageVisited: true, boardPageVisited: false, wikiClicked: true, }, }) const event = createMockEvent({ method: 'GET', path: '/api/onboarding/status' }) const result = await handler(event) expect(result.goals.hasVisitedEvent).toBe(true) expect(result.goals.hasEngagedBoard).toBe(false) expect(result.goals.hasClickedWiki).toBe(true) }) // 1.11: Requires auth (401) it('returns 401 when not authenticated', async () => { requireAuth.mockRejectedValue( createError({ statusCode: 401, statusMessage: 'Authentication required' }) ) const event = createMockEvent({ method: 'GET', path: '/api/onboarding/status' }) await expect(handler(event)).rejects.toMatchObject({ statusCode: 401 }) }) })