package nexara import ( "context" "encoding/json" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" "time" ) func TestTranscribeFileSuccess(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { t.Fatalf("method: got %s", r.Method) } if !strings.HasPrefix(r.Header.Get("Content-Type"), "multipart/form-data") { t.Fatalf("content-type: got %s", r.Header.Get("Content-Type")) } if auth := r.Header.Get("Authorization"); auth != "Bearer nexara-key" { t.Fatalf("auth: got %q", auth) } if err := r.ParseMultipartForm(1 << 20); err != nil { t.Fatal(err) } if r.FormValue("model") != "whisper-1" { t.Fatalf("model: got %q", r.FormValue("model")) } if r.FormValue("response_format") != "json" { t.Fatalf("response_format: got %q", r.FormValue("response_format")) } file, _, err := r.FormFile("file") if err != nil { t.Fatal(err) } defer file.Close() buf := make([]byte, 64) n, _ := file.Read(buf) if string(buf[:n]) != "audio-bytes" { t.Fatalf("file content: got %q", string(buf[:n])) } _ = json.NewEncoder(w).Encode(map[string]any{ "text": "привет мир", "language": "ru", "segments": []map[string]any{ {"start": 0.0, "end": 1.5, "text": "привет"}, {"start": 1.5, "end": 3.0, "text": "мир"}, }, }) })) defer srv.Close() dir := t.TempDir() audioPath := filepath.Join(dir, "test.wav") if err := os.WriteFile(audioPath, []byte("audio-bytes"), 0o644); err != nil { t.Fatal(err) } client := New(srv.URL, "nexara-key", "whisper-1", 5*time.Second) text, lang, segments, err := client.TranscribeFile(context.Background(), audioPath) if err != nil { t.Fatal(err) } if text != "привет мир" { t.Fatalf("text: got %q", text) } if lang != "ru" { t.Fatalf("language: got %q", lang) } if len(segments) != 2 { t.Fatalf("segments: got %d", len(segments)) } if segments[0].Text != "привет" || segments[1].End != 3.0 { t.Fatalf("unexpected segments: %+v", segments) } } func TestTranscribeFileAPIError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnauthorized) _, _ = w.Write([]byte("invalid key")) })) defer srv.Close() dir := t.TempDir() audioPath := filepath.Join(dir, "test.wav") if err := os.WriteFile(audioPath, []byte("x"), 0o644); err != nil { t.Fatal(err) } client := New(srv.URL, "bad", "", 5*time.Second) _, _, _, err := client.TranscribeFile(context.Background(), audioPath) if err == nil { t.Fatal("expected error on 401") } if !strings.Contains(err.Error(), "401") { t.Fatalf("error should mention status: %v", err) } } func TestTranscribeFileMissingFile(t *testing.T) { client := New("http://localhost", "key", "", time.Second) _, _, _, err := client.TranscribeFile(context.Background(), filepath.Join(t.TempDir(), "missing.wav")) if err == nil { t.Fatal("expected error for missing file") } } func TestNewTrimsBaseURL(t *testing.T) { c := New("https://api.example.com/", "k", "m", time.Second) if !strings.HasSuffix(c.apiURL, "/api/v1/audio/transcriptions") { t.Fatalf("apiURL: got %s", c.apiURL) } }