Skip to main content
Glama
youtube.test.ts3.1 kB
import { beforeEach, describe, expect, it, vi } from 'vitest'; import { getTranscript, getVideoMetadata } from './youtube.js'; import * as path from 'node:path'; import * as os from 'node:os'; import * as fs from 'node:fs'; const SAMPLE_METADATA_OUTPUT = `Sample Title Sample description line 1 Sample description line 2`; const SAMPLE_VTT = `WEBVTT 00:00:00.000 --> 00:00:01.000 Hello world! 00:00:01.500 --> 00:00:03.000 This is a test. `; const spawnPromiseMock = vi.hoisted(() => vi.fn()); vi.mock('spawn-rx', () => ({ spawnPromise: (...args: readonly string[]) => spawnPromiseMock(...args), })); function ensureTranscriptWritten(args: readonly string[]) { const outputIndex = args.indexOf('--output'); if (outputIndex === -1) { throw new Error('Missing --output argument in spawnPromise mock'); } const template = args[outputIndex + 1]; const langIndex = args.indexOf('--sub-lang'); const language = langIndex !== -1 ? args[langIndex + 1] : 'ja'; const transcriptPath = template.replace('%(id)s', 'test-video').replace('%(ext)s', `${language}.vtt`); fs.mkdirSync(path.dirname(transcriptPath), { recursive: true }); fs.writeFileSync(transcriptPath, SAMPLE_VTT, 'utf8'); } describe('YouTube Transcript Extractor', () => { const TEST_VIDEO_URL = 'https://www.youtube.com/watch?v=x99-eKSyUqU'; beforeEach(() => { vi.clearAllMocks(); spawnPromiseMock.mockImplementation(async (_command: string, args: readonly string[]) => { if (args.includes('--print')) { return SAMPLE_METADATA_OUTPUT; } if (args.includes('--write-sub')) { ensureTranscriptWritten(args); return ''; } return ''; }); }); it('should extract transcript from the test video', async () => { const transcript = await getTranscript(TEST_VIDEO_URL); expect(transcript).toBe('Hello world!\nThis is a test.'); expect(spawnPromiseMock).toHaveBeenCalled(); }); it('should extract transcript with specified language', async () => { const transcript = await getTranscript(TEST_VIDEO_URL, { language: 'en' }); expect(transcript).toBe('Hello world!\nThis is a test.'); expect(spawnPromiseMock).toHaveBeenCalledWith( 'yt-dlp', expect.arrayContaining(['--sub-lang', 'en']) ); }); it('should use custom temp directory', async () => { const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'yt-test-')); try { const transcript = await getTranscript(TEST_VIDEO_URL, { language: 'ja', tempDir }); expect(transcript).toBe('Hello world!\nThis is a test.'); expect(fs.existsSync(tempDir)).toBe(true); const files = fs.readdirSync(tempDir); expect(files.some((file) => file.endsWith('.vtt'))).toBe(true); } finally { fs.rmSync(tempDir, { recursive: true, force: true }); } }); it('should get video metadata', async () => { const metadata = await getVideoMetadata(TEST_VIDEO_URL); expect(metadata).toEqual({ title: 'Sample Title', description: 'Sample description line 1\nSample description line 2', }); }); });

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/kazuph/mcp-youtube'

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