test: add unit tests for block management API endpoints
This commit is contained in:
@@ -0,0 +1,172 @@
|
|||||||
|
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||||
|
import { fastify } from 'fastify';
|
||||||
|
import blocksRoutes from '../blocks';
|
||||||
|
import { BlockService } from '../../services/blockService';
|
||||||
|
|
||||||
|
// Mock BlockService
|
||||||
|
vi.mock('../../services/blockService', () => ({
|
||||||
|
BlockService: {
|
||||||
|
listBlocks: vi.fn(),
|
||||||
|
createBlock: vi.fn(),
|
||||||
|
updateBlock: vi.fn(),
|
||||||
|
deleteBlock: vi.fn(),
|
||||||
|
insertBlockInstance: vi.fn()
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Mock auth middleware
|
||||||
|
vi.mock('../middleware/auth', () => ({
|
||||||
|
authenticate: vi.fn(async (request, reply, done) => done()),
|
||||||
|
authorizeProjectMember: vi.fn(async (request, reply, done) => done()),
|
||||||
|
authorizePlanner: vi.fn(async (request, reply, done) => done())
|
||||||
|
}));
|
||||||
|
|
||||||
|
const app = fastify();
|
||||||
|
app.register(blocksRoutes, { prefix: '/projects/:projectId/blocks' });
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GET /projects/:projectId/blocks', () => {
|
||||||
|
it('should return list of blocks', async () => {
|
||||||
|
const mockBlocks = [{ id: '1', name: 'Block 1' }];
|
||||||
|
(BlockService.listBlocks as vi.Mock).mockResolvedValue(mockBlocks);
|
||||||
|
|
||||||
|
const response = await app.inject({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/projects/123/blocks'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toBe(200);
|
||||||
|
expect(JSON.parse(response.body)).toEqual(mockBlocks);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle errors', async () => {
|
||||||
|
(BlockService.listBlocks as vi.Mock).mockRejectedValue(new Error('Database error'));
|
||||||
|
|
||||||
|
const response = await app.inject({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/projects/123/blocks'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toBe(500);
|
||||||
|
expect(JSON.parse(response.body)).toEqual({ error: 'Failed to list blocks' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('POST /projects/:projectId/blocks', () => {
|
||||||
|
it('should create a new block', async () => {
|
||||||
|
const mockBlock = { id: '1', name: 'New Block' };
|
||||||
|
(BlockService.createBlock as vi.Mock).mockResolvedValue(mockBlock);
|
||||||
|
|
||||||
|
const response = await app.inject({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/projects/123/blocks',
|
||||||
|
payload: {
|
||||||
|
name: 'New Block',
|
||||||
|
elements: ['element1', 'element2']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toBe(201);
|
||||||
|
expect(JSON.parse(response.body)).toEqual(mockBlock);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle validation errors', async () => {
|
||||||
|
const response = await app.inject({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/projects/123/blocks',
|
||||||
|
payload: {
|
||||||
|
// name is missing
|
||||||
|
elements: ['element1', 'element2']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toBe(400);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('PUT /projects/:projectId/blocks/:blockId', () => {
|
||||||
|
it('should update a block', async () => {
|
||||||
|
const mockBlock = { id: '1', name: 'Updated Block' };
|
||||||
|
(BlockService.updateBlock as vi.Mock).mockResolvedValue(mockBlock);
|
||||||
|
|
||||||
|
const response = await app.inject({
|
||||||
|
method: 'PUT',
|
||||||
|
url: '/projects/123/blocks/1',
|
||||||
|
payload: {
|
||||||
|
name: 'Updated Block'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toBe(200);
|
||||||
|
expect(JSON.parse(response.body)).toEqual(mockBlock);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle validation errors', async () => {
|
||||||
|
const response = await app.inject({
|
||||||
|
method: 'PUT',
|
||||||
|
url: '/projects/123/blocks/invalid-id',
|
||||||
|
payload: {
|
||||||
|
name: 'Updated Block'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toBe(400);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('DELETE /projects/:projectId/blocks/:blockId', () => {
|
||||||
|
it('should delete a block', async () => {
|
||||||
|
(BlockService.deleteBlock as vi.Mock).mockResolvedValue(undefined);
|
||||||
|
|
||||||
|
const response = await app.inject({
|
||||||
|
method: 'DELETE',
|
||||||
|
url: '/projects/123/blocks/1'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toBe(204);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle validation errors', async () => {
|
||||||
|
const response = await app.inject({
|
||||||
|
method: 'DELETE',
|
||||||
|
url: '/projects/123/blocks/invalid-id'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toBe(400);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('POST /projects/:projectId/blocks/:blockId/insert', () => {
|
||||||
|
it('should insert a block instance', async () => {
|
||||||
|
const mockInstance = { id: '1', blockId: '1', position_x: 0, position_y: 0 };
|
||||||
|
(BlockService.insertBlockInstance as vi.Mock).mockResolvedValue(mockInstance);
|
||||||
|
|
||||||
|
const response = await app.inject({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/projects/123/blocks/1/insert',
|
||||||
|
payload: {
|
||||||
|
position_x: 0,
|
||||||
|
position_y: 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toBe(201);
|
||||||
|
expect(JSON.parse(response.body)).toEqual(mockInstance);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle validation errors', async () => {
|
||||||
|
const response = await app.inject({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/projects/123/blocks/1/insert',
|
||||||
|
payload: {
|
||||||
|
// position_x is missing
|
||||||
|
position_y: 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toBe(400);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user