Skip to main content
Glama
JagjeevanAK

OpenFoodFacts-mcp

by JagjeevanAK
file-utils.test.ts7.12 kB
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { getDirectoryContents, getFileContents, readJsonFile, findTaxonomyFile } from '../../src/utils/file-utils'; import * as fs from 'fs/promises'; import * as path from 'path'; // Mock the fs module vi.mock('fs/promises'); vi.mock('path'); describe('File Utilities', () => { beforeEach(() => { vi.resetAllMocks(); }); afterEach(() => { vi.clearAllMocks(); }); describe('getDirectoryContents', () => { it('should return directory contents', async () => { // Mock file system calls const mockStat = { isDirectory: () => true }; const mockEntries = [ { name: 'file1.txt', isDirectory: () => false }, { name: 'folder1', isDirectory: () => true } ]; // Setup mocks vi.mocked(fs.stat).mockResolvedValue(mockStat as any); vi.mocked(fs.readdir).mockResolvedValue(mockEntries as any); vi.mocked(path.resolve).mockReturnValue('/mock/project/root/test-dir'); // Call the function const result = await getDirectoryContents('test-dir'); // Verify mocks were called correctly expect(path.resolve).toHaveBeenCalledWith('/mock/project/root', 'test-dir'); expect(fs.stat).toHaveBeenCalledWith('/mock/project/root/test-dir'); expect(fs.readdir).toHaveBeenCalledWith('/mock/project/root/test-dir', { withFileTypes: true }); // Verify the result expect(result).toBe('file1.txt (file)\nfolder1 (directory)'); }); it('should throw an error if path is outside project root', async () => { // Setup mock to return a path outside project root vi.mocked(path.resolve).mockReturnValueOnce('/outside/project/root'); // Verify error is thrown await expect(getDirectoryContents('../outside')).rejects.toThrow('Access denied'); }); it('should throw an error if path is not a directory', async () => { const mockStat = { isDirectory: () => false }; // Setup mocks vi.mocked(fs.stat).mockResolvedValue(mockStat as any); vi.mocked(path.resolve).mockReturnValue('/mock/project/root/file.txt'); // Verify error is thrown await expect(getDirectoryContents('file.txt')).rejects.toThrow('Not a directory'); }); }); describe('getFileContents', () => { it('should return file contents with metadata', async () => { // Setup mocks const mockStat = { isFile: () => true, size: 1024, mtime: new Date('2023-01-01') }; const mockContent = 'file content'; vi.mocked(fs.stat).mockResolvedValue(mockStat as any); vi.mocked(fs.readFile).mockResolvedValue(mockContent); vi.mocked(path.resolve).mockReturnValue('/mock/project/root/test-file.txt'); vi.mocked(path.basename).mockReturnValue('test-file.txt'); vi.mocked(path.extname).mockReturnValue('.txt'); // Call the function const result = await getFileContents('test-file.txt'); // Verify mocks were called correctly expect(path.resolve).toHaveBeenCalledWith('/mock/project/root', 'test-file.txt'); expect(fs.stat).toHaveBeenCalledWith('/mock/project/root/test-file.txt'); expect(fs.readFile).toHaveBeenCalledWith('/mock/project/root/test-file.txt', 'utf8'); // Verify the result expect(result).toEqual({ content: 'file content', metadata: { filename: 'test-file.txt', extension: '.txt', size: 1024, lastModified: new Date('2023-01-01').toISOString() } }); }); it('should throw an error if path is outside project root', async () => { // Setup mock to return a path outside project root vi.mocked(path.resolve).mockReturnValueOnce('/outside/project/root'); // Verify error is thrown await expect(getFileContents('../outside')).rejects.toThrow('Access denied'); }); it('should throw an error if path is not a file', async () => { const mockStat = { isFile: () => false }; // Setup mocks vi.mocked(fs.stat).mockResolvedValue(mockStat as any); vi.mocked(path.resolve).mockReturnValue('/mock/project/root/folder'); // Verify error is thrown await expect(getFileContents('folder')).rejects.toThrow('Not a file'); }); }); describe('readJsonFile', () => { it('should return parsed JSON when file exists', async () => { const mockJson = '{"name":"test","value":123}'; const mockDefaultValue = { default: true }; // Setup mocks vi.mocked(fs.readFile).mockResolvedValue(mockJson); vi.mocked(path.resolve).mockReturnValue('/mock/project/root/test.json'); // Call the function const result = await readJsonFile('test.json', mockDefaultValue); // Verify mocks were called correctly expect(path.resolve).toHaveBeenCalledWith('/mock/project/root', 'test.json'); expect(fs.readFile).toHaveBeenCalledWith('/mock/project/root/test.json', 'utf8'); // Verify the result expect(result).toEqual({ name: 'test', value: 123 }); }); it('should return default value when file does not exist', async () => { const mockDefaultValue = { default: true }; // Setup mocks vi.mocked(fs.readFile).mockRejectedValue(new Error('File not found')); // Call the function const result = await readJsonFile('nonexistent.json', mockDefaultValue); // Verify the result is the default value expect(result).toEqual(mockDefaultValue); }); }); describe('findTaxonomyFile', () => { it('should find and return taxonomy content if file exists', async () => { const mockContent = 'taxonomy content'; const taxonomyId = 'categories'; // Setup mocks for the first path vi.mocked(fs.stat).mockImplementation(async (path) => { // Only succeed for the first path if (path === '/mock/project/root/taxonomies/categories/taxonomy.txt') { return { isFile: () => true } as any; } throw new Error('File not found'); }); vi.mocked(fs.readFile).mockResolvedValue(mockContent); // Call the function const result = await findTaxonomyFile(taxonomyId); // Verify mocks were called correctly expect(fs.stat).toHaveBeenCalledWith('/mock/project/root/taxonomies/categories/taxonomy.txt'); expect(fs.readFile).toHaveBeenCalledWith('/mock/project/root/taxonomies/categories/taxonomy.txt', 'utf8'); // Verify the result expect(result).toEqual({ content: 'taxonomy content', path: 'taxonomies/categories/taxonomy.txt' }); }); it('should try multiple paths and return null if taxonomy not found', async () => { const taxonomyId = 'nonexistent'; // Setup mocks to fail for all paths vi.mocked(fs.stat).mockRejectedValue(new Error('File not found')); // Call the function const result = await findTaxonomyFile(taxonomyId); // Verify the result expect(result).toBeNull(); }); }); });

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/JagjeevanAK/OpenFoodFacts-MCP'

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