Files
gridpilot.gg/adapters/identity/persistence/inmemory/InMemoryUserRepository.test.ts
2025-12-23 20:43:57 +01:00

70 lines
2.1 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { Logger } from '@core/shared/application';
import type { StoredUser } from '@core/identity/domain/repositories/IUserRepository';
import { InMemoryUserRepository } from './InMemoryUserRepository';
describe('InMemoryUserRepository', () => {
let repository: InMemoryUserRepository;
let mockLogger: Logger;
beforeEach(() => {
mockLogger = {
debug: vi.fn(),
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
} as unknown as Logger;
const seeded: StoredUser[] = [
{
id: 'u1',
email: 'seed@example.com',
displayName: 'Seed',
passwordHash: 'hash',
salt: 'salt',
createdAt: new Date('2025-01-01T00:00:00.000Z'),
},
];
repository = new InMemoryUserRepository(mockLogger, seeded);
});
it('finds by email and id', async () => {
expect((await repository.findByEmail('seed@example.com'))?.id).toBe('u1');
expect((await repository.findById('u1'))?.email).toBe('seed@example.com');
expect(await repository.findByEmail('missing@example.com')).toBeNull();
});
it('creates and rejects duplicate emails', async () => {
const user: StoredUser = {
id: 'u2',
email: 'new@example.com',
displayName: 'New',
passwordHash: 'hash2',
salt: 'salt2',
createdAt: new Date(),
};
await repository.create(user);
expect(await repository.emailExists('new@example.com')).toBe(true);
await expect(repository.create({ ...user, id: 'u3' })).rejects.toThrow('Email already exists');
});
it('updates and maintains email index', async () => {
const existing = await repository.findById('u1');
expect(existing).not.toBeNull();
const updated: StoredUser = {
...(existing as StoredUser),
email: 'changed@example.com',
displayName: 'Changed',
};
await repository.update(updated);
expect(await repository.findByEmail('seed@example.com')).toBeNull();
expect((await repository.findByEmail('changed@example.com'))?.displayName).toBe('Changed');
});
});