164 lines
4.9 KiB
JavaScript
164 lines
4.9 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: [],
|
|
communityEcology: { topics: [] },
|
|
onboarding: {
|
|
completedAt: null,
|
|
eventPageVisited: false,
|
|
ecologyPageVisited: 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 ecology topics', async () => {
|
|
requireAuth.mockResolvedValue({
|
|
_id: 'member-1',
|
|
craftTags: ['game-design'],
|
|
communityEcology: {
|
|
topics: [{ tagSlug: 'governance', state: 'interested' }],
|
|
},
|
|
onboarding: {
|
|
completedAt: null,
|
|
eventPageVisited: false,
|
|
ecologyPageVisited: 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 ecology topics', async () => {
|
|
requireAuth.mockResolvedValue({
|
|
_id: 'member-1',
|
|
craftTags: ['game-design'],
|
|
communityEcology: { topics: [] },
|
|
onboarding: {
|
|
completedAt: null,
|
|
eventPageVisited: false,
|
|
ecologyPageVisited: 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: [],
|
|
communityEcology: {
|
|
topics: [{ tagSlug: 'governance', state: 'help' }],
|
|
},
|
|
onboarding: {
|
|
completedAt: null,
|
|
eventPageVisited: false,
|
|
ecologyPageVisited: 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: [],
|
|
communityEcology: { topics: [] },
|
|
onboarding: {
|
|
completedAt: null,
|
|
eventPageVisited: false,
|
|
ecologyPageVisited: 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: [],
|
|
communityEcology: { topics: [] },
|
|
onboarding: {
|
|
completedAt: null,
|
|
eventPageVisited: true,
|
|
ecologyPageVisited: 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 })
|
|
})
|
|
})
|