import { NativeModules, Platform } from 'react-native' import { isTalkSpeechPlaying, shutdownTalkSpeech, speakTalkText, stopTalkSpeech, } from '../src/features/talk/talk-tts' const originalPlatform = Platform.OS beforeAll(() => { Object.defineProperty(Platform, 'OS', { configurable: true, value: 'android' }) }) afterAll(() => { Object.defineProperty(Platform, 'OS', { configurable: true, value: originalPlatform }) }) afterEach(() => { delete NativeModules.D3ROTalk jest.clearAllMocks() }) describe('Android Talk TTS bridge', () => { it('normalizes text, language and rate and returns the native completion result', async () => { const module = { speak: jest.fn().mockResolvedValue({ utteranceId: 'reply-1', status: 'completed' }), stop: jest.fn().mockResolvedValue(true), shutdown: jest.fn().mockResolvedValue(undefined), isSpeaking: jest.fn().mockResolvedValue(false), } NativeModules.D3ROTalk = module await expect(speakTalkText({ text: ' 실제 답변 ', languageTag: 'ko-KR', rate: 4, utteranceId: 'reply-1', })).resolves.toEqual({ utteranceId: 'reply-1', status: 'completed' }) expect(module.speak).toHaveBeenCalledWith({ text: '실제 답변', languageTag: 'ko-KR', rate: 2, utteranceId: 'reply-1', }) await expect(stopTalkSpeech()).resolves.toBe(true) await expect(isTalkSpeechPlaying()).resolves.toBe(false) await expect(shutdownTalkSpeech()).resolves.toBeUndefined() }) it('fails closed when the native engine is missing or text is empty', async () => { await expect(speakTalkText({ text: 'hello', languageTag: 'en-US', utteranceId: 'reply-2', })).rejects.toMatchObject({ code: 'UNAVAILABLE' }) await expect(speakTalkText({ text: ' ', languageTag: 'en-US', utteranceId: 'reply-3', })).rejects.toMatchObject({ code: 'INVALID_TEXT' }) }) })