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:
Ho Ngoc Hai
2026-01-07 18:15:00 +07:00
parent eca4b84249
commit a7d2362b2f
17 changed files with 76 additions and 51 deletions

View File

@@ -3,12 +3,26 @@
import goodgoConfig from '@goodgo/eslint-config';
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)
// VI: Override riêng cho service (loại trừ test files)
files: ['**/*.ts'],
ignores: ['**/*.test.ts', '**/*.spec.ts', '**/__tests__/**'],
ignores: [
'**/*.test.ts',
'**/*.spec.ts',
'**/*.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: {
parserOptions: {
tsconfigRootDir: import.meta.dirname,

View File

@@ -1,9 +0,0 @@
module.exports = {
ignorePatterns: ['.eslintrc.js'],
extends: ['@goodgo/eslint-config'],
root: true,
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json',
},
};

View File

@@ -3,12 +3,26 @@
import goodgoConfig from '@goodgo/eslint-config';
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)
// VI: Override riêng cho service (loại trừ test files)
files: ['**/*.ts'],
ignores: ['**/*.test.ts', '**/*.spec.ts', '**/__tests__/**'],
ignores: [
'**/*.test.ts',
'**/*.spec.ts',
'**/*.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: {
parserOptions: {
tsconfigRootDir: import.meta.dirname,

View File

@@ -1,8 +1,8 @@
import express from 'express';
import request from 'supertest';
import { createRouter } from '../routes';
import { getPrismaClient } from '../config/database.config';
import { createRouter } from '../routes';
// EN: Mock getPrismaClient to return the mocked prisma client
// VI: Mock getPrismaClient để trả về mocked prisma client

View File

@@ -1,8 +1,8 @@
import express from 'express';
import request from 'supertest';
import { createRouter } from '../routes';
import { getPrismaClient } from '../config/database.config';
import { createRouter } from '../routes';
// EN: Mock getPrismaClient to return a mock prisma client
// VI: Mock getPrismaClient để trả về mock prisma client

View File

@@ -1,6 +1,6 @@
import { PrismaClient } from '@prisma/client';
import { execSync } from 'child_process';
import { join } from 'path';
import { PrismaClient } from '@prisma/client';
// Test database configuration
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() {
try {
console.log('🚀 Setting up test database...');
console.warn('🚀 Setting up test database...');
// Create test database if it doesn't exist
try {
@@ -22,10 +22,10 @@ export async function setupTestDatabase() {
stdio: 'pipe',
env: { ...process.env, PGPASSWORD: 'test' }
});
console.log('✅ Test database created');
} catch (error) {
console.warn('✅ Test database created');
} catch {
// Database might already exist, continue
console.log(' Test database already exists');
console.warn(' Test database already exists');
}
// Initialize Prisma client with test database
@@ -35,23 +35,23 @@ export async function setupTestDatabase() {
// Connect to database
await prisma.$connect();
console.log('✅ Connected to test database');
console.warn('✅ Connected to test database');
// Run migrations
console.log('📦 Running database migrations...');
console.warn('📦 Running database migrations...');
execSync('cd services/iam-service && pnpm prisma:migrate:deploy', {
stdio: 'inherit',
env: { ...process.env, DATABASE_URL: TEST_DATABASE_URL }
});
console.log('✅ Migrations completed');
console.warn('✅ Migrations completed');
// Seed test data
console.log('🌱 Seeding test data...');
console.warn('🌱 Seeding test data...');
execSync('cd services/iam-service && pnpm prisma:db:seed', {
stdio: 'inherit',
env: { ...process.env, DATABASE_URL: TEST_DATABASE_URL }
});
console.log('✅ Test data seeded');
console.warn('✅ Test data seeded');
return prisma;
} catch (error) {
@@ -65,7 +65,7 @@ export async function setupTestDatabase() {
*/
export async function teardownTestDatabase() {
try {
console.log('🧹 Cleaning up test database...');
console.warn('🧹 Cleaning up test database...');
if (prisma) {
// Clear all data
@@ -93,7 +93,7 @@ export async function teardownTestDatabase() {
]);
await prisma.$disconnect();
console.log('✅ Test database cleaned and disconnected');
console.warn('✅ Test database cleaned and disconnected');
}
} catch (error) {
console.error('❌ Failed to cleanup test database:', error);

View File

@@ -1,4 +1,3 @@
import { logger } from '@goodgo/logger';
import { initTracing } from '@goodgo/tracing';
import cookieParser from 'cookie-parser';
import cors from 'cors';

View File

@@ -1,3 +1,4 @@
import { logger } from '@goodgo/logger';
import { Application } from 'express';
import swaggerJSDoc from 'swagger-jsdoc';
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));
});
console.log(`📚 Swagger documentation available at: http://localhost:${appConfig.port}${basePath}`);
logger.info(`📚 Swagger documentation available at: http://localhost:${appConfig.port}${basePath}`);
};
export { specs };

View File

@@ -1,6 +1,7 @@
import request from 'supertest';
import { app } from '../../../app';
import { PrismaClient } from '@prisma/client';
import request from 'supertest';
import { app } from '../../../app';
const prisma = new PrismaClient();

View File

@@ -1,6 +1,6 @@
import { TestFactory } from '../../../__tests__/factories';
import { AuthController } from '../auth.controller';
import { authService } from '../auth.service';
import { TestFactory } from '../../../__tests__/factories';
// Mock dependencies
jest.mock('../auth.service');

View File

@@ -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 { auditService } from '../../../core/events/audit.service';
import { rbacService } from '../../rbac/rbac.service';
import { sessionService } from '../../session/session.service';
import { jwtService } from '../../token/jwt.service';
import { auditService } from '../../../core/events/audit.service';
import { accountLockoutService } from '../account-lockout.service';
import { TestFactory } from '../../../__tests__/factories';
import bcrypt from 'bcryptjs';
import { AuthService } from '../auth.service';
// Mock dependencies
jest.mock('../../rbac/rbac.service');

View File

@@ -1,6 +1,6 @@
import { prisma } from '../../../config/database.config';
import { ConflictError } from '../../../errors/http-error';
import { FeatureRepository } from '../feature.repository';
import { prisma } from '../../../config/database.config';
// EN: Use jest.mocked to properly type the mock
// VI: Sử dụng jest.mocked để type mock đúng cách

View File

@@ -39,7 +39,7 @@ export class HealthController {
data: { status: 'ready' },
timestamp: new Date().toISOString(),
});
} catch (error) {
} catch {
// EN: Return 503 if database is not ready
// VI: Trả về 503 nếu database chưa sẵn sàng
res.status(503).json({

View File

@@ -1,8 +1,8 @@
import { PrismaClient } from '@prisma/client';
import { RBACService } from '../rbac.service';
import { RoleRepository, PermissionRepository } from '../../../repositories/role.repository';
import { UserRepository } from '../../../repositories/user.repository';
import { RBACService } from '../rbac.service';
// Mock dependencies
jest.mock('../../../config/database.config');

View File

@@ -40,6 +40,7 @@ describe('UserRepository', () => {
const result = await repository.findByEmail(email);
expect(result).toEqual(mockUser);
expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
where: { email },
include: {
@@ -68,6 +69,7 @@ describe('UserRepository', () => {
const result = await repository.findByUsername(username);
expect(result).toEqual(mockUser);
expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
where: { username },
});
@@ -88,6 +90,7 @@ describe('UserRepository', () => {
const result = await repository.findWithPermissions(userId);
expect(result).toEqual(mockUser);
expect(mockPrisma.user.findUnique).toHaveBeenCalledWith({
where: { id: userId },
include: expect.objectContaining({

View File

@@ -1,4 +1,5 @@
import { Request } from 'express';
import {
generateRandomString,
hashString,

View File

@@ -17,13 +17,12 @@
"noUnusedParameters": false
},
"include": [
"src/**/*"
"src/**/*",
"src/**/*.test.ts",
"src/__tests__/**/*"
],
"exclude": [
"node_modules",
"dist",
"tests",
"src/__tests__",
"**/*.test.ts"
"dist"
]
}