Skip to main content
Glama
fileModificationApi.test.ts7.03 kB
import { describe, it, expect, beforeEach, vi } from 'vitest'; import express from 'express'; import request from 'supertest'; // Import the repositories API import { setupFileModificationRoutes } from '../../src/api/fileModificationApi'; import { RepositoryManager } from '../../src/core/repositoryManager'; describe('File Modification API', () => { let app: express.Application; let mockRepositoryManager: RepositoryManager; beforeEach(() => { // Reset mocks vi.resetAllMocks(); // Create Express app app = express(); app.use(express.json()); // Create mocked repository const mockRepo = { writeFile: vi.fn().mockResolvedValue(undefined), readFile: vi.fn().mockResolvedValue('# Existing content'), commit: vi.fn().mockResolvedValue({ success: true, hash: 'commit-hash' }), deleteFile: vi.fn().mockResolvedValue(undefined), fileExists: vi.fn().mockImplementation((path) => { return Promise.resolve(path === 'existing.md'); }), moveFile: vi.fn().mockResolvedValue(undefined) }; // Create mock repository manager mockRepositoryManager = { getRepository: vi.fn().mockImplementation((id) => { if (id === 'repo1-id') { return mockRepo; } throw new Error('Repository not found'); }), getRepositoryId: vi.fn().mockImplementation((name) => { if (name === 'repo1') { return 'repo1-id'; } throw new Error('Repository not found'); }) } as any; // Set up API routes setupFileModificationRoutes(app, mockRepositoryManager as any); }); it('should create a new file', async () => { const response = await request(app) .post('/api/repositories/repo1-id/files') .send({ path: 'new-file.md', content: '# New File\n\nThis is a new file.' }) .expect('Content-Type', /json/) .expect(201); expect(response.body).toEqual({ success: true, path: 'new-file.md', commit: 'commit-hash' }); const repository = mockRepositoryManager.getRepository('repo1-id'); expect(repository.writeFile).toHaveBeenCalledWith( 'new-file.md', '# New File\n\nThis is a new file.' ); expect(repository.commit).toHaveBeenCalledWith( expect.stringContaining('Add new-file.md') ); }); it('should update an existing file', async () => { const repository = mockRepositoryManager.getRepository('repo1-id'); const response = await request(app) .put('/api/repositories/repo1-id/files/existing.md') .send({ content: '# Updated File\n\nThis file has been updated.' }) .expect('Content-Type', /json/) .expect(200); expect(response.body).toEqual({ success: true, path: 'existing.md', commit: 'commit-hash' }); expect(repository.writeFile).toHaveBeenCalledWith( 'existing.md', '# Updated File\n\nThis file has been updated.' ); expect(repository.commit).toHaveBeenCalledWith( expect.stringContaining('Update existing.md') ); }); it('should delete a file', async () => { const repository = mockRepositoryManager.getRepository('repo1-id'); const response = await request(app) .delete('/api/repositories/repo1-id/files/existing.md') .expect('Content-Type', /json/) .expect(200); expect(response.body).toEqual({ success: true, path: 'existing.md', commit: 'commit-hash' }); expect(repository.deleteFile).toHaveBeenCalledWith('existing.md'); expect(repository.commit).toHaveBeenCalledWith( expect.stringContaining('Delete existing.md') ); }); it('should move/rename a file', async () => { const repository = mockRepositoryManager.getRepository('repo1-id'); const response = await request(app) .post('/api/repositories/repo1-id/files/move') .send({ oldPath: 'existing.md', newPath: 'renamed.md' }) .expect('Content-Type', /json/) .expect(200); expect(response.body).toEqual({ success: true, oldPath: 'existing.md', newPath: 'renamed.md', commit: 'commit-hash' }); expect(repository.moveFile).toHaveBeenCalledWith('existing.md', 'renamed.md'); expect(repository.commit).toHaveBeenCalledWith( expect.stringContaining('Move existing.md to renamed.md') ); }); it('should return 404 for non-existent repository', async () => { await request(app) .post('/api/repositories/non-existent/files') .send({ path: 'new-file.md', content: '# New File' }) .expect(404); }); it('should return 404 for non-existent file', async () => { await request(app) .put('/api/repositories/repo1-id/files/non-existent.md') .send({ content: '# Updated File' }) .expect(404); }); it('should apply a patch to a file', async () => { const repository = mockRepositoryManager.getRepository('repo1-id'); // Mock file exists check repository.fileExists = vi.fn().mockResolvedValue(true); // Mock readFile to return original content repository.readFile = vi.fn().mockResolvedValue('# Original Content\n\nThis is the original file content.'); const response = await request(app) .patch('/api/repositories/repo1-id/files/existing.md') .send({ patches: [ { operation: 'replace', path: '/title', value: 'Updated Title' }, { operation: 'add', path: '/sections/-', value: '## New Section\n\nThis is a new section.' } ] }) .expect('Content-Type', /json/) .expect(200); expect(response.body).toEqual({ success: true, path: 'existing.md', commit: 'commit-hash' }); // The implementation would need to apply the JSON Patch to the markdown, // but for this test we're just making sure the API routes are working expect(repository.writeFile).toHaveBeenCalled(); expect(repository.commit).toHaveBeenCalledWith( expect.stringContaining('Update existing.md') ); }); it('should create multiple files in a single commit', async () => { const repository = mockRepositoryManager.getRepository('repo1-id'); const response = await request(app) .post('/api/repositories/repo1-id/files/batch') .send({ files: [ { path: 'file1.md', content: '# File 1' }, { path: 'file2.md', content: '# File 2' }, { path: 'docs/file3.md', content: '# File 3' } ], commitMessage: 'Add multiple files' }) .expect('Content-Type', /json/) .expect(201); expect(response.body).toEqual({ success: true, fileCount: 3, commit: 'commit-hash' }); expect(repository.writeFile).toHaveBeenCalledTimes(3); expect(repository.commit).toHaveBeenCalledWith('Add multiple files'); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Lspace-io/lspace-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server