@@ -61,8 +61,8 @@ describe("bandwidthRtcV1 sendDtmf", () => {
6161 setupMocks ( ) ;
6262 } ) ;
6363
64- function makeDtmfSender ( ) {
65- return { insertDTMF : jest . fn ( ) } ;
64+ function makeDtmfSender ( canInsertDTMF : boolean = true ) {
65+ return { insertDTMF : jest . fn ( ) , canInsertDTMF } ;
6666 }
6767
6868 test ( "calls insertDTMF on all registered senders when no streamId given" , ( ) => {
@@ -117,9 +117,41 @@ describe("bandwidthRtcV1 sendDtmf", () => {
117117
118118 expect ( sender . insertDTMF ) . not . toHaveBeenCalled ( ) ;
119119 } ) ;
120+
121+ test ( "skips a sender that is not ready (canInsertDTMF false) without throwing" , ( ) => {
122+ const brtc = new BandwidthRtc ( ) ;
123+ const notReady = makeDtmfSender ( false ) ;
124+ const ready = makeDtmfSender ( true ) ;
125+ ( brtc as any ) . localDtmfSenders . set ( "stream-1" , notReady ) ;
126+ ( brtc as any ) . localDtmfSenders . set ( "stream-2" , ready ) ;
127+
128+ expect ( ( ) => brtc . sendDtmf ( "5" ) ) . not . toThrow ( ) ;
129+
130+ expect ( notReady . insertDTMF ) . not . toHaveBeenCalled ( ) ;
131+ expect ( ready . insertDTMF ) . toHaveBeenCalledWith ( "5" , 100 , 70 ) ;
132+ } ) ;
133+
134+ test ( "catches an insertDTMF error on one sender and still calls the others" , ( ) => {
135+ const brtc = new BandwidthRtc ( ) ;
136+ const throwing = makeDtmfSender ( ) ;
137+ throwing . insertDTMF . mockImplementation ( ( ) => {
138+ throw new DOMException ( "not ready" , "InvalidStateError" ) ;
139+ } ) ;
140+ const healthy = makeDtmfSender ( ) ;
141+ ( brtc as any ) . localDtmfSenders . set ( "stream-1" , throwing ) ;
142+ ( brtc as any ) . localDtmfSenders . set ( "stream-2" , healthy ) ;
143+
144+ expect ( ( ) => brtc . sendDtmf ( "5" ) ) . not . toThrow ( ) ;
145+
146+ expect ( healthy . insertDTMF ) . toHaveBeenCalledWith ( "5" , 100 , 70 ) ;
147+ } ) ;
120148} ) ;
121149
122150describe ( "bandwidthRtcV1 addStreamToPublishingPeerConnection" , ( ) => {
151+ afterEach ( ( ) => {
152+ delete ( global as any ) . RTCRtpSender ;
153+ } ) ;
154+
123155 function makeTransceiver ( dtmf : RTCDTMFSender | null = { insertDTMF : jest . fn ( ) } as any ) {
124156 return { sender : { dtmf } , setCodecPreferences : jest . fn ( ) } ;
125157 }
@@ -191,6 +223,30 @@ describe("bandwidthRtcV1 addStreamToPublishingPeerConnection", () => {
191223
192224 expect ( transceiver . setCodecPreferences ) . toHaveBeenCalledWith ( [ opusCodec ] ) ;
193225 } ) ;
226+
227+ test ( "forces telephone-event into codec preferences even without explicit codecPreferences" , ( ) => {
228+ const brtc = new BandwidthRtc ( ) ;
229+ const transceiver = makeTransceiver ( ) ;
230+ withPublishingPeerConnection ( brtc , transceiver ) ;
231+
232+ const opusCodec = { mimeType : "audio/opus" , clockRate : 48000 } ;
233+ const telephoneEventCodec = { mimeType : "audio/telephone-event" , clockRate : 8000 } ;
234+ ( global as any ) . RTCRtpSender = { getCapabilities : jest . fn ( ) . mockReturnValue ( { codecs : [ opusCodec , telephoneEventCodec ] } ) } ;
235+
236+ ( brtc as any ) . addStreamToPublishingPeerConnection ( makeMockStream ( "stream-1" , "audio" ) ) ;
237+
238+ expect ( transceiver . setCodecPreferences ) . toHaveBeenCalledWith ( [ opusCodec , telephoneEventCodec ] ) ;
239+ } ) ;
240+
241+ test ( "skips setCodecPreferences when RTCRtpSender is unavailable (e.g. non-browser environment)" , ( ) => {
242+ const brtc = new BandwidthRtc ( ) ;
243+ const transceiver = makeTransceiver ( ) ;
244+ withPublishingPeerConnection ( brtc , transceiver ) ;
245+
246+ expect ( ( ) => ( brtc as any ) . addStreamToPublishingPeerConnection ( makeMockStream ( "stream-1" , "audio" ) ) ) . not . toThrow ( ) ;
247+
248+ expect ( transceiver . setCodecPreferences ) . not . toHaveBeenCalled ( ) ;
249+ } ) ;
194250} ) ;
195251
196252describe ( "bandwidthRtcV1 connect method" , ( ) => {
0 commit comments