Skip to main content
Glama

Peekaboo MCP

by steipete
RealtimeVoiceServiceTests.swiftβ€’7.83 kB
// // RealtimeVoiceServiceTests.swift // PeekabooTests // import Testing import Foundation import PeekabooCore import Tachikoma @testable import Peekaboo @Suite("RealtimeVoiceService Tests", .tags(.unit, .ai), .disabled("Uses PeekabooServices.shared which may hang")) @MainActor struct RealtimeVoiceServiceTests { // MARK: - Test Helpers private func createMockDependencies() -> (PeekabooAgentService, SessionStore, PeekabooSettings) { let services = PeekabooServices.shared let agentService = try! PeekabooAgentService(services: services) let sessionStore = SessionStore() let settings = PeekabooSettings() return (agentService, sessionStore, settings) } // MARK: - Initialization Tests @Test("Service initializes with correct dependencies") func serviceInitialization() throws { let (agentService, sessionStore, settings) = createMockDependencies() let service = RealtimeVoiceService( agentService: agentService, sessionStore: sessionStore, settings: settings ) #expect(service.isConnected == false) #expect(service.connectionState == .idle) #expect(service.currentTranscript.isEmpty) #expect(service.conversationHistory.isEmpty) #expect(service.error == nil) #expect(service.isRecording == false) #expect(service.isSpeaking == false) #expect(service.audioLevel == 0.0) #expect(service.selectedVoice == .alloy) } @Test("Service loads voice preference from settings") func voicePreferenceLoading() throws { let (agentService, sessionStore, settings) = createMockDependencies() // Set a voice preference in settings settings.realtimeVoice = "echo" let service = RealtimeVoiceService( agentService: agentService, sessionStore: sessionStore, settings: settings ) #expect(service.selectedVoice == .echo) } // MARK: - Session Management Tests @Test("Starting session without API key fails", .tags(.integration)) func startSessionWithoutAPIKey() async throws { let (agentService, sessionStore, settings) = createMockDependencies() // Ensure no API key is set settings.openAIAPIKey = "" TachikomaConfiguration.current.setAPIKey("", for: .openai) let service = RealtimeVoiceService( agentService: agentService, sessionStore: sessionStore, settings: settings ) await #expect(throws: Error.self) { try await service.startSession() } #expect(service.isConnected == false) #expect(service.error != nil) } @Test("Ending session cleans up properly") func endSessionCleanup() async throws { let (agentService, sessionStore, settings) = createMockDependencies() let service = RealtimeVoiceService( agentService: agentService, sessionStore: sessionStore, settings: settings ) // Simulate a connected state await service.endSession() #expect(service.conversation == nil) #expect(service.isConnected == false) #expect(service.connectionState == .idle) #expect(service.isRecording == false) #expect(service.isSpeaking == false) #expect(service.audioLevel == 0.0) } // MARK: - Recording Tests @Test("Toggle recording requires active connection") func toggleRecordingWithoutConnection() async throws { let (agentService, sessionStore, settings) = createMockDependencies() let service = RealtimeVoiceService( agentService: agentService, sessionStore: sessionStore, settings: settings ) await #expect(throws: RealtimeError.notConnected) { try await service.toggleRecording() } } // MARK: - Message Sending Tests @Test("Sending message requires active connection") func sendMessageWithoutConnection() async throws { let (agentService, sessionStore, settings) = createMockDependencies() let service = RealtimeVoiceService( agentService: agentService, sessionStore: sessionStore, settings: settings ) await #expect(throws: RealtimeError.notConnected) { try await service.sendMessage("Test message") } } @Test("Sending message updates conversation history") func sendMessageUpdatesHistory() async throws { let (agentService, sessionStore, settings) = createMockDependencies() let service = RealtimeVoiceService( agentService: agentService, sessionStore: sessionStore, settings: settings ) // Note: This would require mocking the conversation // For now, we just verify the method exists and can be called #expect(service.conversationHistory.isEmpty) } // MARK: - Voice Settings Tests @Test("Update voice setting persists to settings") func updateVoicePersistence() throws { let (agentService, sessionStore, settings) = createMockDependencies() let service = RealtimeVoiceService( agentService: agentService, sessionStore: sessionStore, settings: settings ) service.updateVoice(.shimmer) #expect(service.selectedVoice == .shimmer) #expect(settings.realtimeVoice == "shimmer") } // MARK: - Interrupt Tests @Test("Interrupt requires active connection") func interruptWithoutConnection() async throws { let (agentService, sessionStore, settings) = createMockDependencies() let service = RealtimeVoiceService( agentService: agentService, sessionStore: sessionStore, settings: settings ) await #expect(throws: RealtimeError.notConnected) { try await service.interrupt() } } // MARK: - Error Handling Tests @Test("Service handles connection failures gracefully") func connectionFailureHandling() async throws { let (agentService, sessionStore, settings) = createMockDependencies() // Set an invalid API key to trigger failure settings.openAIAPIKey = "invalid-key" TachikomaConfiguration.current.setAPIKey("invalid-key", for: .openai) let service = RealtimeVoiceService( agentService: agentService, sessionStore: sessionStore, settings: settings ) do { try await service.startSession() Issue.record("Expected connection to fail with invalid API key") } catch { #expect(service.error != nil) #expect(service.isConnected == false) } } // MARK: - State Management Tests @Test("Connection states transition correctly") func connectionStateTransitions() throws { let (agentService, sessionStore, settings) = createMockDependencies() let service = RealtimeVoiceService( agentService: agentService, sessionStore: sessionStore, settings: settings ) // Initial state #expect(service.connectionState == .idle) // Other state transitions would require mocking the conversation } } // MARK: - Test Tags // Tags are already defined in TestTags.swift

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/steipete/Peekaboo'

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