Files
Assistant/cmd/cognitive-worker/multimodal_test.go
m 75d707e960
CI / test (push) Successful in 1m22s
CI / test (pull_request) Successful in 1m25s
Honor requested image quality
2026-08-25 22:12:44 +03:00

97 lines
3.8 KiB
Go

package main
import (
"bytes"
"context"
"encoding/json"
"mime/multipart"
"net/http"
"net/http/httptest"
"testing"
"time"
"git.cin.su/m/Assistant/adapters/multimodal"
"git.cin.su/m/Assistant/contracts/capability"
)
func TestMultimodalTranscriptionHandlerReturnsLocalResult(t *testing.T) {
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/inference" || r.Method != http.MethodPost {
t.Fatalf("unexpected upstream request: %s %s", r.Method, r.URL.Path)
}
_ = json.NewEncoder(w).Encode(map[string]string{"text": "добрый день"})
}))
defer upstream.Close()
server := multimodalGateway{speech: multimodal.SpeechClient{BaseURL: upstream.URL, Client: upstream.Client()}, now: time.Now}
request := multipartRequest(t, "/v1/multimodal/transcribe", "voice.wav", []byte("audio"))
response := httptest.NewRecorder()
server.handler(capability.MultimodalTranscribe)(response, request)
if response.Code != http.StatusOK || !bytes.Contains(response.Body.Bytes(), []byte("добрый день")) {
t.Fatalf("status=%d body=%s", response.Code, response.Body.String())
}
}
func TestMultimodalImageGenerationFailsClosedWhenSkillIsUnbound(t *testing.T) {
server := multimodalGateway{now: time.Now}
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
if err := writer.WriteField("prompt", "green bird"); err != nil || writer.Close() != nil {
t.Fatal("failed to build generation request")
}
request := httptest.NewRequest(http.MethodPost, "/v1/multimodal/generate-image", body)
request.Header.Set("Content-Type", writer.FormDataContentType())
response := httptest.NewRecorder()
server.handler(capability.MultimodalGenerateImage)(response, request)
if response.Code != http.StatusBadGateway || !bytes.Contains(response.Body.Bytes(), []byte("unavailable")) {
t.Fatalf("status=%d body=%s", response.Code, response.Body.String())
}
}
func TestImageRequestSizeUsesExplicitSizeOrQualityTarget(t *testing.T) {
for _, test := range []struct {
name string
prompt string
requested string
want string
}{
{name: "explicit", prompt: "нарисуй птицу", requested: "768x512", want: "768x512"},
{name: "hd", prompt: "нарисуй птицу в HD", want: "1024x1024"},
{name: "uhd", prompt: "draw a bird in UHD", want: "2048x2048"},
{name: "ordinary", prompt: "нарисуй птицу", want: ""},
{name: "invalid explicit", prompt: "нарисуй птицу", requested: "100x100", want: ""},
} {
t.Run(test.name, func(t *testing.T) {
if got := imageRequestSize(test.prompt, test.requested); got != test.want {
t.Fatalf("imageRequestSize(%q, %q) = %q, want %q", test.prompt, test.requested, got, test.want)
}
})
}
}
func TestMultimodalVideoUnderstandingFailsClosedWhenSkillIsUnbound(t *testing.T) {
server := multimodalGateway{now: time.Now}
request := multipartRequest(t, "/v1/multimodal/video-understand", "clip.mp4", []byte("video"))
response := httptest.NewRecorder()
server.handler(capability.MultimodalUnderstandVideo)(response, request)
if response.Code != http.StatusBadGateway || !bytes.Contains(response.Body.Bytes(), []byte("unavailable")) {
t.Fatalf("status=%d body=%s", response.Code, response.Body.String())
}
}
func multipartRequest(t *testing.T, path, filename string, data []byte) *http.Request {
t.Helper()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("file", filename)
if err != nil {
t.Fatal(err)
}
if _, err := part.Write(data); err != nil || writer.Close() != nil {
t.Fatal("failed to build multipart request")
}
request := httptest.NewRequest(http.MethodPost, path, body)
request = request.WithContext(context.Background())
request.Header.Set("Content-Type", writer.FormDataContentType())
return request
}