Files
story/internal/callmemory/volume_test.go
T

98 lines
4.0 KiB
Go
Raw Normal View History

package callmemory
import (
"context"
"data-terminal-cloud/internal/volcsubtitle"
"github.com/google/uuid"
"sync"
"testing"
)
func TestSpokenVolumePhrases(t *testing.T) {
for _, text := range []string{"调大音量", "把音量调大", "声音放大一点"} {
if spokenVolumeAction(text) != "up" {
t.Errorf("not recognized: %s", text)
}
}
for text, want := range map[string]string{
"大点儿声": "up", "大点声": "up", "请你声音大一点": "up", "能不能大点儿声?": "up", "帮我把音量调高一点": "up", "声音太小了": "up", "声音有点低": "up",
"小点儿声": "down", "把声音调小一点好吗": "down", "声音太大了": "down", "音量低一点": "down",
"不要大点儿声": "", "不用调大音量": "", "他说大点儿声": "", "如果我说大点声会怎样": "", "大点声,小点声": "", "大一点": "", "我年轻时声音太大了": "", "“大点儿声”": "", "声音大一点也没用": "",
} {
if got := spokenVolumeAction(text); got != want {
t.Errorf("%q: got %q want %q", text, got, want)
}
}
}
func TestSpokenVolumeCallbackSafety(t *testing.T) {
f, d := directFixture(t)
ctx := context.Background()
sid := uuid.NewString()
if _, err := f.s.DirectRequest(ctx, d, "start", DirectInput{SessionID: sid, BootID: f.boot}); err != nil {
t.Fatal(err)
}
f.exec(t, `INSERT INTO device_twin(device_id,tenant_id,desired_revision,desired_config) VALUES($1,$2,1,'{"volume":{"speaker":22},"identity":{"display_name":"保留名称"}}') ON CONFLICT(device_id) DO UPDATE SET desired_config=EXCLUDED.desired_config,desired_revision=1`, f.device, f.tenant)
packet := func(round, seq int64, who, text string, final bool) volcsubtitle.Packet {
return volcsubtitle.Packet{Type: "subtitle", Data: []volcsubtitle.Segment{{UserID: who, RoundID: &round, Sequence: &seq, Text: text, Definite: final}}}
}
send := func(p volcsubtitle.Packet) {
t.Helper()
if err := f.s.DirectSubtitle(ctx, sid, p); err != nil {
t.Fatal(err)
}
}
check := func(want, rev int) {
t.Helper()
var got, r int
var name string
if err := f.p.QueryRow(ctx, `SELECT (desired_config->'volume'->>'speaker')::int,desired_revision,desired_config->'identity'->>'display_name' FROM device_twin WHERE device_id=$1`, f.device).Scan(&got, &r, &name); err != nil {
t.Fatal(err)
}
if got != want || r != rev || name != "保留名称" {
t.Fatalf("got volume=%d revision=%d name=%s", got, r, name)
}
}
send(packet(1, 1, "input", "大点声", false))
send(packet(2, 1, "output", "大点声", true))
send(packet(3, 1, "input", "不要大点声", true))
check(22, 1)
// Concurrent delivery retries and final fragments in the same round must not
// increment twice; the subtitle and action are in the same transaction.
p := packet(4, 1, "input", "大点儿声", true)
errs := make(chan error, 4)
var wg sync.WaitGroup
for i := 0; i < 4; i++ {
wg.Add(1)
go func() { defer wg.Done(); errs <- f.s.DirectSubtitle(ctx, sid, p) }()
}
wg.Wait()
close(errs)
for err := range errs {
if err != nil {
t.Fatal(err)
}
}
send(packet(4, 2, "input", "声音大一点", true))
check(32, 2)
send(packet(5, 1, "input", "小点儿声", true))
check(22, 3)
f.exec(t, `UPDATE device_twin SET desired_config=jsonb_set(desired_config,'{volume,speaker}','95') WHERE device_id=$1`, f.device)
send(packet(6, 1, "input", "大点声", true))
check(100, 4)
send(packet(7, 1, "input", "大点声", true))
check(100, 4)
f.exec(t, `UPDATE device_twin SET desired_config=jsonb_set(desired_config,'{volume,speaker}','5') WHERE device_id=$1`, f.device)
send(packet(8, 1, "input", "小点声", true))
check(0, 5)
f.exec(t, `UPDATE call_session SET lease_expires_at=now()-interval '1 second' WHERE id=$1`, sid)
send(packet(9, 1, "input", "大点声", true))
check(0, 5)
f.exec(t, `UPDATE call_session SET lease_expires_at=now()+interval '45 seconds' WHERE id=$1`, sid)
if _, err := f.s.DirectRequest(ctx, d, "end", DirectInput{SessionID: sid, Reason: "hangup", SDKStopped: true}); err != nil {
t.Fatal(err)
}
send(packet(10, 1, "input", "大点声", true))
check(0, 5)
}