/opt/mawid/apps/api/src/auth
Edit: /opt/mawid/apps/api/src/auth/auth.service.spec.ts (3153B)
import { ConflictException, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import * as argon2 from 'argon2';
import { AuthService } from './auth.service';
import type { PrismaService } from '../prisma/prisma.service';
const jwtService = new JwtService({ secret: 'test-secret-at-least-16-chars' });
function makePrismaMock() {
const user = { findUnique: jest.fn(), create: jest.fn() };
const clinic = { create: jest.fn() };
const prisma = {
user,
clinic,
$transaction: jest.fn(async (fn: (tx: unknown) => Promise
) =>
fn({ user, clinic }),
),
};
return prisma as unknown as PrismaService & typeof prisma;
}
describe('AuthService', () => {
const registerInput = {
clinicName: 'Clinic A',
clinicPhone: '+905550000000',
name: 'Owner',
email: 'owner@a.clinic',
password: 'super-secret-pw',
};
it('register creates clinic + owner and returns a JWT carrying clinicId', async () => {
const prisma = makePrismaMock();
prisma.user.findUnique.mockResolvedValue(null);
prisma.clinic.create.mockResolvedValue({ id: 'clinic-a' });
prisma.user.create.mockImplementation(async ({ data }: { data: Record }) => ({
id: 'user-1',
...data,
}));
const service = new AuthService(prisma, jwtService);
const result = await service.register(registerInput);
const storedHash = prisma.user.create.mock.calls[0][0].data.passwordHash as string;
expect(storedHash).not.toContain(registerInput.password);
await expect(argon2.verify(storedHash, registerInput.password)).resolves.toBe(true);
const payload = jwtService.verify(result.accessToken);
expect(payload.sub).toBe('user-1');
expect(payload.clinicId).toBe('clinic-a');
});
it('register rejects duplicate email', async () => {
const prisma = makePrismaMock();
prisma.user.findUnique.mockResolvedValue({ id: 'existing' });
const service = new AuthService(prisma, jwtService);
await expect(service.register(registerInput)).rejects.toThrow(ConflictException);
});
it('login succeeds with the right password and fails with a wrong one', async () => {
const prisma = makePrismaMock();
const passwordHash = await argon2.hash('right-password');
prisma.user.findUnique.mockResolvedValue({
id: 'user-1',
clinicId: 'clinic-a',
email: 'owner@a.clinic',
name: 'Owner',
passwordHash,
});
const service = new AuthService(prisma, jwtService);
const ok = await service.login({ email: 'owner@a.clinic', password: 'right-password' });
expect(ok.user.clinicId).toBe('clinic-a');
await expect(
service.login({ email: 'owner@a.clinic', password: 'wrong-password' }),
).rejects.toThrow(UnauthorizedException);
});
it('login fails for unknown email', async () => {
const prisma = makePrismaMock();
prisma.user.findUnique.mockResolvedValue(null);
const service = new AuthService(prisma, jwtService);
await expect(service.login({ email: 'nobody@x.y', password: 'whatever' })).rejects.toThrow(
UnauthorizedException,
);
});
});