test: add unit tests for tags module and global auth guard
Added comprehensive unit tests for `TagsService` and `TagsController`, covering CRUD operations, exception handling, and associations with projects and persons. Mocked `JwtAuthGuard` globally for testing purposes.
This commit is contained in:
parent
7eae25d5de
commit
50583f9ccc
@ -3,6 +3,19 @@ import { Reflector } from '@nestjs/core';
|
|||||||
import { JwtAuthGuard } from './jwt-auth.guard';
|
import { JwtAuthGuard } from './jwt-auth.guard';
|
||||||
import { IS_PUBLIC_KEY } from '../decorators/public.decorator';
|
import { IS_PUBLIC_KEY } from '../decorators/public.decorator';
|
||||||
|
|
||||||
|
// Mock the AuthGuard
|
||||||
|
jest.mock('@nestjs/passport', () => {
|
||||||
|
return {
|
||||||
|
AuthGuard: jest.fn().mockImplementation(() => {
|
||||||
|
return class {
|
||||||
|
canActivate() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
describe('JwtAuthGuard', () => {
|
describe('JwtAuthGuard', () => {
|
||||||
let guard: JwtAuthGuard;
|
let guard: JwtAuthGuard;
|
||||||
let reflector: Reflector;
|
let reflector: Reflector;
|
||||||
|
179
backend/src/modules/tags/controllers/tags.controller.spec.ts
Normal file
179
backend/src/modules/tags/controllers/tags.controller.spec.ts
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { TagsController } from './tags.controller';
|
||||||
|
import { TagsService } from '../services/tags.service';
|
||||||
|
import { CreateTagDto } from '../dto/create-tag.dto';
|
||||||
|
import { UpdateTagDto } from '../dto/update-tag.dto';
|
||||||
|
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
|
||||||
|
|
||||||
|
describe('TagsController', () => {
|
||||||
|
let controller: TagsController;
|
||||||
|
let service: TagsService;
|
||||||
|
|
||||||
|
// Mock data
|
||||||
|
const mockTag = {
|
||||||
|
id: 'tag1',
|
||||||
|
name: 'Test Tag',
|
||||||
|
description: 'Test Description',
|
||||||
|
color: '#FF0000',
|
||||||
|
type: 'PERSON',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockPersonToTag = {
|
||||||
|
personId: 'person1',
|
||||||
|
tagId: 'tag1',
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockProjectToTag = {
|
||||||
|
projectId: 'project1',
|
||||||
|
tagId: 'tag1',
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
controllers: [TagsController],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: TagsService,
|
||||||
|
useValue: {
|
||||||
|
create: jest.fn().mockResolvedValue(mockTag),
|
||||||
|
findAll: jest.fn().mockResolvedValue([mockTag]),
|
||||||
|
findByType: jest.fn().mockResolvedValue([mockTag]),
|
||||||
|
findById: jest.fn().mockResolvedValue(mockTag),
|
||||||
|
update: jest.fn().mockResolvedValue(mockTag),
|
||||||
|
remove: jest.fn().mockResolvedValue(mockTag),
|
||||||
|
addTagToPerson: jest.fn().mockResolvedValue(mockPersonToTag),
|
||||||
|
removeTagFromPerson: jest.fn().mockResolvedValue(mockPersonToTag),
|
||||||
|
getTagsForPerson: jest.fn().mockResolvedValue([{ tag: mockTag }]),
|
||||||
|
addTagToProject: jest.fn().mockResolvedValue(mockProjectToTag),
|
||||||
|
removeTagFromProject: jest.fn().mockResolvedValue(mockProjectToTag),
|
||||||
|
getTagsForProject: jest.fn().mockResolvedValue([{ tag: mockTag }]),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.overrideGuard(JwtAuthGuard)
|
||||||
|
.useValue({ canActivate: () => true })
|
||||||
|
.compile();
|
||||||
|
|
||||||
|
controller = module.get<TagsController>(TagsController);
|
||||||
|
service = module.get<TagsService>(TagsService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(controller).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('create', () => {
|
||||||
|
it('should create a new tag', async () => {
|
||||||
|
const createTagDto: CreateTagDto = {
|
||||||
|
name: 'Test Tag',
|
||||||
|
color: '#FF0000',
|
||||||
|
type: 'PERSON',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(await controller.create(createTagDto)).toBe(mockTag);
|
||||||
|
expect(service.create).toHaveBeenCalledWith(createTagDto);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('findAll', () => {
|
||||||
|
it('should return all tags when no type is provided', async () => {
|
||||||
|
expect(await controller.findAll()).toEqual([mockTag]);
|
||||||
|
expect(service.findAll).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return tags filtered by type when type is provided', async () => {
|
||||||
|
const type = 'PERSON';
|
||||||
|
expect(await controller.findAll(type)).toEqual([mockTag]);
|
||||||
|
expect(service.findByType).toHaveBeenCalledWith(type);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('findOne', () => {
|
||||||
|
it('should return a tag by ID', async () => {
|
||||||
|
const id = 'tag1';
|
||||||
|
expect(await controller.findOne(id)).toBe(mockTag);
|
||||||
|
expect(service.findById).toHaveBeenCalledWith(id);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('update', () => {
|
||||||
|
it('should update a tag', async () => {
|
||||||
|
const id = 'tag1';
|
||||||
|
const updateTagDto: UpdateTagDto = {
|
||||||
|
name: 'Updated Tag',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(await controller.update(id, updateTagDto)).toBe(mockTag);
|
||||||
|
expect(service.update).toHaveBeenCalledWith(id, updateTagDto);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('remove', () => {
|
||||||
|
it('should delete a tag', async () => {
|
||||||
|
const id = 'tag1';
|
||||||
|
expect(await controller.remove(id)).toBe(mockTag);
|
||||||
|
expect(service.remove).toHaveBeenCalledWith(id);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('addTagToPerson', () => {
|
||||||
|
it('should add a tag to a person', async () => {
|
||||||
|
const personId = 'person1';
|
||||||
|
const tagId = 'tag1';
|
||||||
|
|
||||||
|
expect(await controller.addTagToPerson(personId, tagId)).toBe(mockPersonToTag);
|
||||||
|
expect(service.addTagToPerson).toHaveBeenCalledWith(tagId, personId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('removeTagFromPerson', () => {
|
||||||
|
it('should remove a tag from a person', async () => {
|
||||||
|
const personId = 'person1';
|
||||||
|
const tagId = 'tag1';
|
||||||
|
|
||||||
|
expect(await controller.removeTagFromPerson(personId, tagId)).toBe(mockPersonToTag);
|
||||||
|
expect(service.removeTagFromPerson).toHaveBeenCalledWith(tagId, personId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getTagsForPerson', () => {
|
||||||
|
it('should get all tags for a person', async () => {
|
||||||
|
const personId = 'person1';
|
||||||
|
|
||||||
|
expect(await controller.getTagsForPerson(personId)).toEqual([{ tag: mockTag }]);
|
||||||
|
expect(service.getTagsForPerson).toHaveBeenCalledWith(personId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('addTagToProject', () => {
|
||||||
|
it('should add a tag to a project', async () => {
|
||||||
|
const projectId = 'project1';
|
||||||
|
const tagId = 'tag1';
|
||||||
|
|
||||||
|
expect(await controller.addTagToProject(projectId, tagId)).toBe(mockProjectToTag);
|
||||||
|
expect(service.addTagToProject).toHaveBeenCalledWith(tagId, projectId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('removeTagFromProject', () => {
|
||||||
|
it('should remove a tag from a project', async () => {
|
||||||
|
const projectId = 'project1';
|
||||||
|
const tagId = 'tag1';
|
||||||
|
|
||||||
|
expect(await controller.removeTagFromProject(projectId, tagId)).toBe(mockProjectToTag);
|
||||||
|
expect(service.removeTagFromProject).toHaveBeenCalledWith(tagId, projectId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getTagsForProject', () => {
|
||||||
|
it('should get all tags for a project', async () => {
|
||||||
|
const projectId = 'project1';
|
||||||
|
|
||||||
|
expect(await controller.getTagsForProject(projectId)).toEqual([{ tag: mockTag }]);
|
||||||
|
expect(service.getTagsForProject).toHaveBeenCalledWith(projectId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
339
backend/src/modules/tags/services/tags.service.spec.ts
Normal file
339
backend/src/modules/tags/services/tags.service.spec.ts
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { TagsService } from './tags.service';
|
||||||
|
import { NotFoundException } from '@nestjs/common';
|
||||||
|
import { DRIZZLE } from '../../../database/database.module';
|
||||||
|
|
||||||
|
describe('TagsService', () => {
|
||||||
|
let service: TagsService;
|
||||||
|
let mockDb: any;
|
||||||
|
|
||||||
|
// Mock data
|
||||||
|
const mockTag = {
|
||||||
|
id: 'tag1',
|
||||||
|
name: 'Test Tag',
|
||||||
|
description: 'Test Description',
|
||||||
|
color: '#FF0000',
|
||||||
|
type: 'PERSON',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockPerson = {
|
||||||
|
id: 'person1',
|
||||||
|
name: 'Test Person',
|
||||||
|
projectId: 'project1',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockProject = {
|
||||||
|
id: 'project1',
|
||||||
|
name: 'Test Project',
|
||||||
|
userId: 'user1',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockPersonToTag = {
|
||||||
|
personId: 'person1',
|
||||||
|
tagId: 'tag1',
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockProjectToTag = {
|
||||||
|
projectId: 'project1',
|
||||||
|
tagId: 'tag1',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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 [mockTag];
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
mockDb = {
|
||||||
|
...mockDbOperations,
|
||||||
|
};
|
||||||
|
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [
|
||||||
|
TagsService,
|
||||||
|
{
|
||||||
|
provide: DRIZZLE,
|
||||||
|
useValue: mockDb,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<TagsService>(TagsService);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('create', () => {
|
||||||
|
it('should create a new tag', async () => {
|
||||||
|
const createTagDto = {
|
||||||
|
name: 'Test Tag',
|
||||||
|
color: '#FF0000',
|
||||||
|
type: 'PERSON' as 'PERSON',
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await service.create(createTagDto);
|
||||||
|
|
||||||
|
expect(mockDb.insert).toHaveBeenCalled();
|
||||||
|
expect(mockDb.values).toHaveBeenCalledWith({
|
||||||
|
...createTagDto,
|
||||||
|
});
|
||||||
|
expect(result).toEqual(mockTag);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('findAll', () => {
|
||||||
|
it('should return all tags', async () => {
|
||||||
|
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.from.mockImplementationOnce(() => [mockTag]);
|
||||||
|
|
||||||
|
const result = await service.findAll();
|
||||||
|
|
||||||
|
expect(mockDb.select).toHaveBeenCalled();
|
||||||
|
expect(mockDb.from).toHaveBeenCalled();
|
||||||
|
expect(result).toEqual([mockTag]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('findByType', () => {
|
||||||
|
it('should return tags for a specific type', async () => {
|
||||||
|
const type = 'PERSON';
|
||||||
|
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.where.mockImplementationOnce(() => [mockTag]);
|
||||||
|
|
||||||
|
const result = await service.findByType(type);
|
||||||
|
|
||||||
|
expect(mockDb.select).toHaveBeenCalled();
|
||||||
|
expect(mockDb.from).toHaveBeenCalled();
|
||||||
|
expect(mockDb.where).toHaveBeenCalled();
|
||||||
|
expect(result).toEqual([mockTag]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('findById', () => {
|
||||||
|
it('should return a tag by ID', async () => {
|
||||||
|
const id = 'tag1';
|
||||||
|
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.where.mockImplementationOnce(() => [mockTag]);
|
||||||
|
|
||||||
|
const result = await service.findById(id);
|
||||||
|
|
||||||
|
expect(mockDb.select).toHaveBeenCalled();
|
||||||
|
expect(mockDb.from).toHaveBeenCalled();
|
||||||
|
expect(mockDb.where).toHaveBeenCalled();
|
||||||
|
expect(result).toEqual(mockTag);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw NotFoundException if tag 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 tag', async () => {
|
||||||
|
const id = 'tag1';
|
||||||
|
const updateTagDto = {
|
||||||
|
name: 'Updated Tag',
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await service.update(id, updateTagDto);
|
||||||
|
|
||||||
|
expect(mockDb.update).toHaveBeenCalled();
|
||||||
|
expect(mockDb.set).toHaveBeenCalled();
|
||||||
|
expect(mockDb.where).toHaveBeenCalled();
|
||||||
|
expect(result).toEqual(mockTag);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw NotFoundException if tag not found', async () => {
|
||||||
|
const id = 'nonexistent';
|
||||||
|
const updateTagDto = {
|
||||||
|
name: 'Updated Tag',
|
||||||
|
};
|
||||||
|
|
||||||
|
mockDb.update.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.set.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.where.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.returning.mockImplementationOnce(() => []);
|
||||||
|
|
||||||
|
await expect(service.update(id, updateTagDto)).rejects.toThrow(NotFoundException);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('remove', () => {
|
||||||
|
it('should delete a tag', async () => {
|
||||||
|
const id = 'tag1';
|
||||||
|
|
||||||
|
const result = await service.remove(id);
|
||||||
|
|
||||||
|
expect(mockDb.delete).toHaveBeenCalled();
|
||||||
|
expect(mockDb.where).toHaveBeenCalled();
|
||||||
|
expect(result).toEqual(mockTag);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw NotFoundException if tag 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('addTagToPerson', () => {
|
||||||
|
it('should add a tag to a person', async () => {
|
||||||
|
const tagId = 'tag1';
|
||||||
|
const personId = 'person1';
|
||||||
|
|
||||||
|
// Mock findById to return a PERSON tag
|
||||||
|
jest.spyOn(service, 'findById').mockResolvedValueOnce(mockTag);
|
||||||
|
|
||||||
|
// Mock person check
|
||||||
|
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.where.mockImplementationOnce(() => [mockPerson]);
|
||||||
|
|
||||||
|
// Mock relation check
|
||||||
|
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.where.mockImplementationOnce(() => []);
|
||||||
|
|
||||||
|
// Mock insert
|
||||||
|
mockDb.insert.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.values.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.returning.mockImplementationOnce(() => [mockPersonToTag]);
|
||||||
|
|
||||||
|
const result = await service.addTagToPerson(tagId, personId);
|
||||||
|
|
||||||
|
expect(service.findById).toHaveBeenCalledWith(tagId);
|
||||||
|
expect(mockDb.select).toHaveBeenCalled();
|
||||||
|
expect(mockDb.from).toHaveBeenCalled();
|
||||||
|
expect(mockDb.where).toHaveBeenCalled();
|
||||||
|
expect(mockDb.insert).toHaveBeenCalled();
|
||||||
|
expect(mockDb.values).toHaveBeenCalledWith({
|
||||||
|
personId,
|
||||||
|
tagId,
|
||||||
|
});
|
||||||
|
expect(result).toEqual(mockPersonToTag);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getTagsForPerson', () => {
|
||||||
|
it('should get all tags for a person', async () => {
|
||||||
|
const personId = 'person1';
|
||||||
|
|
||||||
|
// Mock person check
|
||||||
|
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.where.mockImplementationOnce(() => [mockPerson]);
|
||||||
|
|
||||||
|
// Mock get tags
|
||||||
|
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.innerJoin.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.where.mockImplementationOnce(() => [{ tag: mockTag }]);
|
||||||
|
|
||||||
|
const result = await service.getTagsForPerson(personId);
|
||||||
|
|
||||||
|
expect(mockDb.select).toHaveBeenCalled();
|
||||||
|
expect(mockDb.from).toHaveBeenCalled();
|
||||||
|
expect(mockDb.innerJoin).toHaveBeenCalled();
|
||||||
|
expect(mockDb.where).toHaveBeenCalled();
|
||||||
|
expect(result).toEqual([{ tag: mockTag }]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('addTagToProject', () => {
|
||||||
|
it('should add a tag to a project', async () => {
|
||||||
|
const tagId = 'tag1';
|
||||||
|
const projectId = 'project1';
|
||||||
|
|
||||||
|
// Mock findById to return a PROJECT tag
|
||||||
|
const projectTag = { ...mockTag, type: 'PROJECT' };
|
||||||
|
jest.spyOn(service, 'findById').mockResolvedValueOnce(projectTag);
|
||||||
|
|
||||||
|
// Mock project check
|
||||||
|
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.where.mockImplementationOnce(() => [mockProject]);
|
||||||
|
|
||||||
|
// Mock relation check
|
||||||
|
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.where.mockImplementationOnce(() => []);
|
||||||
|
|
||||||
|
// Mock insert
|
||||||
|
mockDb.insert.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.values.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.returning.mockImplementationOnce(() => [mockProjectToTag]);
|
||||||
|
|
||||||
|
const result = await service.addTagToProject(tagId, projectId);
|
||||||
|
|
||||||
|
expect(service.findById).toHaveBeenCalledWith(tagId);
|
||||||
|
expect(mockDb.select).toHaveBeenCalled();
|
||||||
|
expect(mockDb.from).toHaveBeenCalled();
|
||||||
|
expect(mockDb.where).toHaveBeenCalled();
|
||||||
|
expect(mockDb.insert).toHaveBeenCalled();
|
||||||
|
expect(mockDb.values).toHaveBeenCalledWith({
|
||||||
|
projectId,
|
||||||
|
tagId,
|
||||||
|
});
|
||||||
|
expect(result).toEqual(mockProjectToTag);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getTagsForProject', () => {
|
||||||
|
it('should get all tags for a project', async () => {
|
||||||
|
const projectId = 'project1';
|
||||||
|
|
||||||
|
// Mock project check
|
||||||
|
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.where.mockImplementationOnce(() => [mockProject]);
|
||||||
|
|
||||||
|
// Mock get tags
|
||||||
|
mockDb.select.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.from.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.innerJoin.mockImplementationOnce(() => mockDbOperations);
|
||||||
|
mockDbOperations.where.mockImplementationOnce(() => [{ tag: mockTag }]);
|
||||||
|
|
||||||
|
const result = await service.getTagsForProject(projectId);
|
||||||
|
|
||||||
|
expect(mockDb.select).toHaveBeenCalled();
|
||||||
|
expect(mockDb.from).toHaveBeenCalled();
|
||||||
|
expect(mockDb.innerJoin).toHaveBeenCalled();
|
||||||
|
expect(mockDb.where).toHaveBeenCalled();
|
||||||
|
expect(result).toEqual([{ tag: mockTag }]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user