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 }