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,141 @@
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { SwaggerModule } from '@nestjs/swagger';
|
||||
import { AppController } from '../../app.controller';
|
||||
import { AppService } from '../../app.service';
|
||||
import { AuthController } from '../../modules/auth/auth.controller';
|
||||
import { AuthService } from '../../modules/auth/auth.service';
|
||||
import {
|
||||
createOpenApiDocument,
|
||||
isSwaggerEnabled,
|
||||
setupSwagger,
|
||||
} from './setup-swagger';
|
||||
|
||||
describe('isSwaggerEnabled', () => {
|
||||
it('is disabled in production by default', () => {
|
||||
expect(isSwaggerEnabled({ NODE_ENV: 'production' })).toBe(false);
|
||||
});
|
||||
|
||||
it('is enabled in production when SWAGGER_ENABLED=true', () => {
|
||||
expect(
|
||||
isSwaggerEnabled({
|
||||
NODE_ENV: 'production',
|
||||
SWAGGER_ENABLED: 'true',
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('is enabled when not production', () => {
|
||||
expect(isSwaggerEnabled({ NODE_ENV: 'development' })).toBe(true);
|
||||
});
|
||||
|
||||
it('is disabled when SWAGGER_ENABLED=false', () => {
|
||||
expect(
|
||||
isSwaggerEnabled({
|
||||
NODE_ENV: 'development',
|
||||
SWAGGER_ENABLED: 'false',
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createOpenApiDocument', () => {
|
||||
let app: INestApplication;
|
||||
|
||||
beforeAll(async () => {
|
||||
const moduleRef: TestingModule = await Test.createTestingModule({
|
||||
controllers: [AppController, AuthController],
|
||||
providers: [
|
||||
AppService,
|
||||
{
|
||||
provide: AuthService,
|
||||
useValue: {
|
||||
register: jest.fn(),
|
||||
login: jest.fn(),
|
||||
refresh: jest.fn(),
|
||||
revoke: jest.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
app = moduleRef.createNestApplication();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
it('includes auth and app paths with bearer scheme', () => {
|
||||
const document = createOpenApiDocument(app);
|
||||
|
||||
expect(document.info.title).toBe('Tracking API');
|
||||
expect(document.paths['/auth/login']).toBeDefined();
|
||||
expect(document.paths['/auth/me']).toBeDefined();
|
||||
expect(document.paths['/']).toBeDefined();
|
||||
expect(document.components?.securitySchemes?.['access-token']).toEqual(
|
||||
expect.objectContaining({ type: 'http', scheme: 'bearer' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('requires bearer on /auth/me but not on public auth posts', () => {
|
||||
const document = createOpenApiDocument(app);
|
||||
|
||||
expect(document.paths['/auth/me']?.get?.security).toEqual([
|
||||
{ 'access-token': [] },
|
||||
]);
|
||||
expect(document.paths['/auth/login']?.post?.security).toBeUndefined();
|
||||
expect(document.paths['/auth/register']?.post?.security).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('setupSwagger', () => {
|
||||
let app: INestApplication;
|
||||
let setupSpy: jest.SpyInstance;
|
||||
|
||||
beforeAll(async () => {
|
||||
const moduleRef: TestingModule = await Test.createTestingModule({
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
}).compile();
|
||||
|
||||
app = moduleRef.createNestApplication();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
setupSpy = jest
|
||||
.spyOn(SwaggerModule, 'setup')
|
||||
.mockImplementation(() => undefined);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
setupSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('skips mounting when swagger is disabled', () => {
|
||||
setupSwagger(app, {
|
||||
NODE_ENV: 'production',
|
||||
});
|
||||
|
||||
expect(setupSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('mounts at /docs when swagger is enabled', () => {
|
||||
setupSwagger(app, {
|
||||
NODE_ENV: 'test',
|
||||
});
|
||||
|
||||
expect(setupSpy).toHaveBeenCalledWith(
|
||||
'docs',
|
||||
app,
|
||||
expect.any(Object),
|
||||
expect.objectContaining({ jsonDocumentUrl: 'docs-json' }),
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user