@@ -57,6 +57,7 @@ func expectNoResponse(t *testing.T, tx sip.ClientTransaction) {
57
57
type TestHandler struct {
58
58
GetAuthCredentialsFunc func (ctx context.Context , call * rpc.SIPCall ) (AuthInfo , error )
59
59
DispatchCallFunc func (ctx context.Context , info * CallInfo ) CallDispatch
60
+ OnCallEndFunc func (ctx context.Context , callInfo * livekit.SIPCallInfo , reason string )
60
61
}
61
62
62
63
func (h TestHandler ) GetAuthCredentials (ctx context.Context , call * rpc.SIPCall ) (AuthInfo , error ) {
@@ -80,6 +81,12 @@ func (h TestHandler) DeregisterTransferSIPParticipantTopic(sipCallId string) {
80
81
// no-op
81
82
}
82
83
84
+ func (h TestHandler ) OnCallEnd (ctx context.Context , callInfo * livekit.SIPCallInfo , reason string ) {
85
+ if h .OnCallEndFunc != nil {
86
+ h .OnCallEndFunc (ctx , callInfo , reason )
87
+ }
88
+ }
89
+
83
90
func testInvite (t * testing.T , h Handler , hidden bool , from , to string , test func (tx sip.ClientTransaction )) {
84
91
sipPort := rand .Intn (testPortSIPMax - testPortSIPMin ) + testPortSIPMin
85
92
localIP , err := config .GetLocalIP ()
@@ -169,3 +176,73 @@ func TestService_AuthDrop(t *testing.T) {
169
176
expectNoResponse (t , tx )
170
177
})
171
178
}
179
+
180
+ func TestService_OnCallEnd (t * testing.T ) {
181
+ const (
182
+ expectedCallID = "test-call-id"
183
+ expectedReason = "test-reason"
184
+ )
185
+
186
+ callEnded := make (chan struct {})
187
+ var receivedCallInfo * livekit.SIPCallInfo
188
+ var receivedReason string
189
+
190
+ h := & TestHandler {
191
+ GetAuthCredentialsFunc : func (ctx context.Context , call * rpc.SIPCall ) (AuthInfo , error ) {
192
+ return AuthInfo {Result : AuthAccept }, nil
193
+ },
194
+ DispatchCallFunc : func (ctx context.Context , info * CallInfo ) CallDispatch {
195
+ return CallDispatch {
196
+ Result : DispatchAccept ,
197
+ Room : RoomConfig {
198
+ RoomName : "test-room" ,
199
+ Participant : ParticipantConfig {
200
+ Identity : "test-participant" ,
201
+ },
202
+ },
203
+ }
204
+ },
205
+ OnCallEndFunc : func (ctx context.Context , callInfo * livekit.SIPCallInfo , reason string ) {
206
+ receivedCallInfo = callInfo
207
+ receivedReason = reason
208
+ close (callEnded )
209
+ },
210
+ }
211
+
212
+ // Create a new service
213
+ sipPort := rand .Intn (testPortSIPMax - testPortSIPMin ) + testPortSIPMin
214
+
215
+ mon , err := stats .NewMonitor (& config.Config {MaxCpuUtilization : 0.9 })
216
+ require .NoError (t , err )
217
+
218
+ log := logger .NewTestLogger (t )
219
+ s , err := NewService ("" , & config.Config {
220
+ SIPPort : sipPort ,
221
+ SIPPortListen : sipPort ,
222
+ RTPPort : rtcconfig.PortRange {Start : testPortRTPMin , End : testPortRTPMax },
223
+ }, mon , log , func (projectID string ) rpc.IOInfoClient { return nil })
224
+ require .NoError (t , err )
225
+ require .NotNil (t , s )
226
+ t .Cleanup (s .Stop )
227
+
228
+ s .SetHandler (h )
229
+ require .NoError (t , s .Start ())
230
+
231
+ // Call OnCallEnd directly
232
+ h .OnCallEnd (context .Background (), & livekit.SIPCallInfo {
233
+ CallId : expectedCallID ,
234
+ }, expectedReason )
235
+
236
+ // Wait for OnCallEnd to be called
237
+ select {
238
+ case <- callEnded :
239
+ // Success
240
+ case <- time .After (time .Second ):
241
+ t .Fatal ("OnCallEnd was not called" )
242
+ }
243
+
244
+ // Verify the parameters passed to OnCallEnd
245
+ require .NotNil (t , receivedCallInfo , "CallInfo should not be nil" )
246
+ require .Equal (t , expectedCallID , receivedCallInfo .CallId , "CallInfo.CallId should match" )
247
+ require .Equal (t , expectedReason , receivedReason , "Reason should match" )
248
+ }
0 commit comments