import { describe, it, expect, vi, beforeEach } from 'vitest'; import { UsersService } from './users.service.js'; import { NotFoundError } from '../../common/errors.js'; describe('UsersService', () => { const mockRepo = { findByKeycloakId: vi.fn(), findById: vi.fn(), create: vi.fn(), update: vi.fn(), upsertFromToken: vi.fn(), }; let service: UsersService; beforeEach(() => { vi.clearAllMocks(); service = new UsersService({ usersRepository: mockRepo as never }); }); describe('syncFromToken', () => { it('upserts user from auth token data', async () => { const authUser = { keycloakId: 'kc-1', email: 'test@example.com', displayName: 'Test User', roles: ['member'], householdIds: [], }; const upserted = { _id: 'u1', ...authUser }; mockRepo.upsertFromToken.mockResolvedValue(upserted); const result = await service.syncFromToken(authUser); expect(mockRepo.upsertFromToken).toHaveBeenCalledWith( 'kc-1', 'test@example.com', 'Test User', ); expect(result).toEqual(upserted); }); }); describe('getProfile', () => { it('returns user when found', async () => { const user = { _id: 'u1', keycloakId: 'kc-1', displayName: 'Test' }; mockRepo.findByKeycloakId.mockResolvedValue(user); const result = await service.getProfile('kc-1'); expect(result).toEqual(user); expect(mockRepo.findByKeycloakId).toHaveBeenCalledWith('kc-1'); }); it('throws NotFoundError when user not found', async () => { mockRepo.findByKeycloakId.mockResolvedValue(null); await expect(service.getProfile('kc-missing')).rejects.toThrow(NotFoundError); }); }); });