manicanldes-backend/test/auth-service.spec.ts

69 lines
2.4 KiB
TypeScript

import { AuthService } from '../src/identity/auth.service';
import { AuthStore } from '../src/identity/auth.store';
import { PasswordService } from '../src/identity/password.service';
import { RateLimitService } from '../src/identity/rate-limit.service';
import { parseEnvironment } from '../src/config/environment';
describe('login policy', () => {
const store = {
findUser: jest.fn(),
createSession: jest.fn(),
failedLogin: jest.fn(),
};
const passwords = { verify: jest.fn(), dummyVerify: jest.fn() };
const limits = { consume: jest.fn() };
const service = new AuthService(
store as unknown as AuthStore,
passwords as unknown as PasswordService,
limits as unknown as RateLimitService,
parseEnvironment({ DATABASE_URL: 'postgresql://localhost/mani' }),
);
const input = {
organizationId: 'organization',
email: 'user@example.com',
password: 'password',
};
beforeEach(() => {
jest.resetAllMocks();
store.findUser.mockResolvedValue({
id: 'user',
organizationId: 'organization',
status: 'ACTIVE',
passwordHash: 'hash',
});
passwords.verify.mockResolvedValue(true);
});
it('passes only the token digest to persistence', async () => {
const result = await service.login(input);
expect(store.createSession).toHaveBeenCalledWith(
'user',
'hash',
expect.stringMatching(/^[a-f0-9]{64}$/),
expect.any(Date),
);
expect(JSON.stringify(store.createSession.mock.calls)).not.toContain(
result.accessToken,
);
});
it('does not create sessions for unapproved users', async () => {
store.findUser.mockResolvedValue({
id: 'user',
status: 'PENDING',
organizationId: 'organization',
passwordHash: 'hash',
});
await expect(service.login(input)).rejects.toThrow('Invalid credentials');
expect(store.createSession).not.toHaveBeenCalled();
});
it('does equivalent hashing work for unknown users', async () => {
store.findUser.mockResolvedValue(null);
await expect(service.login(input)).rejects.toThrow('Invalid credentials');
expect(passwords.dummyVerify).toHaveBeenCalledWith(input.password);
});
it('stops before querying users when throttled', async () => {
limits.consume.mockRejectedValue(new Error('limited'));
await expect(service.login(input)).rejects.toThrow('limited');
expect(store.findUser).not.toHaveBeenCalled();
});
});