Files
VoCat/internal/vowifi/ims/call_runtime_test.go
T

88 lines
3.1 KiB
Go

package ims
import (
"context"
"strings"
"testing"
"vocat/internal/vowifi"
)
func TestIncomingCallCanRingAndAnswerWithMediaOffer(t *testing.T) {
session := &Session{fromTag: "local-tag", calls: make(map[string]*imsCall)}
packet, err := parseSIPPacket([]byte(strings.Join([]string{
"INVITE sip:[email protected] SIP/2.0",
"Via: SIP/2.0/UDP 192.0.2.10:5060;branch=z9hG4bK-incoming",
"From: <tel:+447700900001>;tag=remote",
"To: <sip:[email protected]>",
"Call-ID: [email protected]",
"CSeq: 1 INVITE",
"Content-Length: 0", "", "",
}, "\r\n")))
if err != nil || packet.Request == nil {
t.Fatalf("parse INVITE: %v", err)
}
var responses [][]byte
session.handleSIPRequest(packet.Request, func(response []byte) error {
responses = append(responses, append([]byte(nil), response...))
return nil
})
calls := session.Calls()
if len(calls) != 1 || calls[0].Direction != "incoming" || calls[0].State != "ringing" || calls[0].Number != "+447700900001" {
t.Fatalf("incoming Calls = %#v", calls)
}
if len(responses) != 1 || !strings.HasPrefix(string(responses[0]), "SIP/2.0 180 Ringing") {
t.Fatalf("ringing response = %q", responses)
}
answered, err := session.AnswerCall(context.Background(), calls[0].ID)
if err != nil {
t.Fatal(err)
}
if answered.State != "active" || len(responses) != 2 || !strings.Contains(string(responses[1]), "a=sendrecv") {
t.Fatalf("answered = %#v, response = %q", answered, responses[1])
}
}
func TestIncomingCallCanBeRejected(t *testing.T) {
session := &Session{fromTag: "local-tag", calls: make(map[string]*imsCall)}
packet, err := parseSIPPacket([]byte(strings.Join([]string{
"INVITE sip:[email protected] SIP/2.0",
"Via: SIP/2.0/UDP 192.0.2.10:5060;branch=z9hG4bK-a",
"From: <tel:+1>;tag=a", "To: <sip:[email protected]>",
"Call-ID: reject-call", "CSeq: 1 INVITE", "Content-Length: 0", "", "",
}, "\r\n")))
if err != nil || packet.Request == nil {
t.Fatalf("parse INVITE: %v", err)
}
var response []byte
session.handleCallRequest(packet.Request, func(value []byte) error { response = append([]byte(nil), value...); return nil })
if err := session.HangupCall(context.Background(), "reject-call"); err != nil {
t.Fatal(err)
}
if !strings.HasPrefix(string(response), "SIP/2.0 486 Busy Here") {
t.Fatalf("reject response = %q", response)
}
calls := session.Calls()
if len(calls) != 1 || calls[0].State != "ended" || calls[0].EndedAt == nil {
t.Fatalf("terminal call status = %#v", calls)
}
}
func TestRejectedOutgoingCallRetainsSIPReason(t *testing.T) {
session := &Session{calls: make(map[string]*imsCall)}
call := &imsCall{public: vowifi.Call{ID: "rejected", State: "dialing"}}
session.calls[call.public.ID] = call
session.finishCall(call.public.ID, "failed", 484, "Address Incomplete\r\nignored")
calls := session.Calls()
if len(calls) != 1 || calls[0].State != "failed" || calls[0].SIPCode != 484 ||
calls[0].Reason != "Address Incomplete ignored" || calls[0].EndedAt == nil {
t.Fatalf("rejected call = %#v", calls)
}
}
func TestValidCallNumber(t *testing.T) {
if !validCallNumber("+447700900000") || validCallNumber("12\r\nBYE") {
t.Fatal("call number validation mismatch")
}
}