Opening a repository shows its model card, rendered from markdown, with its base model, license and languages above it; the listing names each repository's base model and license under its name. The card is a stranger's text: raw HTML and dangerous links are dropped, images are shown as links rather than loaded, and relative links point into the repository. Adds github.com/yuin/goldmark for the markdown. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
117 lines
4.7 KiB
Go
117 lines
4.7 KiB
Go
package web
|
|
|
|
import (
|
|
"html"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.mynodes.xyz/ilker/llmgw/internal/hf"
|
|
)
|
|
|
|
func ggufModel(id, arch string, params int64, created time.Time) hf.Model {
|
|
return hf.Model{ID: id, CreatedAt: created, LastModified: created,
|
|
GGUF: &hf.GGUFInfo{Total: params, Architecture: arch, ContextLength: 32768}}
|
|
}
|
|
|
|
func TestTheExplorerOpensOnTrendingModelsTheNodesCanRun(t *testing.T) {
|
|
// Opened from the menu, with nothing typed: what is current, in the
|
|
// shape this cluster runs, without a search to start it.
|
|
now := time.Now()
|
|
reg := &fakeRegistry{results: []hf.Model{
|
|
ggufModel("Qwen/Qwen3-8B-GGUF", "qwen3", 8.2e9, now.Add(-90*24*time.Hour)),
|
|
ggufModel("odd/Kev-GGUF", "ggmlc", 5e8, now.Add(-2*24*time.Hour)),
|
|
}}
|
|
body := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror").Body.String()
|
|
|
|
q := reg.query
|
|
if q.Sort != hf.SortTrending || q.Task != "text-generation" || !q.GGUF || q.Search != "" {
|
|
t.Errorf("asked the registry for %+v", q)
|
|
}
|
|
if !strings.Contains(body, "Qwen/Qwen3-8B-GGUF") || !strings.Contains(body, "8.2B") {
|
|
t.Errorf("the trending model is missing or unsized: %s", body)
|
|
}
|
|
// The kev case: listed, it invites a fetch the nodes cannot use.
|
|
if strings.Contains(body, "odd/Kev-GGUF") {
|
|
t.Error("a model llama.cpp cannot load is offered")
|
|
}
|
|
if !strings.Contains(body, "1 more is hidden") {
|
|
t.Error("the page should say something was hidden, and why")
|
|
}
|
|
}
|
|
|
|
func TestUntickingRunsHereShowsEverythingWithAVerdict(t *testing.T) {
|
|
reg := &fakeRegistry{results: []hf.Model{
|
|
ggufModel("odd/Kev-GGUF", "ggmlc", 5e8, time.Now()),
|
|
}}
|
|
// x=1 is the submitted form; "here" absent is the box unticked.
|
|
body := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror?x=1&view=downloads&task=any&size=9").Body.String()
|
|
|
|
q := reg.query
|
|
if q.GGUF || q.Sort != hf.SortDownloads || q.Task != "" || q.MaxParams != 9e9 {
|
|
t.Errorf("asked the registry for %+v", q)
|
|
}
|
|
if !strings.Contains(body, "odd/Kev-GGUF") || !strings.Contains(body, "ggmlc ✗") {
|
|
t.Errorf("the unrunnable model should be listed and marked: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestNewThisMonthLeavesOutOlderRepositories(t *testing.T) {
|
|
now := time.Now()
|
|
reg := &fakeRegistry{results: []hf.Model{
|
|
ggufModel("a/Old-GGUF", "llama", 1e9, now.Add(-200*24*time.Hour)),
|
|
ggufModel("a/Fresh-GGUF", "llama", 1e9, now.Add(-3*24*time.Hour)),
|
|
}}
|
|
body := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror?view=new").Body.String()
|
|
if strings.Contains(body, "a/Old-GGUF") || !strings.Contains(body, "a/Fresh-GGUF") {
|
|
t.Errorf("new this month shows the wrong repositories: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestOpeningARepositoryKeepsTheWayBack(t *testing.T) {
|
|
reg := &fakeRegistry{results: []hf.Model{ggufModel("a/B-GGUF", "llama", 1e9, time.Now())}}
|
|
mux := mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg})
|
|
body := html.UnescapeString(mirrorGet(t, mux, "/admin/mirror?view=new&size=3").Body.String())
|
|
if !strings.Contains(body, "size=3") || !strings.Contains(body, "repo=a%2FB-GGUF") {
|
|
t.Fatalf("the row's link should keep the filters: %s", body)
|
|
}
|
|
|
|
reg.repo = hf.Repo{ID: "a/B-GGUF", Revision: "abc123def456"}
|
|
body = html.UnescapeString(mirrorGet(t, mux, "/admin/mirror?view=new&size=3&repo=a/B-GGUF").Body.String())
|
|
if !strings.Contains(body, "back to the list") || !strings.Contains(body, "view=new") {
|
|
t.Errorf("the repository page should lead back to the same listing: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestAnAdapterIsNotListedAsAModel(t *testing.T) {
|
|
reg := &fakeRegistry{results: []hf.Model{
|
|
ggufModel("a/Some-LoRA-GGUF", "qwen2", 2e6, time.Now()),
|
|
ggufModel("a/Tiny-GGUF", "qwen2", 135e6, time.Now()),
|
|
}}
|
|
body := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror").Body.String()
|
|
if strings.Contains(body, "Some-LoRA") || !strings.Contains(body, "a/Tiny-GGUF") {
|
|
t.Errorf("adapters should be left out and small models kept: %s", body)
|
|
}
|
|
}
|
|
|
|
func TestARepositoryShowsItsCard(t *testing.T) {
|
|
reg := &fakeRegistry{repo: hf.Repo{
|
|
ID: "Qwen/X-GGUF", Revision: "abc123def456", License: "apache-2.0",
|
|
BaseModel: []string{"Qwen/X"}, Card: "# X\n\nA **small** model. See [the license](LICENSE).",
|
|
Files: []hf.File{{Path: "x.gguf", Bytes: 10}},
|
|
}}
|
|
body := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
|
|
"/admin/mirror?repo=Qwen/X-GGUF").Body.String()
|
|
for _, want := range []string{"<strong>small</strong>", "license apache-2.0", "<code>Qwen/X</code>",
|
|
`href="https://huggingface.co/Qwen/X-GGUF/blob/abc123def456/LICENSE"`,
|
|
`href="https://huggingface.co/Qwen/X-GGUF"`} {
|
|
if !strings.Contains(body, want) {
|
|
t.Errorf("missing %s", want)
|
|
}
|
|
}
|
|
}
|