Skip to main content
Glama
voice-input-state.test.ts8.31 kB
import { TestServer } from '../test-utils/test-server.js'; describe('Voice Input State Error Handling', () => { let server: TestServer; beforeEach(async () => { server = new TestServer(); await server.start(); }); afterEach(async () => { await server.stop(); }); describe('POST /api/dequeue-utterances', () => { it('should return 400 error when voice input is not active', async () => { // Add an utterance await fetch(`${server.url}/api/potential-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: 'Test utterance' }) }); // Try to dequeue without activating voice input const response = await fetch(`${server.url}/api/dequeue-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const data = await response.json() as any; expect(response.status).toBe(400); expect(data.success).toBe(false); expect(data.error).toContain('Voice input is not active'); }); it('should dequeue utterances successfully when voice input is active', async () => { // Enable voice input await fetch(`${server.url}/api/voice-input`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ active: true }) }); // Add utterances await fetch(`${server.url}/api/potential-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: 'Test utterance 1' }) }); await fetch(`${server.url}/api/potential-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: 'Test utterance 2' }) }); // Dequeue should succeed const response = await fetch(`${server.url}/api/dequeue-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const data = await response.json() as any; expect(response.status).toBe(200); expect(data.success).toBe(true); expect(data.utterances.length).toBe(2); }); it('should dequeue all pending utterances when voice input is active', async () => { // Enable voice input await fetch(`${server.url}/api/voice-input`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ active: true }) }); // Add multiple utterances for (let i = 1; i <= 5; i++) { await fetch(`${server.url}/api/potential-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: `Utterance ${i}` }) }); } // Dequeue all const response = await fetch(`${server.url}/api/dequeue-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const data = await response.json() as any; expect(response.status).toBe(200); expect(data.success).toBe(true); expect(data.utterances.length).toBe(5); // Verify all are delivered const statusResponse = await fetch(`${server.url}/api/utterances/status`); const statusData = await statusResponse.json() as any; expect(statusData.pending).toBe(0); expect(statusData.delivered).toBe(5); }); }); describe('POST /api/wait-for-utterances', () => { it('should return 400 error when voice input is not active', async () => { const response = await fetch(`${server.url}/api/wait-for-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const data = await response.json() as any; expect(response.status).toBe(400); expect(data.success).toBe(false); expect(data.error).toContain('Voice input is not active'); }); it('should process wait request when voice input is active', async () => { // Enable voice input await fetch(`${server.url}/api/voice-input`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ active: true }) }); // Add an utterance await fetch(`${server.url}/api/potential-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: 'Test utterance' }) }); // Wait should find it const response = await fetch(`${server.url}/api/wait-for-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const data = await response.json() as any; expect(response.status).toBe(200); expect(data.success).toBe(true); expect(data.utterances.length).toBe(1); expect(data.utterances[0].text).toBe('Test utterance'); }); it('should return immediately when voice input is deactivated during wait', async () => { // Enable voice input await fetch(`${server.url}/api/voice-input`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ active: true }) }); // Wait with no utterances (in real server this would poll, but our test server returns immediately) const response = await fetch(`${server.url}/api/wait-for-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const data = await response.json() as any; expect(response.status).toBe(200); expect(data.success).toBe(true); expect(data.utterances.length).toBe(0); }); }); describe('Voice input state transitions', () => { it('should allow dequeue when voice input is activated', async () => { // Add an utterance await fetch(`${server.url}/api/potential-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: 'Test' }) }); // Dequeue should fail when voice input is off let response = await fetch(`${server.url}/api/dequeue-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); expect(response.status).toBe(400); // Activate voice input await fetch(`${server.url}/api/voice-input`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ active: true }) }); // Now dequeue should succeed response = await fetch(`${server.url}/api/dequeue-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); expect(response.status).toBe(200); }); it('should prevent dequeue when voice input is deactivated', async () => { // Enable voice input await fetch(`${server.url}/api/voice-input`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ active: true }) }); // Add an utterance await fetch(`${server.url}/api/potential-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: 'Test' }) }); // Dequeue should succeed let response = await fetch(`${server.url}/api/dequeue-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); expect(response.status).toBe(200); // Add another utterance await fetch(`${server.url}/api/potential-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: 'Test 2' }) }); // Deactivate voice input await fetch(`${server.url}/api/voice-input`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ active: false }) }); // Now dequeue should fail response = await fetch(`${server.url}/api/dequeue-utterances`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); expect(response.status).toBe(400); }); }); });

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/johnmatthewtennant/mcp-voice-hooks'

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