251208:0010 Backend & Frontend Debug
Spec Validation / validate-markdown (push) Has been cancelled
Spec Validation / validate-diagrams (push) Has been cancelled
Spec Validation / check-todos (push) Has been cancelled

This commit is contained in:
2025-12-08 00:10:37 +07:00
parent 32d820ea6b
commit dcd126d704
99 changed files with 2775 additions and 1480 deletions
@@ -1,9 +1,9 @@
import { Injectable, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserAssignment } from './entities/user-assignment.entity.js'; // ต้องไปสร้าง Entity นี้ก่อน (ดูข้อ 3)
import { UserAssignment } from './entities/user-assignment.entity'; // ต้องไปสร้าง Entity นี้ก่อน (ดูข้อ 3)
import { AssignRoleDto } from './dto/assign-role.dto.js';
import { User } from './entities/user.entity.js';
import { User } from './entities/user.entity';
@Injectable()
export class UserAssignmentService {
+76 -1
View File
@@ -1,18 +1,93 @@
// File: src/modules/user/user.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { UserService } from './user.service';
import { User } from './entities/user.entity';
// Mock Repository
const mockUserRepository = {
find: jest.fn(),
findOne: jest.fn(),
create: jest.fn(),
save: jest.fn(),
merge: jest.fn(),
softDelete: jest.fn(),
query: jest.fn(),
};
// Mock Cache Manager
const mockCacheManager = {
get: jest.fn(),
set: jest.fn(),
del: jest.fn(),
};
describe('UserService', () => {
let service: UserService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UserService],
providers: [
UserService,
{
provide: getRepositoryToken(User),
useValue: mockUserRepository,
},
{
provide: CACHE_MANAGER,
useValue: mockCacheManager,
},
],
}).compile();
service = module.get<UserService>(UserService);
});
afterEach(() => {
jest.clearAllMocks();
});
it('should be defined', () => {
expect(service).toBeDefined();
});
describe('findAll', () => {
it('should return array of users', async () => {
const mockUsers = [{ user_id: 1, username: 'test' }];
mockUserRepository.find.mockResolvedValue(mockUsers);
const result = await service.findAll();
expect(result).toEqual(mockUsers);
expect(mockUserRepository.find).toHaveBeenCalled();
});
});
describe('getUserPermissions', () => {
it('should return cached permissions if available', async () => {
const cachedPermissions = ['document.view', 'document.create'];
mockCacheManager.get.mockResolvedValue(cachedPermissions);
const result = await service.getUserPermissions(1);
expect(result).toEqual(cachedPermissions);
expect(mockCacheManager.get).toHaveBeenCalledWith('permissions:user:1');
expect(mockUserRepository.query).not.toHaveBeenCalled();
});
it('should query DB and cache if not in cache', async () => {
const dbPermissions = [
{ permission_name: 'document.view' },
{ permission_name: 'document.create' },
];
mockCacheManager.get.mockResolvedValue(null);
mockUserRepository.query.mockResolvedValue(dbPermissions);
const result = await service.getUserPermissions(1);
expect(result).toEqual(['document.view', 'document.create']);
expect(mockCacheManager.set).toHaveBeenCalled();
});
});
});
+3 -3
View File
@@ -21,7 +21,7 @@ export class UserService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
@Inject(CACHE_MANAGER) private cacheManager: Cache,
@Inject(CACHE_MANAGER) private cacheManager: Cache
) {}
// 1. สร้างผู้ใช้ (Hash Password ก่อนบันทึก)
@@ -64,7 +64,7 @@ export class UserService {
async findOne(id: number): Promise<User> {
const user = await this.usersRepository.findOne({
where: { user_id: id },
relations: ['preferences', 'roles'], // [IMPORTANT] ต้องโหลด preferences มาด้วย
relations: ['preference', 'assignments'], // [IMPORTANT] ต้องโหลด preference มาด้วย
});
if (!user) {
@@ -130,7 +130,7 @@ export class UserService {
// 2. ถ้าไม่มีใน Cache ให้ Query จาก DB (View: v_user_all_permissions)
const permissions = await this.usersRepository.query(
`SELECT permission_name FROM v_user_all_permissions WHERE user_id = ?`,
[userId],
[userId]
);
const permissionList = permissions.map((row: any) => row.permission_name);