diff --git a/services/_template/eslint.config.js b/services/_template/eslint.config.js index eb22e384..08b95c3b 100644 --- a/services/_template/eslint.config.js +++ b/services/_template/eslint.config.js @@ -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, diff --git a/services/iam-service/.eslintrc.js b/services/iam-service/.eslintrc.js deleted file mode 100644 index 7f0d0a51..00000000 --- a/services/iam-service/.eslintrc.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - ignorePatterns: ['.eslintrc.js'], - extends: ['@goodgo/eslint-config'], - root: true, - parserOptions: { - tsconfigRootDir: __dirname, - project: './tsconfig.json', - }, -}; \ No newline at end of file diff --git a/services/iam-service/eslint.config.js b/services/iam-service/eslint.config.js index dec926df..bacec6d7 100644 --- a/services/iam-service/eslint.config.js +++ b/services/iam-service/eslint.config.js @@ -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, diff --git a/services/iam-service/src/__tests__/feature.e2e.ts b/services/iam-service/src/__tests__/feature.e2e.ts index 2a7d85ca..963ab012 100644 --- a/services/iam-service/src/__tests__/feature.e2e.ts +++ b/services/iam-service/src/__tests__/feature.e2e.ts @@ -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 diff --git a/services/iam-service/src/__tests__/health.e2e.ts b/services/iam-service/src/__tests__/health.e2e.ts index 25b6aced..212e390f 100644 --- a/services/iam-service/src/__tests__/health.e2e.ts +++ b/services/iam-service/src/__tests__/health.e2e.ts @@ -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 diff --git a/services/iam-service/src/__tests__/integration/setup.ts b/services/iam-service/src/__tests__/integration/setup.ts index a71b85c2..cebbd561 100644 --- a/services/iam-service/src/__tests__/integration/setup.ts +++ b/services/iam-service/src/__tests__/integration/setup.ts @@ -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); diff --git a/services/iam-service/src/app.ts b/services/iam-service/src/app.ts index 857e1ba8..4373ecc1 100644 --- a/services/iam-service/src/app.ts +++ b/services/iam-service/src/app.ts @@ -1,4 +1,3 @@ -import { logger } from '@goodgo/logger'; import { initTracing } from '@goodgo/tracing'; import cookieParser from 'cookie-parser'; import cors from 'cors'; diff --git a/services/iam-service/src/docs/swagger.ts b/services/iam-service/src/docs/swagger.ts index bd86cdaf..ba3c1b5d 100644 --- a/services/iam-service/src/docs/swagger.ts +++ b/services/iam-service/src/docs/swagger.ts @@ -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 }; diff --git a/services/iam-service/src/modules/auth/__tests__/auth.api.integration.test.ts b/services/iam-service/src/modules/auth/__tests__/auth.api.integration.test.ts index 6f5a8e65..9f295e39 100644 --- a/services/iam-service/src/modules/auth/__tests__/auth.api.integration.test.ts +++ b/services/iam-service/src/modules/auth/__tests__/auth.api.integration.test.ts @@ -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(); diff --git a/services/iam-service/src/modules/auth/__tests__/auth.controller.test.ts b/services/iam-service/src/modules/auth/__tests__/auth.controller.test.ts index fe0d92d1..b5bbeb2a 100644 --- a/services/iam-service/src/modules/auth/__tests__/auth.controller.test.ts +++ b/services/iam-service/src/modules/auth/__tests__/auth.controller.test.ts @@ -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'); diff --git a/services/iam-service/src/modules/auth/__tests__/auth.service.test.ts b/services/iam-service/src/modules/auth/__tests__/auth.service.test.ts index 922ab545..3edef38a 100644 --- a/services/iam-service/src/modules/auth/__tests__/auth.service.test.ts +++ b/services/iam-service/src/modules/auth/__tests__/auth.service.test.ts @@ -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'); diff --git a/services/iam-service/src/modules/feature/__tests__/feature.repository.test.ts b/services/iam-service/src/modules/feature/__tests__/feature.repository.test.ts index 0672a3bc..1d5355ed 100644 --- a/services/iam-service/src/modules/feature/__tests__/feature.repository.test.ts +++ b/services/iam-service/src/modules/feature/__tests__/feature.repository.test.ts @@ -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 diff --git a/services/iam-service/src/modules/health/health.controller.ts b/services/iam-service/src/modules/health/health.controller.ts index 8e24d82e..3d807c36 100644 --- a/services/iam-service/src/modules/health/health.controller.ts +++ b/services/iam-service/src/modules/health/health.controller.ts @@ -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({ diff --git a/services/iam-service/src/modules/rbac/__tests__/rbac.service.test.ts b/services/iam-service/src/modules/rbac/__tests__/rbac.service.test.ts index 198e963a..7817cf14 100644 --- a/services/iam-service/src/modules/rbac/__tests__/rbac.service.test.ts +++ b/services/iam-service/src/modules/rbac/__tests__/rbac.service.test.ts @@ -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'); diff --git a/services/iam-service/src/repositories/__tests__/user.repository.test.ts b/services/iam-service/src/repositories/__tests__/user.repository.test.ts index 6a1d1b8a..b4462da7 100644 --- a/services/iam-service/src/repositories/__tests__/user.repository.test.ts +++ b/services/iam-service/src/repositories/__tests__/user.repository.test.ts @@ -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({ diff --git a/services/iam-service/src/utils/__tests__/helpers.test.ts b/services/iam-service/src/utils/__tests__/helpers.test.ts index b3f03037..539c701a 100644 --- a/services/iam-service/src/utils/__tests__/helpers.test.ts +++ b/services/iam-service/src/utils/__tests__/helpers.test.ts @@ -1,4 +1,5 @@ import { Request } from 'express'; + import { generateRandomString, hashString, diff --git a/services/iam-service/tsconfig.json b/services/iam-service/tsconfig.json index 8f6d4be4..bca79862 100644 --- a/services/iam-service/tsconfig.json +++ b/services/iam-service/tsconfig.json @@ -17,13 +17,12 @@ "noUnusedParameters": false }, "include": [ - "src/**/*" + "src/**/*", + "src/**/*.test.ts", + "src/__tests__/**/*" ], "exclude": [ "node_modules", - "dist", - "tests", - "src/__tests__", - "**/*.test.ts" + "dist" ] } \ No newline at end of file