Files
MOPC-Portal/tests/unit/mentor-primary-role-assignable.test.ts

99 lines
3.1 KiB
TypeScript
Raw Normal View History

import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest'
vi.mock('@/lib/email', async () => {
const actual = await vi.importActual<typeof import('@/lib/email')>('@/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()
})
})