package handler import ( "context" "encoding/json" "net/http" "net/http/httptest" "os" "path/filepath" "testing" "codeberg.org/VARASYS/ZDDC/zddc/internal/config" ) // TestServeProjectListFiltersHiddenAndScaffolding asserts the project list // excludes both '.'-prefixed entries (the long-standing rule, e.g. .devshell) // AND '_'-prefixed entries (operator scaffolding like install.zip's // _template/ that's reachable by direct URL but should not clutter the // project picker). func TestServeProjectListFiltersHiddenAndScaffolding(t *testing.T) { root := t.TempDir() for _, name := range []string{ "Project-A", "Project-B", ".devshell", // dot-prefixed dir — must be excluded "_template", // underscore scaffolding — must be excluded "_archive", } { if err := os.MkdirAll(filepath.Join(root, name), 0o755); err != nil { t.Fatalf("mkdir %s: %v", name, err) } } // A loose .zddc that allows everyone, so ACL doesn't interfere with // what we're actually testing (the prefix filter). if err := os.WriteFile(filepath.Join(root, ".zddc"), []byte("acl:\n allow: [\"*\"]\n"), 0o644); err != nil { t.Fatalf("write .zddc: %v", err) } cfg := config.Config{Root: root, EmailHeader: "X-Auth-Request-Email"} req := httptest.NewRequest(http.MethodGet, "/", nil) req = req.WithContext(context.WithValue(req.Context(), EmailKey, "alice@example.com")) rec := httptest.NewRecorder() ServeProjectList(cfg, rec, req) if rec.Code != http.StatusOK { t.Fatalf("status = %d, want 200; body = %s", rec.Code, rec.Body.String()) } var got []map[string]string if err := json.Unmarshal(rec.Body.Bytes(), &got); err != nil { t.Fatalf("invalid JSON: %v\n%s", err, rec.Body.String()) } want := map[string]bool{"Project-A": true, "Project-B": true} if len(got) != len(want) { t.Fatalf("got %d projects (%+v), want %d (%v)", len(got), got, len(want), want) } for _, p := range got { if !want[p["name"]] { t.Errorf("unexpected project in list: %q", p["name"]) } } }