package api import ( "fmt" "net/http/httptest" "net/url" "os" "path/filepath" "strings" "testing" "hamlab/internal/config" "hamlab/internal/files" ) // The file a machine transcodes from another is read through the hub by a token naming that // one file: ranges pass through, the query can't point it anywhere else, and an unknown token // is nothing. func TestPlaySrc(t *testing.T) { dir := t.TempDir() p := filepath.Join(dir, "film.mp4") if err := os.WriteFile(p, []byte("0123456789"), 0o644); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, "other.mp4"), []byte("secret"), 0o644); err != nil { t.Fatal(err) } s := &Server{fsLocal: files.Local{}, cfg: &config.Config{Listen: "10.0.0.234:8100"}} u, err := s.srcURL("", "", p, false) if err != nil || !strings.HasPrefix(u, "http://10.0.0.234:8100/api/play-src/") { t.Fatalf("url %q %v", u, err) } tok := strings.TrimPrefix(u, "http://10.0.0.234:8100/api/play-src/") get := func(tok, query, rng string) *httptest.ResponseRecorder { r := httptest.NewRequest("GET", "/api/play-src/"+tok+query, nil) r.SetPathValue("token", tok) if rng != "" { r.Header.Set("Range", rng) } w := httptest.NewRecorder() s.playSrc(w, r) return w } if w := get(tok, "", "bytes=2-4"); w.Code != 206 || w.Body.String() != "234" { t.Fatalf("range: %d %q", w.Code, w.Body) } if w := get(tok, "?path="+filepath.Join(dir, "other.mp4"), ""); w.Body.String() != "0123456789" { t.Fatalf("the query moved it: %q", w.Body) } if w := get("nope", "", ""); w.Code != 404 { t.Fatalf("unknown token: %d", w.Code) } } // A preview made on another machine is kept by the file's own: only while the file is still // the one it was made of, and a failure is kept as a failure. func TestThumbPut(t *testing.T) { dir := t.TempDir() p := filepath.Join(dir, "film.mp4") if err := os.WriteFile(p, []byte("0123456789"), 0o644); err != nil { t.Fatal(err) } fi, _ := os.Stat(p) s := &Server{fsLocal: files.Local{}, thumbs: newThumbSvc(dir, "")} v := fmt.Sprintf("%d-%d", fi.ModTime().UnixMilli(), fi.Size()) put := func(v string, body string, hdr map[string]string) int { r := httptest.NewRequest("PUT", "/api/files/thumb?path="+url.QueryEscape(p)+"&v="+v, strings.NewReader(body)) for k, x := range hdr { r.Header.Set(k, x) } w := httptest.NewRecorder() s.thumbPut(w, r) return w.Code } get := func() *httptest.ResponseRecorder { r := httptest.NewRequest("GET", "/api/files/thumb?cached=1&path="+url.QueryEscape(p)+"&v="+v, nil) w := httptest.NewRecorder() s.filesThumb(w, r) return w } if w := get(); w.Code != 404 { t.Fatalf("cached=1 before anything: %d", w.Code) } if c := put("1-10", "jpeg", nil); c != 409 { t.Fatalf("a changed file: %d", c) } if c := put(v, "jpeg-bytes", map[string]string{"X-Hamlab-Thumb": "grid vaapi:/dev/dri/renderD129"}); c != 204 { t.Fatalf("put: %d", c) } if w := get(); w.Code != 200 || w.Body.String() != "jpeg-bytes" || !strings.Contains(w.Header().Get("X-Hamlab-Thumb"), "grid") { t.Fatalf("kept: %d %q %q", w.Code, w.Body, w.Header().Get("X-Hamlab-Thumb")) } }