Set up PostgreSQL database configuration and enhance application structure
- Added .env.example with database connection details and JWT configuration. - Introduced docker-compose.yml for PostgreSQL service setup with health checks. - Created drizzle.config.ts for database schema and migration management. - Updated nest-cli.json to include Swagger plugin configuration for API documentation. - Enhanced package.json with new database-related scripts and dependencies. - Implemented initial database migrations for user and token management. - Configured application bootstrap process to load environment variables and set up Swagger. - Added shared application configuration in configure-app.ts for consistent setup. - Included unit tests for application configuration and Swagger setup.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { ConflictException } from '@nestjs/common';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { DateTime } from '../../common/value-objects/date-time/date-time';
|
||||
import type { User } from './user';
|
||||
import { UsersRepository } from './users.repository';
|
||||
import { UsersService } from './users.service';
|
||||
|
||||
describe('UsersService', () => {
|
||||
let service: UsersService;
|
||||
let repository: jest.Mocked<
|
||||
Pick<UsersRepository, 'findById' | 'findByUsername' | 'create'>
|
||||
>;
|
||||
|
||||
const now = DateTime.fromUnixMs(1_700_000_000_000);
|
||||
const sampleUser: User = {
|
||||
id: 'user-1',
|
||||
username: 'alice',
|
||||
passwordHash: 'hashed',
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
repository = {
|
||||
findById: jest.fn(),
|
||||
findByUsername: jest.fn(),
|
||||
create: jest.fn(),
|
||||
};
|
||||
|
||||
const moduleRef: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
UsersService,
|
||||
{ provide: UsersRepository, useValue: repository },
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = moduleRef.get(UsersService);
|
||||
});
|
||||
|
||||
it('findById delegates to repository', async () => {
|
||||
repository.findById.mockResolvedValue(sampleUser);
|
||||
await expect(service.findById('user-1')).resolves.toEqual(sampleUser);
|
||||
});
|
||||
|
||||
it('create stores lowercase username', async () => {
|
||||
repository.findByUsername.mockResolvedValue(null);
|
||||
repository.create.mockResolvedValue(sampleUser);
|
||||
|
||||
await service.create('Alice', 'hashed');
|
||||
|
||||
expect(repository.findByUsername).toHaveBeenCalledWith('alice');
|
||||
expect(repository.create).toHaveBeenCalledWith({
|
||||
username: 'alice',
|
||||
passwordHash: 'hashed',
|
||||
});
|
||||
});
|
||||
|
||||
it('create throws ConflictException when username exists', async () => {
|
||||
repository.findByUsername.mockResolvedValue(sampleUser);
|
||||
|
||||
await expect(service.create('alice', 'hashed')).rejects.toBeInstanceOf(
|
||||
ConflictException,
|
||||
);
|
||||
expect(repository.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('findByUsername delegates to repository', async () => {
|
||||
repository.findByUsername.mockResolvedValue(sampleUser);
|
||||
await expect(service.findByUsername('Alice')).resolves.toEqual(sampleUser);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user