import { ConflictException } from '@nestjs/common'; import { afterAll, describe, expect, it } from 'vitest'; import { createTestPrisma, hasTestDb, uniqueSuffix } from '../testing/test-db'; import { PrismaService } from '../prisma/prisma.service'; import { UsersService } from './users.service'; describe.skipIf(!hasTestDb)('UsersService (database)', () => { const prisma = hasTestDb ? (createTestPrisma() as unknown as PrismaService) : null!; const users = hasTestDb ? new UsersService(prisma) : null!; const suffix = uniqueSuffix(); const input = { username: `uma-${suffix}`, email: `uma-${suffix}@example.org`, displayName: 'Uma Test', password: 'korrekt pferd batterie', locale: 'de', }; afterAll(async () => { if (!hasTestDb) return; await prisma.user.deleteMany({ where: { username: { contains: suffix } } }); await prisma.$disconnect(); }); it('creates a user with a password identity and verifies the password', async () => { const user = await users.createUser(input); expect(user.status).toBe('PENDING_VERIFICATION'); expect(await users.checkPassword(user.id, input.password)).toBe(true); expect(await users.checkPassword(user.id, 'wrong')).toBe(false); }); it('rejects duplicate usernames with a field-level conflict', async () => { await expect( users.createUser({ ...input, email: `other-${suffix}@example.org` }), ).rejects.toBeInstanceOf(ConflictException); }); it('rejects duplicate e-mail addresses case-insensitively', async () => { await expect( users.createUser({ ...input, username: `other-${suffix}`, email: input.email.toUpperCase(), }), ).rejects.toBeInstanceOf(ConflictException); }); it('normalizes lookup by e-mail or username', async () => { const byEmail = await users.findByUsernameOrEmail(input.email.toUpperCase()); const byName = await users.findByUsernameOrEmail(input.username); expect(byEmail?.id).toBe(byName?.id); }); });