package web
import (
"context"
"net/http/httptest"
"strings"
"testing"
"craftdesign.group/quarry/internal/ops"
)
func TestTreeLinksPinTheResolvedVersionNotItsLabel(t *testing.T) {
r := viewRegistry(t, nil)
hash := strings.Repeat("ab", 32)
type treeRequest struct {
Repo string `json:"repo"`
Version string `json:"version"`
Path string `json:"path"`
}
type treeAnswer struct {
Version string `json:"version"`
Ref string `json:"ref"`
Entries []treeRow `json:"entries"`
}
if err := ops.Register(r, ops.Op[treeRequest, treeAnswer]{
Name: "tree.list", Kind: ops.Query, Auth: ops.Anonymous, Caps: "o",
Doc: "test tree", Route: "GET /api/v1/r/{repo}/tree/{version}/{path...}",
Run: func(context.Context, treeRequest) (treeAnswer, error) {
return treeAnswer{Version: hash, Ref: "heads/main", Entries: []treeRow{
{Name: "value.txt", Path: "value.txt"},
{Name: "src", Path: "src", Dir: true},
}}, nil
},
}); err != nil {
t.Fatal(err)
}
w := httptest.NewRecorder()
HandlerWith(r, nil, nil, nil).ServeHTTP(w, httptest.NewRequest("GET", "/r/test", nil))
if w.Code != 200 {
t.Fatalf("FAIL: tree returned %d: %s", w.Code, w.Body.String())
}
body := w.Body.String()
for _, path := range []string{"/file/" + hash + "/value.txt", "/tree/" + hash + "/src"} {
if !strings.Contains(body, `href="/r/test`+path+`"`) {
t.Errorf("FAIL: tree did not pin link %s", path)
}
}
if strings.Contains(body, "/file/heads/main/") || strings.Contains(body, "/tree/heads/main/") {
t.Fatal("FAIL: source-head label escaped into a path")
}
t.Log("ok: file and directory links carry the resolved hash")
}