75 lines
3.0 KiB
Go
75 lines
3.0 KiB
Go
package asterisk
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/CyCoreSystems/ari/v5"
|
|
)
|
|
|
|
type answerEvents struct {
|
|
ari.Subscription
|
|
events chan ari.Event
|
|
}
|
|
|
|
func (f answerEvents) Events() <-chan ari.Event { return f.events }
|
|
func (f answerEvents) Cancel() {}
|
|
|
|
func TestAwaitDialUpRequiresStasisAndPostDialUp(t *testing.T) {
|
|
const id = "execution-1"
|
|
for _, tc := range []struct {
|
|
name string
|
|
events []ari.Event
|
|
answer bool
|
|
}{
|
|
{"created_not_answered", []ari.Event{&ari.StasisStart{Channel: ari.ChannelData{ID: id}}}, false},
|
|
{"up_without_stasis", []ari.Event{&ari.ChannelStateChange{Channel: ari.ChannelData{ID: id, State: "Up"}}}, false},
|
|
{"wrong_channel", []ari.Event{&ari.StasisStart{Channel: ari.ChannelData{ID: "other"}}, &ari.ChannelStateChange{Channel: ari.ChannelData{ID: "other", State: "Up"}}}, false},
|
|
{"answer", []ari.Event{&ari.StasisStart{Channel: ari.ChannelData{ID: id}}, &ari.ChannelStateChange{Channel: ari.ChannelData{ID: id, State: "Up"}}}, true},
|
|
{"answer_reordered", []ari.Event{&ari.ChannelStateChange{Channel: ari.ChannelData{ID: id, State: "Up"}}, &ari.StasisStart{Channel: ari.ChannelData{ID: id}}}, true},
|
|
{"destroyed_before_answer", []ari.Event{&ari.StasisStart{Channel: ari.ChannelData{ID: id}}, &ari.ChannelDestroyed{Channel: ari.ChannelData{ID: id}}}, false},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
ch := make(chan ari.Event, len(tc.events))
|
|
for _, event := range tc.events {
|
|
ch <- event
|
|
}
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
|
|
defer cancel()
|
|
answeredAt, err := awaitDialUp(ctx, answerEvents{events: ch}, id)
|
|
if (err == nil) != tc.answer || (!tc.answer && !answeredAt.IsZero()) {
|
|
t.Fatalf("answer proof mismatch: %v", err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAwaitDialUpPreservesOriginalUpTimestamp(t *testing.T) {
|
|
id := "owned-call"
|
|
answer := time.Date(2026, 10, 10, 12, 0, 0, 123000000, time.UTC)
|
|
ch := make(chan ari.Event, 3)
|
|
ch <- &ari.ChannelStateChange{EventData: ari.EventData{Timestamp: ari.DateTime(answer)}, Channel: ari.ChannelData{ID: id, State: "Up"}}
|
|
ch <- &ari.ChannelStateChange{EventData: ari.EventData{Timestamp: ari.DateTime(answer.Add(time.Second))}, Channel: ari.ChannelData{ID: id, State: "Up"}}
|
|
ch <- &ari.StasisStart{Channel: ari.ChannelData{ID: id}}
|
|
got, err := awaitDialUp(context.Background(), answerEvents{events: ch}, id)
|
|
if err != nil || !got.Equal(answer) {
|
|
t.Fatalf("native answer timestamp lost: %v %v", got, err)
|
|
}
|
|
}
|
|
|
|
func TestAwaitDialUpFailsClosedOnLostEventsOrCancellation(t *testing.T) {
|
|
ch := make(chan ari.Event)
|
|
close(ch)
|
|
if _, err := awaitDialUp(context.Background(), answerEvents{events: ch}, "execution-1"); err == nil || !strings.Contains(err.Error(), "closed") {
|
|
t.Fatalf("subscription loss was hidden: %v", err)
|
|
}
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel()
|
|
if _, err := awaitDialUp(ctx, answerEvents{events: make(chan ari.Event)}, "execution-1"); !errors.Is(err, context.Canceled) {
|
|
t.Fatalf("cancellation was hidden: %v", err)
|
|
}
|
|
}
|