import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest' vi.mock('@/lib/email', async () => { const actual = await vi.importActual('@/lib/email') return { ...actual, sendMentorBulkAssignmentEmail: vi.fn(async () => true), sendTeamMentorIntroductionEmail: vi.fn(async () => true), } }) import { prisma, createCaller } from '../setup' import { createTestProgram, createTestCompetition, createTestRound, createTestProject, createTestProjectRoundState, createTestUser, cleanupTestData, uid, } from '../helpers' import { mentorRouter } from '../../src/server/routers/mentor' /** * Regression: a user whose MENTOR role is the PRIMARY role but whose roles[] * array is empty (legacy/seeded records, e.g. prod user "Arnaud Blandin") must * still be selectable + assignable on the mentor config page. Previously the * candidate query filtered `roles: { has: 'MENTOR' }`, which excludes an empty * roles[] even when role === 'MENTOR'. */ describe('mentor.getCandidates / bulkAssign — primary-role-only mentors are assignable', () => { let programId = '' let projectId = '' let mentorId = '' let adminId = '' const userIds: string[] = [] beforeAll(async () => { const program = await createTestProgram() programId = program.id const competition = await createTestCompetition(program.id) const round = await createTestRound(competition.id, { roundType: 'MENTORING', status: 'ROUND_DRAFT', // draft → assignment emails are deferred }) const project = await createTestProject(program.id) projectId = project.id await createTestProjectRoundState(project.id, round.id) // The crux: primary role MENTOR, but roles[] is EMPTY. const mentor = await prisma.user.create({ data: { id: uid('u'), email: `${uid('arnaud')}@test.local`, name: 'Primary Only Mentor', role: 'MENTOR', roles: [], status: 'ACTIVE', }, }) mentorId = mentor.id const admin = await createTestUser('SUPER_ADMIN') adminId = admin.id userIds.push(mentor.id, admin.id) }) afterAll(async () => { await cleanupTestData(programId, userIds) }) it('getCandidates includes a primary-role-only mentor', async () => { const caller = createCaller(mentorRouter, { id: adminId, email: 'admin@test.local', role: 'SUPER_ADMIN', }) const res = await caller.getCandidates({ projectId }) const ids = res.candidates.map((c: { id: string }) => c.id) expect(ids).toContain(mentorId) }) it('bulkAssign accepts a primary-role-only mentor and creates the assignment', async () => { const caller = createCaller(mentorRouter, { id: adminId, email: 'admin@test.local', role: 'SUPER_ADMIN', }) // Must not throw "None of the selected users have the MENTOR role". await caller.bulkAssign({ mentorIds: [mentorId], projectIds: [projectId] }) const assignment = await prisma.mentorAssignment.findFirst({ where: { projectId, mentorId }, }) expect(assignment).not.toBeNull() }) })