Skip to main content
Glama
githubGitAdapter.test.ts7.96 kB
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { GitHubAdapter } from '../../src/adapters/githubGitAdapter'; import { Repository } from '../../src/core/repository'; // Mock the GitHub API vi.mock('@octokit/rest', () => { return { Octokit: vi.fn(() => ({ repos: { get: vi.fn(), getContent: vi.fn(), createOrUpdateFileContents: vi.fn(), listCommits: vi.fn() }, git: { getTree: vi.fn(), createBlob: vi.fn(), createTree: vi.fn(), createCommit: vi.fn(), updateRef: vi.fn() } })) }; }); describe('GitHubAdapter', () => { let adapter: GitHubAdapter; let mockOctokit: any; beforeEach(() => { // Reset mocks vi.resetAllMocks(); // Create adapter with mock credentials adapter = new GitHubAdapter({ token: 'mock-token', owner: 'test-owner', repo: 'test-repo' }); // Get reference to the mocked Octokit instance mockOctokit = adapter['octokit']; }); it('should initialize a repository', async () => { // Mock repository information mockOctokit.repos.get.mockResolvedValue({ data: { name: 'test-repo', owner: { login: 'test-owner' }, default_branch: 'main' } }); // Call initialize const repository = await adapter.initialize(); // Verify the repository expect(repository).toBeInstanceOf(Repository); expect(repository.path).toBe('github://test-owner/test-repo'); // Verify that the GitHub API was called expect(mockOctokit.repos.get).toHaveBeenCalledWith({ owner: 'test-owner', repo: 'test-repo' }); }); it('should add a file to the repository', async () => { // Mock repository initialization mockOctokit.repos.get.mockResolvedValue({ data: { name: 'test-repo', owner: { login: 'test-owner' }, default_branch: 'main' } }); // Mock the GitHub API for creating file content mockOctokit.repos.createOrUpdateFileContents.mockResolvedValue({ data: { content: { sha: 'new-file-sha' }, commit: { sha: 'new-commit-sha' } } }); // Initialize repository const repository = await adapter.initialize(); // Write a file const testFilePath = 'test-file.md'; const testFileContent = '# Test File\n\nThis is a test file.'; await repository.writeFile(testFilePath, testFileContent); // Verify that the GitHub API was called to create the file expect(mockOctokit.repos.createOrUpdateFileContents).toHaveBeenCalledWith({ owner: 'test-owner', repo: 'test-repo', path: testFilePath, message: expect.stringContaining('Add test-file.md'), content: expect.any(String), // Base64 encoded content branch: 'main' }); }); it('should commit changes to the repository', async () => { // Mock repository initialization mockOctokit.repos.get.mockResolvedValue({ data: { name: 'test-repo', owner: { login: 'test-owner' }, default_branch: 'main' } }); // Mock the git API for creating a commit mockOctokit.git.createCommit.mockResolvedValue({ data: { sha: 'new-commit-sha' } }); // Mock the git API for updating a reference mockOctokit.git.updateRef.mockResolvedValue({ data: { ref: 'refs/heads/main', object: { sha: 'new-commit-sha' } } }); // Initialize repository const repository = await adapter.initialize(); // Stage a file (this is handled internally in the GitHub adapter) repository['stagedFiles'] = [ { path: 'test-file.md', content: '# Test File', mode: '100644' } ]; // Create a commit const commitResult = await repository.commit('Test commit message'); // Verify the commit result expect(commitResult.success).toBe(true); expect(commitResult.hash).toBe('new-commit-sha'); // Verify that the GitHub API was called to create the commit expect(mockOctokit.git.createCommit).toHaveBeenCalledWith({ owner: 'test-owner', repo: 'test-repo', message: 'Test commit message', tree: expect.any(String), parents: expect.any(Array) }); // Verify that the GitHub API was called to update the reference expect(mockOctokit.git.updateRef).toHaveBeenCalledWith({ owner: 'test-owner', repo: 'test-repo', ref: 'heads/main', sha: 'new-commit-sha' }); }); it('should read a file from the repository', async () => { // Mock repository initialization mockOctokit.repos.get.mockResolvedValue({ data: { name: 'test-repo', owner: { login: 'test-owner' }, default_branch: 'main' } }); // Mock the GitHub API for getting file content mockOctokit.repos.getContent.mockResolvedValue({ data: { type: 'file', content: Buffer.from('# Test File\n\nThis is a test file.').toString('base64'), encoding: 'base64' } }); // Initialize repository const repository = await adapter.initialize(); // Read a file const testFilePath = 'test-file.md'; const content = await repository.readFile(testFilePath); // Verify the content expect(content).toBe('# Test File\n\nThis is a test file.'); // Verify that the GitHub API was called to get the file content expect(mockOctokit.repos.getContent).toHaveBeenCalledWith({ owner: 'test-owner', repo: 'test-repo', path: testFilePath, ref: 'main' }); }); it('should list files in the repository', async () => { // Mock repository initialization mockOctokit.repos.get.mockResolvedValue({ data: { name: 'test-repo', owner: { login: 'test-owner' }, default_branch: 'main' } }); // Mock the git API for getting the tree mockOctokit.git.getTree.mockResolvedValue({ data: { sha: 'tree-sha', tree: [ { path: 'file1.md', type: 'blob', mode: '100644', sha: 'file1-sha' }, { path: 'file2.md', type: 'blob', mode: '100644', sha: 'file2-sha' }, { path: 'docs', type: 'tree', mode: '040000', sha: 'docs-sha' }, { path: 'docs/file3.md', type: 'blob', mode: '100644', sha: 'file3-sha' } ] } }); // Initialize repository const repository = await adapter.initialize(); // List files const files = await repository.listFiles(); // Verify the files expect(files).toHaveLength(3); expect(files).toContainEqual({ path: 'file1.md', type: 'file' }); expect(files).toContainEqual({ path: 'file2.md', type: 'file' }); expect(files).toContainEqual({ path: 'docs/file3.md', type: 'file' }); // Verify that the GitHub API was called to get the tree expect(mockOctokit.git.getTree).toHaveBeenCalledWith({ owner: 'test-owner', repo: 'test-repo', tree_sha: 'main', recursive: 1 }); }); it('should get the status of the repository', async () => { // Mock repository initialization mockOctokit.repos.get.mockResolvedValue({ data: { name: 'test-repo', owner: { login: 'test-owner' }, default_branch: 'main' } }); // Initialize repository const repository = await adapter.initialize(); // Stage some files repository['stagedFiles'] = [ { path: 'test-file.md', content: '# Test File', mode: '100644' } ]; // Get status const status = await repository.getStatus(); // Verify the status expect(status.branch).toBe('main'); expect(status.files).toHaveLength(1); expect(status.files[0]).toEqual({ path: 'test-file.md', staged: true, modified: true, added: true, deleted: false }); }); });

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