package apidoc_test import ( "encoding/json" "os" "path/filepath" "strings" "testing" ) func swaggerPath(t *testing.T) string { t.Helper() path := filepath.Join("..", "..", "api", "swagger.json") abs, err := filepath.Abs(path) if err != nil { t.Fatal(err) } if _, err := os.Stat(abs); err != nil { t.Fatal(err) } return abs } var documentedPaths = []struct { path string method string }{ {"/swagger.json", "get"}, {"/spr/models", "get"}, {"/spr/hostname", "get"}, {"/spr/queue", "get"}, {"/spr/queue/{taskID}", "get"}, {"/spr/queue/{taskID}", "delete"}, {"/spr/stt/{id}", "post"}, {"/spr/result/{taskID}", "get"}, {"/spr/audio/{taskID}", "get"}, {"/spr/waveform/{taskID}", "get"}, {"/spr/import/{id}", "post"}, {"/spr/export/{id}", "get"}, {"/spr/delete/{id}", "delete"}, {"/v1/models", "get"}, {"/v1/audio/transcriptions", "post"}, {"/v1/audio/transcriptions/", "post"}, } func TestSwaggerJSON_validAndComplete(t *testing.T) { data, err := os.ReadFile(swaggerPath(t)) if err != nil { t.Fatal(err) } var spec struct { Swagger string `json:"swagger"` Paths map[string]map[string]json.RawMessage `json:"paths"` Info struct { Title string `json:"title"` } `json:"info"` } if err := json.Unmarshal(data, &spec); err != nil { t.Fatalf("invalid JSON: %v", err) } if spec.Swagger != "2.0" { t.Fatalf("swagger version: got %q", spec.Swagger) } for _, want := range documentedPaths { methods, ok := spec.Paths[want.path] if !ok { t.Errorf("missing path %s", want.path) continue } if _, ok := methods[want.method]; !ok { t.Errorf("path %s missing method %s", want.path, want.method) } } } func TestSwaggerJSON_sttQueryParamsMatchImplementation(t *testing.T) { data, err := os.ReadFile(swaggerPath(t)) if err != nil { t.Fatal(err) } var spec struct { Paths map[string]struct { Post struct { Parameters []struct { Name string `json:"name"` In string `json:"in"` } `json:"parameters"` } `json:"post"` } `json:"paths"` } if err := json.Unmarshal(data, &spec); err != nil { t.Fatal(err) } stt := spec.Paths["/spr/stt/{id}"] var queryNames []string for _, p := range stt.Post.Parameters { if p.In == "query" { queryNames = append(queryNames, p.Name) } } for _, required := range []string{"async", "language", "punctuation", "speakers", "speaker_counter"} { if !contains(queryNames, required) { t.Errorf("STT missing query param %q", required) } } for _, removed := range []string{"webhook", "toxicity", "normalization", "vad", "classifiers"} { if contains(queryNames, removed) { t.Errorf("STT documents unused param %q", removed) } } } func TestSwaggerJSON_hasOpenAIPaths(t *testing.T) { data, err := os.ReadFile(swaggerPath(t)) if err != nil { t.Fatal(err) } s := string(data) if !strings.Contains(s, "/v1/audio/transcriptions") { t.Fatal("missing OpenAI transcription path") } } func contains(ss []string, s string) bool { for _, x := range ss { if x == s { return true } } return false }