test: add unit tests for persons and projects modules
Added comprehensive unit tests for `PersonsController`, `PersonsService`, `ProjectsController`, and `ProjectsService`. Covered CRUD operations, exception handling, group/project associations, and user access validation. Mocked `JwtAuthGuard` for all tests.
This commit is contained in:
parent
0f3c55f947
commit
269ba622f8
@ -0,0 +1,154 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { PersonsController } from './persons.controller';
|
||||
import { PersonsService } from '../services/persons.service';
|
||||
import { CreatePersonDto, Gender, OralEaseLevel } from '../dto/create-person.dto';
|
||||
import { UpdatePersonDto } from '../dto/update-person.dto';
|
||||
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
|
||||
|
||||
describe('PersonsController', () => {
|
||||
let controller: PersonsController;
|
||||
let service: PersonsService;
|
||||
|
||||
// Mock data
|
||||
const mockPerson = {
|
||||
id: 'person1',
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
gender: Gender.MALE,
|
||||
technicalLevel: 3,
|
||||
hasTechnicalTraining: true,
|
||||
frenchSpeakingLevel: 4,
|
||||
oralEaseLevel: OralEaseLevel.COMFORTABLE,
|
||||
age: 30,
|
||||
projectId: 'project1',
|
||||
attributes: {},
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
const mockPersonToGroup = {
|
||||
personId: 'person1',
|
||||
groupId: 'group1',
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [PersonsController],
|
||||
providers: [
|
||||
{
|
||||
provide: PersonsService,
|
||||
useValue: {
|
||||
create: jest.fn().mockResolvedValue(mockPerson),
|
||||
findAll: jest.fn().mockResolvedValue([mockPerson]),
|
||||
findByProjectId: jest.fn().mockResolvedValue([mockPerson]),
|
||||
findById: jest.fn().mockResolvedValue(mockPerson),
|
||||
update: jest.fn().mockResolvedValue(mockPerson),
|
||||
remove: jest.fn().mockResolvedValue(mockPerson),
|
||||
findByProjectIdAndGroupId: jest.fn().mockResolvedValue([{ person: mockPerson }]),
|
||||
addToGroup: jest.fn().mockResolvedValue(mockPersonToGroup),
|
||||
removeFromGroup: jest.fn().mockResolvedValue(mockPersonToGroup),
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
.overrideGuard(JwtAuthGuard)
|
||||
.useValue({ canActivate: () => true })
|
||||
.compile();
|
||||
|
||||
controller = module.get<PersonsController>(PersonsController);
|
||||
service = module.get<PersonsService>(PersonsService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
|
||||
describe('create', () => {
|
||||
it('should create a new person', async () => {
|
||||
const createPersonDto: CreatePersonDto = {
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
gender: Gender.MALE,
|
||||
technicalLevel: 3,
|
||||
hasTechnicalTraining: true,
|
||||
frenchSpeakingLevel: 4,
|
||||
oralEaseLevel: OralEaseLevel.COMFORTABLE,
|
||||
projectId: 'project1',
|
||||
};
|
||||
|
||||
expect(await controller.create(createPersonDto)).toBe(mockPerson);
|
||||
expect(service.create).toHaveBeenCalledWith(createPersonDto);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findAll', () => {
|
||||
it('should return all persons when no projectId is provided', async () => {
|
||||
expect(await controller.findAll()).toEqual([mockPerson]);
|
||||
expect(service.findAll).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return persons filtered by projectId when projectId is provided', async () => {
|
||||
const projectId = 'project1';
|
||||
expect(await controller.findAll(projectId)).toEqual([mockPerson]);
|
||||
expect(service.findByProjectId).toHaveBeenCalledWith(projectId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findOne', () => {
|
||||
it('should return a person by ID', async () => {
|
||||
const id = 'person1';
|
||||
expect(await controller.findOne(id)).toBe(mockPerson);
|
||||
expect(service.findById).toHaveBeenCalledWith(id);
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
it('should update a person', async () => {
|
||||
const id = 'person1';
|
||||
const updatePersonDto: UpdatePersonDto = {
|
||||
firstName: 'Jane',
|
||||
};
|
||||
|
||||
expect(await controller.update(id, updatePersonDto)).toBe(mockPerson);
|
||||
expect(service.update).toHaveBeenCalledWith(id, updatePersonDto);
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove', () => {
|
||||
it('should delete a person', async () => {
|
||||
const id = 'person1';
|
||||
expect(await controller.remove(id)).toBe(mockPerson);
|
||||
expect(service.remove).toHaveBeenCalledWith(id);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findByProjectIdAndGroupId', () => {
|
||||
it('should return persons by project ID and group ID', async () => {
|
||||
const projectId = 'project1';
|
||||
const groupId = 'group1';
|
||||
|
||||
expect(await controller.findByProjectIdAndGroupId(projectId, groupId)).toEqual([{ person: mockPerson }]);
|
||||
expect(service.findByProjectIdAndGroupId).toHaveBeenCalledWith(projectId, groupId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addToGroup', () => {
|
||||
it('should add a person to a group', async () => {
|
||||
const id = 'person1';
|
||||
const groupId = 'group1';
|
||||
|
||||
expect(await controller.addToGroup(id, groupId)).toBe(mockPersonToGroup);
|
||||
expect(service.addToGroup).toHaveBeenCalledWith(id, groupId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeFromGroup', () => {
|
||||
it('should remove a person from a group', async () => {
|
||||
const id = 'person1';
|
||||
const groupId = 'group1';
|
||||
|
||||
expect(await controller.removeFromGroup(id, groupId)).toBe(mockPersonToGroup);
|
||||
expect(service.removeFromGroup).toHaveBeenCalledWith(id, groupId);
|
||||
});
|
||||
});
|
||||
});
|
277
backend/src/modules/persons/services/persons.service.spec.ts
Normal file
277
backend/src/modules/persons/services/persons.service.spec.ts
Normal file
@ -0,0 +1,277 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { PersonsService } from './persons.service';
|
||||
import { NotFoundException } from '@nestjs/common';
|
||||
import { DRIZZLE } from '../../../database/database.module';
|
||||
import { Gender, OralEaseLevel } from '../dto/create-person.dto';
|
||||
|
||||
describe('PersonsService', () => {
|
||||
let service: PersonsService;
|
||||
let mockDb: any;
|
||||
|
||||
// Mock data
|
||||
const mockPerson = {
|
||||
id: 'person1',
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
gender: Gender.MALE,
|
||||
technicalLevel: 3,
|
||||
hasTechnicalTraining: true,
|
||||
frenchSpeakingLevel: 4,
|
||||
oralEaseLevel: OralEaseLevel.COMFORTABLE,
|
||||
age: 30,
|
||||
projectId: 'project1',
|
||||
attributes: {},
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
const mockGroup = {
|
||||
id: 'group1',
|
||||
name: 'Test Group',
|
||||
projectId: 'project1',
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
const mockPersonToGroup = {
|
||||
personId: 'person1',
|
||||
groupId: 'group1',
|
||||
};
|
||||
|
||||
// Mock database operations
|
||||
const mockDbOperations = {
|
||||
select: jest.fn().mockReturnThis(),
|
||||
from: jest.fn().mockReturnThis(),
|
||||
where: jest.fn().mockReturnThis(),
|
||||
insert: jest.fn().mockReturnThis(),
|
||||
values: jest.fn().mockReturnThis(),
|
||||
update: jest.fn().mockReturnThis(),
|
||||
set: jest.fn().mockReturnThis(),
|
||||
delete: jest.fn().mockReturnThis(),
|
||||
innerJoin: jest.fn().mockReturnThis(),
|
||||
returning: jest.fn().mockImplementation(() => {
|
||||
return [mockPerson];
|
||||
}),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
mockDb = {
|
||||
...mockDbOperations,
|
||||
};
|
||||
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
PersonsService,
|
||||
{
|
||||
provide: DRIZZLE,
|
||||
useValue: mockDb,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<PersonsService>(PersonsService);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe('create', () => {
|
||||
it('should create a new person', async () => {
|
||||
const createPersonDto = {
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
gender: Gender.MALE,
|
||||
technicalLevel: 3,
|
||||
hasTechnicalTraining: true,
|
||||
frenchSpeakingLevel: 4,
|
||||
oralEaseLevel: OralEaseLevel.COMFORTABLE,
|
||||
projectId: 'project1',
|
||||
};
|
||||
|
||||
const result = await service.create(createPersonDto);
|
||||
|
||||
expect(mockDb.insert).toHaveBeenCalled();
|
||||
expect(mockDb.values).toHaveBeenCalledWith(createPersonDto);
|
||||
expect(result).toEqual(mockPerson);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findAll', () => {
|
||||
it('should return all persons', async () => {
|
||||
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.from.mockImplementationOnce(() => [mockPerson]);
|
||||
|
||||
const result = await service.findAll();
|
||||
|
||||
expect(mockDb.select).toHaveBeenCalled();
|
||||
expect(mockDb.from).toHaveBeenCalled();
|
||||
expect(result).toEqual([mockPerson]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findByProjectId', () => {
|
||||
it('should return persons for a specific project', async () => {
|
||||
const projectId = 'project1';
|
||||
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => [mockPerson]);
|
||||
|
||||
const result = await service.findByProjectId(projectId);
|
||||
|
||||
expect(mockDb.select).toHaveBeenCalled();
|
||||
expect(mockDb.from).toHaveBeenCalled();
|
||||
expect(mockDb.where).toHaveBeenCalled();
|
||||
expect(result).toEqual([mockPerson]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findById', () => {
|
||||
it('should return a person by ID', async () => {
|
||||
const id = 'person1';
|
||||
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => [mockPerson]);
|
||||
|
||||
const result = await service.findById(id);
|
||||
|
||||
expect(mockDb.select).toHaveBeenCalled();
|
||||
expect(mockDb.from).toHaveBeenCalled();
|
||||
expect(mockDb.where).toHaveBeenCalled();
|
||||
expect(result).toEqual(mockPerson);
|
||||
});
|
||||
|
||||
it('should throw NotFoundException if person not found', async () => {
|
||||
const id = 'nonexistent';
|
||||
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => []);
|
||||
|
||||
await expect(service.findById(id)).rejects.toThrow(NotFoundException);
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
it('should update a person', async () => {
|
||||
const id = 'person1';
|
||||
const updatePersonDto = {
|
||||
firstName: 'Jane',
|
||||
};
|
||||
|
||||
const result = await service.update(id, updatePersonDto);
|
||||
|
||||
expect(mockDb.update).toHaveBeenCalled();
|
||||
expect(mockDb.set).toHaveBeenCalled();
|
||||
expect(mockDb.where).toHaveBeenCalled();
|
||||
expect(result).toEqual(mockPerson);
|
||||
});
|
||||
|
||||
it('should throw NotFoundException if person not found', async () => {
|
||||
const id = 'nonexistent';
|
||||
const updatePersonDto = {
|
||||
firstName: 'Jane',
|
||||
};
|
||||
|
||||
mockDb.update.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.set.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.returning.mockImplementationOnce(() => []);
|
||||
|
||||
await expect(service.update(id, updatePersonDto)).rejects.toThrow(NotFoundException);
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove', () => {
|
||||
it('should delete a person', async () => {
|
||||
const id = 'person1';
|
||||
|
||||
const result = await service.remove(id);
|
||||
|
||||
expect(mockDb.delete).toHaveBeenCalled();
|
||||
expect(mockDb.where).toHaveBeenCalled();
|
||||
expect(result).toEqual(mockPerson);
|
||||
});
|
||||
|
||||
it('should throw NotFoundException if person not found', async () => {
|
||||
const id = 'nonexistent';
|
||||
|
||||
mockDb.delete.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.returning.mockImplementationOnce(() => []);
|
||||
|
||||
await expect(service.remove(id)).rejects.toThrow(NotFoundException);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findByProjectIdAndGroupId', () => {
|
||||
it('should return persons by project ID and group ID', async () => {
|
||||
const projectId = 'project1';
|
||||
const groupId = 'group1';
|
||||
|
||||
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.innerJoin.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => [{ person: mockPerson }]);
|
||||
|
||||
const result = await service.findByProjectIdAndGroupId(projectId, groupId);
|
||||
|
||||
expect(mockDb.select).toHaveBeenCalled();
|
||||
expect(mockDb.from).toHaveBeenCalled();
|
||||
expect(mockDb.innerJoin).toHaveBeenCalled();
|
||||
expect(mockDb.where).toHaveBeenCalled();
|
||||
expect(result).toEqual([{ person: mockPerson }]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addToGroup', () => {
|
||||
it('should add a person to a group', async () => {
|
||||
const personId = 'person1';
|
||||
const groupId = 'group1';
|
||||
|
||||
mockDb.insert.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.values.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.returning.mockImplementationOnce(() => [mockPersonToGroup]);
|
||||
|
||||
const result = await service.addToGroup(personId, groupId);
|
||||
|
||||
expect(mockDb.insert).toHaveBeenCalled();
|
||||
expect(mockDb.values).toHaveBeenCalledWith({
|
||||
personId,
|
||||
groupId,
|
||||
});
|
||||
expect(result).toEqual(mockPersonToGroup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeFromGroup', () => {
|
||||
it('should remove a person from a group', async () => {
|
||||
const personId = 'person1';
|
||||
const groupId = 'group1';
|
||||
|
||||
mockDb.delete.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.returning.mockImplementationOnce(() => [mockPersonToGroup]);
|
||||
|
||||
const result = await service.removeFromGroup(personId, groupId);
|
||||
|
||||
expect(mockDb.delete).toHaveBeenCalled();
|
||||
expect(mockDb.where).toHaveBeenCalled();
|
||||
expect(result).toEqual(mockPersonToGroup);
|
||||
});
|
||||
|
||||
it('should throw NotFoundException if relation not found', async () => {
|
||||
const personId = 'nonexistent';
|
||||
const groupId = 'group1';
|
||||
|
||||
mockDb.delete.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.returning.mockImplementationOnce(() => []);
|
||||
|
||||
await expect(service.removeFromGroup(personId, groupId)).rejects.toThrow(NotFoundException);
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,116 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ProjectsController } from './projects.controller';
|
||||
import { ProjectsService } from '../services/projects.service';
|
||||
import { CreateProjectDto } from '../dto/create-project.dto';
|
||||
import { UpdateProjectDto } from '../dto/update-project.dto';
|
||||
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
|
||||
|
||||
describe('ProjectsController', () => {
|
||||
let controller: ProjectsController;
|
||||
let service: ProjectsService;
|
||||
|
||||
// Mock data
|
||||
const mockProject = {
|
||||
id: 'project1',
|
||||
name: 'Test Project',
|
||||
description: 'Test Description',
|
||||
ownerId: 'user1',
|
||||
settings: {},
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [ProjectsController],
|
||||
providers: [
|
||||
{
|
||||
provide: ProjectsService,
|
||||
useValue: {
|
||||
create: jest.fn().mockResolvedValue(mockProject),
|
||||
findAll: jest.fn().mockResolvedValue([mockProject]),
|
||||
findByOwnerId: jest.fn().mockResolvedValue([mockProject]),
|
||||
findById: jest.fn().mockResolvedValue(mockProject),
|
||||
update: jest.fn().mockResolvedValue(mockProject),
|
||||
remove: jest.fn().mockResolvedValue(mockProject),
|
||||
checkUserAccess: jest.fn().mockResolvedValue(true),
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
.overrideGuard(JwtAuthGuard)
|
||||
.useValue({ canActivate: () => true })
|
||||
.compile();
|
||||
|
||||
controller = module.get<ProjectsController>(ProjectsController);
|
||||
service = module.get<ProjectsService>(ProjectsService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
|
||||
describe('create', () => {
|
||||
it('should create a new project', async () => {
|
||||
const createProjectDto: CreateProjectDto = {
|
||||
name: 'Test Project',
|
||||
description: 'Test Description',
|
||||
ownerId: 'user1',
|
||||
};
|
||||
|
||||
expect(await controller.create(createProjectDto)).toBe(mockProject);
|
||||
expect(service.create).toHaveBeenCalledWith(createProjectDto);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findAll', () => {
|
||||
it('should return all projects when no ownerId is provided', async () => {
|
||||
expect(await controller.findAll()).toEqual([mockProject]);
|
||||
expect(service.findAll).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return projects filtered by ownerId when ownerId is provided', async () => {
|
||||
const ownerId = 'user1';
|
||||
expect(await controller.findAll(ownerId)).toEqual([mockProject]);
|
||||
expect(service.findByOwnerId).toHaveBeenCalledWith(ownerId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findOne', () => {
|
||||
it('should return a project by ID', async () => {
|
||||
const id = 'project1';
|
||||
expect(await controller.findOne(id)).toBe(mockProject);
|
||||
expect(service.findById).toHaveBeenCalledWith(id);
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
it('should update a project', async () => {
|
||||
const id = 'project1';
|
||||
const updateProjectDto: UpdateProjectDto = {
|
||||
name: 'Updated Project',
|
||||
};
|
||||
|
||||
expect(await controller.update(id, updateProjectDto)).toBe(mockProject);
|
||||
expect(service.update).toHaveBeenCalledWith(id, updateProjectDto);
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove', () => {
|
||||
it('should delete a project', async () => {
|
||||
const id = 'project1';
|
||||
expect(await controller.remove(id)).toBe(mockProject);
|
||||
expect(service.remove).toHaveBeenCalledWith(id);
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkUserAccess', () => {
|
||||
it('should check if a user has access to a project', async () => {
|
||||
const projectId = 'project1';
|
||||
const userId = 'user1';
|
||||
|
||||
expect(await controller.checkUserAccess(projectId, userId)).toBe(true);
|
||||
expect(service.checkUserAccess).toHaveBeenCalledWith(projectId, userId);
|
||||
});
|
||||
});
|
||||
});
|
217
backend/src/modules/projects/services/projects.service.spec.ts
Normal file
217
backend/src/modules/projects/services/projects.service.spec.ts
Normal file
@ -0,0 +1,217 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ProjectsService } from './projects.service';
|
||||
import { NotFoundException } from '@nestjs/common';
|
||||
import { DRIZZLE } from '../../../database/database.module';
|
||||
|
||||
describe('ProjectsService', () => {
|
||||
let service: ProjectsService;
|
||||
let mockDb: any;
|
||||
|
||||
// Mock data
|
||||
const mockProject = {
|
||||
id: 'project1',
|
||||
name: 'Test Project',
|
||||
description: 'Test Description',
|
||||
ownerId: 'user1',
|
||||
settings: {},
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
// Mock database operations
|
||||
const mockDbOperations = {
|
||||
select: jest.fn().mockReturnThis(),
|
||||
from: jest.fn().mockReturnThis(),
|
||||
where: jest.fn().mockReturnThis(),
|
||||
insert: jest.fn().mockReturnThis(),
|
||||
values: jest.fn().mockReturnThis(),
|
||||
update: jest.fn().mockReturnThis(),
|
||||
set: jest.fn().mockReturnThis(),
|
||||
delete: jest.fn().mockReturnThis(),
|
||||
returning: jest.fn().mockImplementation(() => {
|
||||
return [mockProject];
|
||||
}),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
mockDb = {
|
||||
...mockDbOperations,
|
||||
};
|
||||
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
ProjectsService,
|
||||
{
|
||||
provide: DRIZZLE,
|
||||
useValue: mockDb,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<ProjectsService>(ProjectsService);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe('create', () => {
|
||||
it('should create a new project', async () => {
|
||||
const createProjectDto = {
|
||||
name: 'Test Project',
|
||||
description: 'Test Description',
|
||||
ownerId: 'user1',
|
||||
};
|
||||
|
||||
const result = await service.create(createProjectDto);
|
||||
|
||||
expect(mockDb.insert).toHaveBeenCalled();
|
||||
expect(mockDb.values).toHaveBeenCalledWith(createProjectDto);
|
||||
expect(result).toEqual(mockProject);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findAll', () => {
|
||||
it('should return all projects', async () => {
|
||||
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.from.mockImplementationOnce(() => [mockProject]);
|
||||
|
||||
const result = await service.findAll();
|
||||
|
||||
expect(mockDb.select).toHaveBeenCalled();
|
||||
expect(mockDb.from).toHaveBeenCalled();
|
||||
expect(result).toEqual([mockProject]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findByOwnerId', () => {
|
||||
it('should return projects for a specific owner', async () => {
|
||||
const ownerId = 'user1';
|
||||
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => [mockProject]);
|
||||
|
||||
const result = await service.findByOwnerId(ownerId);
|
||||
|
||||
expect(mockDb.select).toHaveBeenCalled();
|
||||
expect(mockDb.from).toHaveBeenCalled();
|
||||
expect(mockDb.where).toHaveBeenCalled();
|
||||
expect(result).toEqual([mockProject]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findById', () => {
|
||||
it('should return a project by ID', async () => {
|
||||
const id = 'project1';
|
||||
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => [mockProject]);
|
||||
|
||||
const result = await service.findById(id);
|
||||
|
||||
expect(mockDb.select).toHaveBeenCalled();
|
||||
expect(mockDb.from).toHaveBeenCalled();
|
||||
expect(mockDb.where).toHaveBeenCalled();
|
||||
expect(result).toEqual(mockProject);
|
||||
});
|
||||
|
||||
it('should throw NotFoundException if project not found', async () => {
|
||||
const id = 'nonexistent';
|
||||
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => []);
|
||||
|
||||
await expect(service.findById(id)).rejects.toThrow(NotFoundException);
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
it('should update a project', async () => {
|
||||
const id = 'project1';
|
||||
const updateProjectDto = {
|
||||
name: 'Updated Project',
|
||||
};
|
||||
|
||||
const result = await service.update(id, updateProjectDto);
|
||||
|
||||
expect(mockDb.update).toHaveBeenCalled();
|
||||
expect(mockDb.set).toHaveBeenCalled();
|
||||
expect(mockDb.where).toHaveBeenCalled();
|
||||
expect(result).toEqual(mockProject);
|
||||
});
|
||||
|
||||
it('should throw NotFoundException if project not found', async () => {
|
||||
const id = 'nonexistent';
|
||||
const updateProjectDto = {
|
||||
name: 'Updated Project',
|
||||
};
|
||||
|
||||
mockDb.update.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.set.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.returning.mockImplementationOnce(() => []);
|
||||
|
||||
await expect(service.update(id, updateProjectDto)).rejects.toThrow(NotFoundException);
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove', () => {
|
||||
it('should delete a project', async () => {
|
||||
const id = 'project1';
|
||||
|
||||
const result = await service.remove(id);
|
||||
|
||||
expect(mockDb.delete).toHaveBeenCalled();
|
||||
expect(mockDb.where).toHaveBeenCalled();
|
||||
expect(result).toEqual(mockProject);
|
||||
});
|
||||
|
||||
it('should throw NotFoundException if project not found', async () => {
|
||||
const id = 'nonexistent';
|
||||
|
||||
mockDb.delete.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.returning.mockImplementationOnce(() => []);
|
||||
|
||||
await expect(service.remove(id)).rejects.toThrow(NotFoundException);
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkUserAccess', () => {
|
||||
it('should return true if user has access to project', async () => {
|
||||
const projectId = 'project1';
|
||||
const userId = 'user1';
|
||||
|
||||
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => [mockProject]);
|
||||
|
||||
const result = await service.checkUserAccess(projectId, userId);
|
||||
|
||||
expect(mockDb.select).toHaveBeenCalled();
|
||||
expect(mockDb.from).toHaveBeenCalled();
|
||||
expect(mockDb.where).toHaveBeenCalled();
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if user does not have access to project', async () => {
|
||||
const projectId = 'project1';
|
||||
const userId = 'user2';
|
||||
|
||||
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||
mockDbOperations.where.mockImplementationOnce(() => []);
|
||||
|
||||
const result = await service.checkUserAccess(projectId, userId);
|
||||
|
||||
expect(mockDb.select).toHaveBeenCalled();
|
||||
expect(mockDb.from).toHaveBeenCalled();
|
||||
expect(mockDb.where).toHaveBeenCalled();
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user