ghostguild-org/tests/server/api/onboarding-status.test.js
Jennie Robinson Faber 74b2287d48 feat: update tests + seed script, add ecology→board migration
- useOnboarding.test.js: hasEngagedEcology→hasEngagedBoard, /api/ecology/suggestions→/api/board/suggestions, ecology key/route→board in test assertions
- onboarding-status.test.js: stale description strings updated
- seed-welcome-tester.cjs: communityEcology→board, ecologyPageVisited→boardPageVisited
- migrate-ecology-to-board.cjs: one-time migration renames three member fields and activity log action values
2026-04-14 12:20:46 +01:00

164 lines
4.8 KiB
JavaScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
vi.mock('../../../server/utils/auth.js', () => ({
requireAuth: vi.fn()
}))
vi.mock('../../../server/utils/mongoose.js', () => ({
connectDB: vi.fn()
}))
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()
})
// 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: [],
board: { topics: [] },
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,
hasEngagedEcology: false,
hasClickedWiki: false,
},
completedAt: null,
})
})
// 1.2: hasProfileTags true when both tag types present
it('hasProfileTags is true when member has both craft tags and board topics', async () => {
requireAuth.mockResolvedValue({
_id: 'member-1',
craftTags: ['game-design'],
board: {
topics: [{ tagSlug: 'governance', state: 'interested' }],
},
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 only craft tags
it('hasProfileTags is false when member has craft tags but no board topics', async () => {
requireAuth.mockResolvedValue({
_id: 'member-1',
craftTags: ['game-design'],
board: { topics: [] },
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: hasEngagedEcology true when visited AND has tag with engagement state
it('hasEngagedEcology is true when page visited and has engaged topic', async () => {
requireAuth.mockResolvedValue({
_id: 'member-1',
craftTags: [],
board: {
topics: [{ tagSlug: 'governance', state: 'help' }],
},
onboarding: {
completedAt: null,
eventPageVisited: false,
boardPageVisited: true,
wikiClicked: false,
},
})
const event = createMockEvent({ method: 'GET', path: '/api/onboarding/status' })
const result = await handler(event)
expect(result.goals.hasEngagedEcology).toBe(true)
})
// 1.6: hasEngagedEcology false when visited but no engagement state
it('hasEngagedEcology is false when page visited but no topics have engagement state', async () => {
requireAuth.mockResolvedValue({
_id: 'member-1',
craftTags: [],
board: { topics: [] },
onboarding: {
completedAt: null,
eventPageVisited: false,
boardPageVisited: true,
wikiClicked: false,
},
})
const event = createMockEvent({ method: 'GET', path: '/api/onboarding/status' })
const result = await handler(event)
expect(result.goals.hasEngagedEcology).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: [],
board: { topics: [] },
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.hasEngagedEcology).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 })
})
})