@@ -362,6 +362,201 @@ func TestSIPDispatchRuleFilter(t *testing.T) {
362362 }
363363}
364364
365+ func TestTransferSIPParticipantRequestValidate (t * testing.T ) {
366+ cases := []struct {
367+ name string
368+ req * TransferSIPParticipantRequest
369+ expectError bool
370+ expectedURI string // Expected TransferTo after validation
371+ }{
372+ {
373+ name : "valid sip URI without brackets" ,
374+ req : & TransferSIPParticipantRequest {
375+ RoomName : "room1" ,
376+ ParticipantIdentity : "participant1" ,
377+ TransferTo :
"sip:[email protected] " ,
378+ },
379+ expectError : false ,
380+ expectedURI :
"<sip:[email protected] >" ,
381+ },
382+ {
383+ name : "valid tel URI without brackets" ,
384+ req : & TransferSIPParticipantRequest {
385+ RoomName : "room1" ,
386+ ParticipantIdentity : "participant1" ,
387+ TransferTo : "tel:+15105550100" ,
388+ },
389+ expectError : false ,
390+ expectedURI : "<tel:+15105550100>" ,
391+ },
392+ {
393+ name : "valid sip URI with brackets" ,
394+ req : & TransferSIPParticipantRequest {
395+ RoomName : "room1" ,
396+ ParticipantIdentity : "participant1" ,
397+ TransferTo :
"<sip:[email protected] >" ,
398+ },
399+ expectError : false ,
400+ expectedURI :
"<sip:[email protected] >" ,
401+ },
402+ {
403+ name : "valid tel URI with brackets" ,
404+ req : & TransferSIPParticipantRequest {
405+ RoomName : "room1" ,
406+ ParticipantIdentity : "participant1" ,
407+ TransferTo : "<tel:+15105550100>" ,
408+ },
409+ expectError : false ,
410+ expectedURI : "<tel:+15105550100>" ,
411+ },
412+ {
413+ name : "invalid URI - http" ,
414+ req : & TransferSIPParticipantRequest {
415+ RoomName : "room1" ,
416+ ParticipantIdentity : "participant1" ,
417+ TransferTo : "http://example.com" ,
418+ },
419+ expectError : true ,
420+ },
421+ {
422+ name : "invalid URI - mailto" ,
423+ req : & TransferSIPParticipantRequest {
424+ RoomName : "room1" ,
425+ ParticipantIdentity : "participant1" ,
426+ TransferTo :
"mailto:[email protected] " ,
427+ },
428+ expectError : true ,
429+ },
430+ {
431+ name : "invalid URI - plain text" ,
432+ req : & TransferSIPParticipantRequest {
433+ RoomName : "room1" ,
434+ ParticipantIdentity : "participant1" ,
435+ TransferTo : "just-a-phone-number" ,
436+ },
437+ expectError : true ,
438+ },
439+ {
440+ name : "invalid URI - empty" ,
441+ req : & TransferSIPParticipantRequest {
442+ RoomName : "room1" ,
443+ ParticipantIdentity : "participant1" ,
444+ TransferTo : "" ,
445+ },
446+ expectError : true ,
447+ },
448+ {
449+ name : "missing room name" ,
450+ req : & TransferSIPParticipantRequest {
451+ RoomName : "" ,
452+ ParticipantIdentity : "participant1" ,
453+ TransferTo :
"sip:[email protected] " ,
454+ },
455+ expectError : true ,
456+ },
457+ {
458+ name : "missing participant identity" ,
459+ req : & TransferSIPParticipantRequest {
460+ RoomName : "room1" ,
461+ ParticipantIdentity : "" ,
462+ TransferTo :
"sip:[email protected] " ,
463+ },
464+ expectError : true ,
465+ },
466+ {
467+ name : "invalid URI with brackets - http" ,
468+ req : & TransferSIPParticipantRequest {
469+ RoomName : "room1" ,
470+ ParticipantIdentity : "participant1" ,
471+ TransferTo : "<http://example.com>" ,
472+ },
473+ expectError : true ,
474+ },
475+ {
476+ name : "complex sip URI with transport" ,
477+ req : & TransferSIPParticipantRequest {
478+ RoomName : "room1" ,
479+ ParticipantIdentity : "participant1" ,
480+ TransferTo :
"sip:[email protected] ;transport=tcp" ,
481+ },
482+ expectError : false ,
483+ expectedURI :
"<sip:[email protected] ;transport=tcp>" ,
484+ },
485+ {
486+ name : "sip URI with user and parameters" ,
487+ req : & TransferSIPParticipantRequest {
488+ RoomName : "room1" ,
489+ ParticipantIdentity : "participant1" ,
490+ TransferTo :
"sip:[email protected] ,123" ,
491+ },
492+ expectError : false ,
493+ expectedURI :
"<sip:[email protected] ,123>" ,
494+ },
495+ {
496+ name : "sip URI with multiple parameters" ,
497+ req : & TransferSIPParticipantRequest {
498+ RoomName : "room1" ,
499+ ParticipantIdentity : "participant1" ,
500+ TransferTo :
"sip:[email protected] ;transport=tcp;lr;ttl=60" ,
501+ },
502+ expectError : false ,
503+ expectedURI :
"<sip:[email protected] ;transport=tcp;lr;ttl=60>" ,
504+ },
505+ {
506+ name : "sip URI with port" ,
507+ req : & TransferSIPParticipantRequest {
508+ RoomName : "room1" ,
509+ ParticipantIdentity : "participant1" ,
510+ TransferTo :
"sip:[email protected] :5060" ,
511+ },
512+ expectError : false ,
513+ expectedURI :
"<sip:[email protected] :5060>" ,
514+ },
515+ {
516+ name : "tel URI with extension" ,
517+ req : & TransferSIPParticipantRequest {
518+ RoomName : "room1" ,
519+ ParticipantIdentity : "participant1" ,
520+ TransferTo : "tel:+1234567890;ext=123" ,
521+ },
522+ expectError : false ,
523+ expectedURI : "<tel:+1234567890;ext=123>" ,
524+ },
525+ {
526+ name : "tel URI with parameters" ,
527+ req : & TransferSIPParticipantRequest {
528+ RoomName : "room1" ,
529+ ParticipantIdentity : "participant1" ,
530+ TransferTo : "tel:+1234567890;phone-context=example.com" ,
531+ },
532+ expectError : false ,
533+ expectedURI : "<tel:+1234567890;phone-context=example.com>" ,
534+ },
535+ {
536+ name : "sip URI with headers" ,
537+ req : & TransferSIPParticipantRequest {
538+ RoomName : "room1" ,
539+ ParticipantIdentity : "participant1" ,
540+ TransferTo :
"sip:[email protected] ?subject=test&priority=urgent" ,
541+ },
542+ expectError : false ,
543+ expectedURI :
"<sip:[email protected] ?subject=test&priority=urgent>" ,
544+ },
545+ }
546+
547+ for _ , c := range cases {
548+ t .Run (c .name , func (t * testing.T ) {
549+ err := c .req .Validate ()
550+ if c .expectError {
551+ require .Error (t , err , "Expected validation to fail" )
552+ } else {
553+ require .NoError (t , err , "Expected validation to pass" )
554+ require .Equal (t , c .expectedURI , c .req .TransferTo , "TransferTo should be RFC-compliant after validation" )
555+ }
556+ })
557+ }
558+ }
559+
365560func TestGRPCStatus (t * testing.T ) {
366561 e := & SIPStatus {Code : SIPStatusCode_SIP_STATUS_BUSY_HERE }
367562 st , ok := status .FromError (e )
0 commit comments