test: add unit tests for block management API endpoints

This commit is contained in:
2026-06-22 05:51:55 +00:00
parent 9cc418aa99
commit 44a5f53df2
+172
View File
@@ -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);
});
});