refactor: cập nhật cấu hình ESLint, TypeScript để bao gồm tệp kiểm thử và chuẩn hóa cách sắp xếp import, ghi log.
This commit is contained in:
@@ -3,12 +3,26 @@
|
|||||||
import goodgoConfig from '@goodgo/eslint-config';
|
import goodgoConfig from '@goodgo/eslint-config';
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
...goodgoConfig,
|
// EN: Global ignores (must be first and standalone)
|
||||||
|
// VI: Ignores toàn cục (phải đặt đầu tiên và độc lập)
|
||||||
{
|
{
|
||||||
// EN: Service-specific overrides (exclude test files)
|
ignores: [
|
||||||
// VI: Override riêng cho service (loại trừ test files)
|
'**/*.test.ts',
|
||||||
files: ['**/*.ts'],
|
'**/*.spec.ts',
|
||||||
ignores: ['**/*.test.ts', '**/*.spec.ts', '**/__tests__/**'],
|
'**/*.e2e.ts',
|
||||||
|
'**/__tests__/**',
|
||||||
|
'**/tests/**',
|
||||||
|
'dist/**',
|
||||||
|
'node_modules/**',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// EN: Apply base config
|
||||||
|
// VI: Áp dụng config cơ bản
|
||||||
|
...goodgoConfig,
|
||||||
|
// EN: Service-specific configuration
|
||||||
|
// VI: Cấu hình riêng cho service
|
||||||
|
{
|
||||||
|
files: ['src/**/*.ts'],
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
tsconfigRootDir: import.meta.dirname,
|
tsconfigRootDir: import.meta.dirname,
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
ignorePatterns: ['.eslintrc.js'],
|
|
||||||
extends: ['@goodgo/eslint-config'],
|
|
||||||
root: true,
|
|
||||||
parserOptions: {
|
|
||||||
tsconfigRootDir: __dirname,
|
|
||||||
project: './tsconfig.json',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -3,12 +3,26 @@
|
|||||||
import goodgoConfig from '@goodgo/eslint-config';
|
import goodgoConfig from '@goodgo/eslint-config';
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
...goodgoConfig,
|
// EN: Global ignores (must be first and standalone)
|
||||||
|
// VI: Ignores toàn cục (phải đặt đầu tiên và độc lập)
|
||||||
{
|
{
|
||||||
// EN: Service-specific overrides (exclude test files)
|
ignores: [
|
||||||
// VI: Override riêng cho service (loại trừ test files)
|
'**/*.test.ts',
|
||||||
files: ['**/*.ts'],
|
'**/*.spec.ts',
|
||||||
ignores: ['**/*.test.ts', '**/*.spec.ts', '**/__tests__/**'],
|
'**/*.e2e.ts',
|
||||||
|
'**/__tests__/**',
|
||||||
|
'**/tests/**',
|
||||||
|
'dist/**',
|
||||||
|
'node_modules/**',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// EN: Apply base config
|
||||||
|
// VI: Áp dụng config cơ bản
|
||||||
|
...goodgoConfig,
|
||||||
|
// EN: Service-specific configuration
|
||||||
|
// VI: Cấu hình riêng cho service
|
||||||
|
{
|
||||||
|
files: ['src/**/*.ts'],
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
tsconfigRootDir: import.meta.dirname,
|
tsconfigRootDir: import.meta.dirname,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
|
|
||||||
import { createRouter } from '../routes';
|
|
||||||
import { getPrismaClient } from '../config/database.config';
|
import { getPrismaClient } from '../config/database.config';
|
||||||
|
import { createRouter } from '../routes';
|
||||||
|
|
||||||
// EN: Mock getPrismaClient to return the mocked prisma client
|
// EN: Mock getPrismaClient to return the mocked prisma client
|
||||||
// VI: Mock getPrismaClient để trả về mocked prisma client
|
// VI: Mock getPrismaClient để trả về mocked prisma client
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
|
|
||||||
import { createRouter } from '../routes';
|
|
||||||
import { getPrismaClient } from '../config/database.config';
|
import { getPrismaClient } from '../config/database.config';
|
||||||
|
import { createRouter } from '../routes';
|
||||||
|
|
||||||
// EN: Mock getPrismaClient to return a mock prisma client
|
// EN: Mock getPrismaClient to return a mock prisma client
|
||||||
// VI: Mock getPrismaClient để trả về mock prisma client
|
// VI: Mock getPrismaClient để trả về mock prisma client
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { PrismaClient } from '@prisma/client';
|
|
||||||
import { execSync } from 'child_process';
|
import { execSync } from 'child_process';
|
||||||
import { join } from 'path';
|
|
||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
// Test database configuration
|
// Test database configuration
|
||||||
export const TEST_DATABASE_URL = process.env.TEST_DATABASE_URL || 'postgresql://test:test@localhost:5433/test_iam_db';
|
export const TEST_DATABASE_URL = process.env.TEST_DATABASE_URL || 'postgresql://test:test@localhost:5433/test_iam_db';
|
||||||
@@ -14,7 +14,7 @@ let prisma: PrismaClient;
|
|||||||
*/
|
*/
|
||||||
export async function setupTestDatabase() {
|
export async function setupTestDatabase() {
|
||||||
try {
|
try {
|
||||||
console.log('🚀 Setting up test database...');
|
console.warn('🚀 Setting up test database...');
|
||||||
|
|
||||||
// Create test database if it doesn't exist
|
// Create test database if it doesn't exist
|
||||||
try {
|
try {
|
||||||
@@ -22,10 +22,10 @@ export async function setupTestDatabase() {
|
|||||||
stdio: 'pipe',
|
stdio: 'pipe',
|
||||||
env: { ...process.env, PGPASSWORD: 'test' }
|
env: { ...process.env, PGPASSWORD: 'test' }
|
||||||
});
|
});
|
||||||
console.log('✅ Test database created');
|
console.warn('✅ Test database created');
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Database might already exist, continue
|
// Database might already exist, continue
|
||||||
console.log('ℹ️ Test database already exists');
|
console.warn('ℹ️ Test database already exists');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize Prisma client with test database
|
// Initialize Prisma client with test database
|
||||||
@@ -35,23 +35,23 @@ export async function setupTestDatabase() {
|
|||||||
|
|
||||||
// Connect to database
|
// Connect to database
|
||||||
await prisma.$connect();
|
await prisma.$connect();
|
||||||
console.log('✅ Connected to test database');
|
console.warn('✅ Connected to test database');
|
||||||
|
|
||||||
// Run migrations
|
// Run migrations
|
||||||
console.log('📦 Running database migrations...');
|
console.warn('📦 Running database migrations...');
|
||||||
execSync('cd services/iam-service && pnpm prisma:migrate:deploy', {
|
execSync('cd services/iam-service && pnpm prisma:migrate:deploy', {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
env: { ...process.env, DATABASE_URL: TEST_DATABASE_URL }
|
env: { ...process.env, DATABASE_URL: TEST_DATABASE_URL }
|
||||||
});
|
});
|
||||||
console.log('✅ Migrations completed');
|
console.warn('✅ Migrations completed');
|
||||||
|
|
||||||
// Seed test data
|
// Seed test data
|
||||||
console.log('🌱 Seeding test data...');
|
console.warn('🌱 Seeding test data...');
|
||||||
execSync('cd services/iam-service && pnpm prisma:db:seed', {
|
execSync('cd services/iam-service && pnpm prisma:db:seed', {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
env: { ...process.env, DATABASE_URL: TEST_DATABASE_URL }
|
env: { ...process.env, DATABASE_URL: TEST_DATABASE_URL }
|
||||||
});
|
});
|
||||||
console.log('✅ Test data seeded');
|
console.warn('✅ Test data seeded');
|
||||||
|
|
||||||
return prisma;
|
return prisma;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -65,7 +65,7 @@ export async function setupTestDatabase() {
|
|||||||
*/
|
*/
|
||||||
export async function teardownTestDatabase() {
|
export async function teardownTestDatabase() {
|
||||||
try {
|
try {
|
||||||
console.log('🧹 Cleaning up test database...');
|
console.warn('🧹 Cleaning up test database...');
|
||||||
|
|
||||||
if (prisma) {
|
if (prisma) {
|
||||||
// Clear all data
|
// Clear all data
|
||||||
@@ -93,7 +93,7 @@ export async function teardownTestDatabase() {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
await prisma.$disconnect();
|
await prisma.$disconnect();
|
||||||
console.log('✅ Test database cleaned and disconnected');
|
console.warn('✅ Test database cleaned and disconnected');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Failed to cleanup test database:', error);
|
console.error('❌ Failed to cleanup test database:', error);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { logger } from '@goodgo/logger';
|
|
||||||
import { initTracing } from '@goodgo/tracing';
|
import { initTracing } from '@goodgo/tracing';
|
||||||
import cookieParser from 'cookie-parser';
|
import cookieParser from 'cookie-parser';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { logger } from '@goodgo/logger';
|
||||||
import { Application } from 'express';
|
import { Application } from 'express';
|
||||||
import swaggerJSDoc from 'swagger-jsdoc';
|
import swaggerJSDoc from 'swagger-jsdoc';
|
||||||
import swaggerUi from 'swagger-ui-express';
|
import swaggerUi from 'swagger-ui-express';
|
||||||
@@ -605,7 +606,7 @@ export const setupSwagger = (app: Application, basePath: string = '/api-docs') =
|
|||||||
res.send(JSON.stringify(specs, null, 2));
|
res.send(JSON.stringify(specs, null, 2));
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`📚 Swagger documentation available at: http://localhost:${appConfig.port}${basePath}`);
|
logger.info(`📚 Swagger documentation available at: http://localhost:${appConfig.port}${basePath}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export { specs };
|
export { specs };
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import request from 'supertest';
|
|
||||||
import { app } from '../../../app';
|
|
||||||
import { PrismaClient } from '@prisma/client';
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
import request from 'supertest';
|
||||||
|
|
||||||
|
import { app } from '../../../app';
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { TestFactory } from '../../../__tests__/factories';
|
||||||
import { AuthController } from '../auth.controller';
|
import { AuthController } from '../auth.controller';
|
||||||
import { authService } from '../auth.service';
|
import { authService } from '../auth.service';
|
||||||
import { TestFactory } from '../../../__tests__/factories';
|
|
||||||
|
|
||||||
// Mock dependencies
|
// Mock dependencies
|
||||||
jest.mock('../auth.service');
|
jest.mock('../auth.service');
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import { AuthService } from '../auth.service';
|
import bcrypt from 'bcryptjs';
|
||||||
|
|
||||||
|
import { TestFactory } from '../../../__tests__/factories';
|
||||||
import { prisma } from '../../../config/database.config';
|
import { prisma } from '../../../config/database.config';
|
||||||
|
import { auditService } from '../../../core/events/audit.service';
|
||||||
import { rbacService } from '../../rbac/rbac.service';
|
import { rbacService } from '../../rbac/rbac.service';
|
||||||
import { sessionService } from '../../session/session.service';
|
import { sessionService } from '../../session/session.service';
|
||||||
import { jwtService } from '../../token/jwt.service';
|
import { jwtService } from '../../token/jwt.service';
|
||||||
import { auditService } from '../../../core/events/audit.service';
|
|
||||||
import { accountLockoutService } from '../account-lockout.service';
|
import { accountLockoutService } from '../account-lockout.service';
|
||||||
import { TestFactory } from '../../../__tests__/factories';
|
import { AuthService } from '../auth.service';
|
||||||
import bcrypt from 'bcryptjs';
|
|
||||||
|
|
||||||
// Mock dependencies
|
// Mock dependencies
|
||||||
jest.mock('../../rbac/rbac.service');
|
jest.mock('../../rbac/rbac.service');
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { prisma } from '../../../config/database.config';
|
||||||
import { ConflictError } from '../../../errors/http-error';
|
import { ConflictError } from '../../../errors/http-error';
|
||||||
import { FeatureRepository } from '../feature.repository';
|
import { FeatureRepository } from '../feature.repository';
|
||||||
import { prisma } from '../../../config/database.config';
|
|
||||||
|
|
||||||
// EN: Use jest.mocked to properly type the mock
|
// EN: Use jest.mocked to properly type the mock
|
||||||
// VI: Sử dụng jest.mocked để type mock đúng cách
|
// VI: Sử dụng jest.mocked để type mock đúng cách
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export class HealthController {
|
|||||||
data: { status: 'ready' },
|
data: { status: 'ready' },
|
||||||
timestamp: new Date().toISOString(),
|
timestamp: new Date().toISOString(),
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch {
|
||||||
// EN: Return 503 if database is not ready
|
// EN: Return 503 if database is not ready
|
||||||
// VI: Trả về 503 nếu database chưa sẵn sàng
|
// VI: Trả về 503 nếu database chưa sẵn sàng
|
||||||
res.status(503).json({
|
res.status(503).json({
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { PrismaClient } from '@prisma/client';
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
import { RBACService } from '../rbac.service';
|
|
||||||
import { RoleRepository, PermissionRepository } from '../../../repositories/role.repository';
|
import { RoleRepository, PermissionRepository } from '../../../repositories/role.repository';
|
||||||
import { UserRepository } from '../../../repositories/user.repository';
|
import { UserRepository } from '../../../repositories/user.repository';
|
||||||
|
import { RBACService } from '../rbac.service';
|
||||||
|
|
||||||
// Mock dependencies
|
// Mock dependencies
|
||||||
jest.mock('../../../config/database.config');
|
jest.mock('../../../config/database.config');
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ describe('UserRepository', () => {
|
|||||||
|
|
||||||
const result = await repository.findByEmail(email);
|
const result = await repository.findByEmail(email);
|
||||||
|
|
||||||
|
expect(result).toEqual(mockUser);
|
||||||
expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
|
expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
|
||||||
where: { email },
|
where: { email },
|
||||||
include: {
|
include: {
|
||||||
@@ -68,6 +69,7 @@ describe('UserRepository', () => {
|
|||||||
|
|
||||||
const result = await repository.findByUsername(username);
|
const result = await repository.findByUsername(username);
|
||||||
|
|
||||||
|
expect(result).toEqual(mockUser);
|
||||||
expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
|
expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
|
||||||
where: { username },
|
where: { username },
|
||||||
});
|
});
|
||||||
@@ -88,6 +90,7 @@ describe('UserRepository', () => {
|
|||||||
|
|
||||||
const result = await repository.findWithPermissions(userId);
|
const result = await repository.findWithPermissions(userId);
|
||||||
|
|
||||||
|
expect(result).toEqual(mockUser);
|
||||||
expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
|
expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
|
||||||
where: { id: userId },
|
where: { id: userId },
|
||||||
include: expect.objectContaining({
|
include: expect.objectContaining({
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
generateRandomString,
|
generateRandomString,
|
||||||
hashString,
|
hashString,
|
||||||
|
|||||||
@@ -17,13 +17,12 @@
|
|||||||
"noUnusedParameters": false
|
"noUnusedParameters": false
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*"
|
"src/**/*",
|
||||||
|
"src/**/*.test.ts",
|
||||||
|
"src/__tests__/**/*"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
"dist",
|
"dist"
|
||||||
"tests",
|
|
||||||
"src/__tests__",
|
|
||||||
"**/*.test.ts"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user