import { afterAll, describe, expect, it } from 'vitest' import { prisma, createCaller } from '../setup' import { createTestUser, createTestProgram, createTestProject, createTestCompetition, createTestRound, createTestProjectRoundState, cleanupTestData, uid, } from '../helpers' import { userRouter } from '../../src/server/routers/user' import type { UserRole } from '@prisma/client' async function createUserWithRoles(primaryRole: UserRole, rolesArray: UserRole[]) { const id = uid('user') return prisma.user.create({ data: { id, email: `${id}@test.local`, name: `Test ${primaryRole}`, role: primaryRole, roles: rolesArray, status: 'ACTIVE', }, }) } describe('user.getDefaultDashboard', () => { const programIds: string[] = [] const userIds: string[] = [] afterAll(async () => { for (const programId of programIds) { await prisma.mentorAssignment.deleteMany({ where: { project: { programId } } }) await cleanupTestData(programId, []) } if (userIds.length > 0) { await prisma.user.deleteMany({ where: { id: { in: userIds } } }) } }) it('returns /admin for SUPER_ADMIN unconditionally', async () => { const u = await createUserWithRoles('SUPER_ADMIN', ['SUPER_ADMIN']) userIds.push(u.id) const caller = createCaller(userRouter, { id: u.id, email: u.email, role: 'SUPER_ADMIN' }) const result = await caller.getDefaultDashboard() expect(result.path).toBe('/admin') expect(result.role).toBe('SUPER_ADMIN') }) it('returns /jury for a juror with a pending assignment in an active round', async () => { const u = await createUserWithRoles('JURY_MEMBER', ['JURY_MEMBER', 'OBSERVER']) userIds.push(u.id) const program = await createTestProgram({ name: `default-juror-active-${uid()}` }) programIds.push(program.id) const competition = await createTestCompetition(program.id, { status: 'ACTIVE' }) const round = await createTestRound(competition.id, { roundType: 'EVALUATION', status: 'ROUND_ACTIVE', }) const project = await createTestProject(program.id) await createTestProjectRoundState(project.id, round.id) await prisma.assignment.create({ data: { userId: u.id, projectId: project.id, roundId: round.id, method: 'MANUAL' }, }) const caller = createCaller(userRouter, { id: u.id, email: u.email, role: 'JURY_MEMBER' }) const result = await caller.getDefaultDashboard() expect(result.path).toBe('/jury') }) it('falls back to /jury (static priority) when juror+observer has no active work', async () => { const u = await createUserWithRoles('JURY_MEMBER', ['JURY_MEMBER', 'OBSERVER']) userIds.push(u.id) const caller = createCaller(userRouter, { id: u.id, email: u.email, role: 'JURY_MEMBER' }) const result = await caller.getDefaultDashboard() expect(result.path).toBe('/jury') expect(result.reason).toBe('static-fallback') }) it('returns /mentor for a mentor+juror with active mentoring but no jury work', async () => { const u = await createUserWithRoles('MENTOR', ['MENTOR', 'JURY_MEMBER']) userIds.push(u.id) const program = await createTestProgram({ name: `default-mentor-active-${uid()}` }) programIds.push(program.id) const competition = await createTestCompetition(program.id, { status: 'ACTIVE' }) const round = await createTestRound(competition.id, { roundType: 'MENTORING', status: 'ROUND_ACTIVE', }) const project = await createTestProject(program.id) await createTestProjectRoundState(project.id, round.id) await prisma.mentorAssignment.create({ data: { projectId: project.id, mentorId: u.id, method: 'MANUAL', workspaceEnabled: true, }, }) const caller = createCaller(userRouter, { id: u.id, email: u.email, role: 'MENTOR' }) const result = await caller.getDefaultDashboard() expect(result.path).toBe('/mentor') }) it('returns /jury when both jury and mentor work are active (jury wins on priority)', async () => { const u = await createUserWithRoles('JURY_MEMBER', ['JURY_MEMBER', 'MENTOR']) userIds.push(u.id) const program = await createTestProgram({ name: `default-both-active-${uid()}` }) programIds.push(program.id) const competition = await createTestCompetition(program.id, { status: 'ACTIVE' }) const evalRound = await createTestRound(competition.id, { roundType: 'EVALUATION', status: 'ROUND_ACTIVE', sortOrder: 0, }) const mentRound = await createTestRound(competition.id, { roundType: 'MENTORING', status: 'ROUND_ACTIVE', sortOrder: 1, }) const projectE = await createTestProject(program.id) const projectM = await createTestProject(program.id) await createTestProjectRoundState(projectE.id, evalRound.id) await createTestProjectRoundState(projectM.id, mentRound.id) await prisma.assignment.create({ data: { userId: u.id, projectId: projectE.id, roundId: evalRound.id, method: 'MANUAL' }, }) await prisma.mentorAssignment.create({ data: { projectId: projectM.id, mentorId: u.id, method: 'MANUAL', workspaceEnabled: true, }, }) const caller = createCaller(userRouter, { id: u.id, email: u.email, role: 'JURY_MEMBER' }) const result = await caller.getDefaultDashboard() expect(result.path).toBe('/jury') }) it('returns /observer for an observer-only user (static fallback)', async () => { const u = await createUserWithRoles('OBSERVER', ['OBSERVER']) userIds.push(u.id) const caller = createCaller(userRouter, { id: u.id, email: u.email, role: 'OBSERVER' }) const result = await caller.getDefaultDashboard() expect(result.path).toBe('/observer') }) })