package inferencesidecar import ( "encoding/binary" "encoding/json" "math" "net/http" "net/http/httptest" "testing" "gitea.nik4nao.com/nik/home-services/tts-gateway/internal/core/domain" ) func TestClientSynthesize(t *testing.T) { t.Run("happy path decodes little-endian float32 PCM and sample rate header", func(t *testing.T) { wantPCM := []float32{0.1, -0.2, 0.3} srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/synthesize" { t.Fatalf("request path = %q, want /synthesize", r.URL.Path) } var body synthesizeRequest if err := json.NewDecoder(r.Body).Decode(&body); err != nil { t.Fatalf("decode request body: %v", err) } if body.SpeakerID != 29 || len(body.SymbolIDs) != 2 { t.Fatalf("request body = %+v, unexpected", body) } payload := make([]byte, len(wantPCM)*4) for i, f := range wantPCM { binary.LittleEndian.PutUint32(payload[i*4:], math.Float32bits(f)) } w.Header().Set("X-Sample-Rate", "22050") w.WriteHeader(http.StatusOK) _, _ = w.Write(payload) })) defer srv.Close() c := NewClient(srv.Listener.Addr().String()) gotPCM, gotSampleRate, err := c.Synthesize(t.Context(), 29, []int64{1, 2}, domain.SynthesisParams{NoiseScale: 0.37}) if err != nil { t.Fatalf("Synthesize() error = %v", err) } if gotSampleRate != 22050 { t.Fatalf("Synthesize() sampleRate = %d, want 22050", gotSampleRate) } if len(gotPCM) != len(wantPCM) { t.Fatalf("Synthesize() pcm = %v, want %v", gotPCM, wantPCM) } for i, want := range wantPCM { if gotPCM[i] != want { t.Errorf("pcm[%d] = %v, want %v", i, gotPCM[i], want) } } }) t.Run("non-200 response is surfaced as an error with the body", func(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte("bad speaker id")) })) defer srv.Close() c := NewClient(srv.Listener.Addr().String()) _, _, err := c.Synthesize(t.Context(), 999, []int64{1}, domain.SynthesisParams{}) if err == nil { t.Fatal("Synthesize() error = nil, want non-nil") } }) }