ZDDC/zddc/internal/listing/listing_test.go
ZDDC e4e0fedaa2 refactor(history): store under .zddc.d/history/; drop .history carve-out + dead .devshell
Consolidate edit-history bookkeeping under the single reserved .zddc.d/
sidecar (where tokens + access logs already live), instead of its own
top-level .history/ dot-name:

- history.go: record + text history now write/read <dir>/.zddc.d/history/<stem>/
  (was <dir>/.history/<stem>/). Const renamed .history → .zddc.d/history and
  unexported (the only external user was the dispatch carve-out). The history
  VIEWER endpoints (<record>.yaml?history=1, <file>?history=…) read it
  server-side, so they keep working for anyone with read on the live file;
  the raw store is bookkeeping, blocked by the existing dot-prefix guard.
- main.go: drop the .history GET carve-out (b9ebee7) — superseded; history is
  reached via the viewer, not raw browsing. Reword the guard comment to
  "reserve .zddc.d/ bookkeeping" (Part B will replace the blanket block with a
  .zddc.d/ admin-fence).
- Delete dead .devshell references (the dev-shell was dropped from the chart):
  guard comment, paths.go comment, test fixtures/cases (→ .zddc.d), and docs.

This is Part A of the approved plan: ship history in its permanent home so we
never migrate it twice. Tests updated to the new paths; the obsolete
TestDispatchHistoryReadCarveOut is removed (raw-block covered by
TestDispatchHidesDotPrefixedSegments, viewer by mdhistory_test).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 13:48:41 -05:00

87 lines
2.3 KiB
Go

package listing
import (
"os"
"path/filepath"
"testing"
)
// TestFromDirEntriesFiltersHidden asserts that both '.' and '_' prefixed
// entries are excluded from listings — the '.' branch is the long-standing
// rule (matches dispatch dot-prefix guard); '_' is for operator-managed
// scaffolding like install.zip's _template/ that should be reachable by
// direct URL but invisible to browse.
func TestFromDirEntriesFiltersHidden(t *testing.T) {
dir := t.TempDir()
for _, name := range []string{
"Project-A",
"Project-B",
".zddc", // hidden file
".zddc.d", // hidden dir (reserved bookkeeping)
"_template", // scaffolding dir
"_archive", // scaffolding dir
"_notes.txt", // scaffolding file
"normal.txt",
} {
path := filepath.Join(dir, name)
if err := os.WriteFile(path, []byte("x"), 0o644); err != nil {
t.Fatalf("write %s: %v", name, err)
}
}
entries, err := os.ReadDir(dir)
if err != nil {
t.Fatalf("ReadDir: %v", err)
}
got, err := FromDirEntries(entries, "/", false)
if err != nil {
t.Fatalf("FromDirEntries: %v", err)
}
want := map[string]bool{
"Project-A": true,
"Project-B": true,
"normal.txt": true,
}
if len(got) != len(want) {
var names []string
for _, e := range got {
names = append(names, e.Name)
}
t.Fatalf("got %d entries (%v), want %d (%v)", len(got), names, len(want), want)
}
for _, e := range got {
if !want[e.Name] {
t.Errorf("unexpected entry in listing: %q", e.Name)
}
}
}
// TestFromDirEntriesIncludeHidden verifies the includeHidden=true path
// surfaces dot- and underscore-prefixed entries.
func TestFromDirEntriesIncludeHidden(t *testing.T) {
dir := t.TempDir()
for _, name := range []string{".zddc", "_template", "normal.txt"} {
if err := os.WriteFile(filepath.Join(dir, name), []byte("x"), 0o644); err != nil {
t.Fatalf("write %s: %v", name, err)
}
}
entries, err := os.ReadDir(dir)
if err != nil {
t.Fatalf("ReadDir: %v", err)
}
got, err := FromDirEntries(entries, "/", true)
if err != nil {
t.Fatalf("FromDirEntries: %v", err)
}
want := map[string]bool{".zddc": true, "_template": true, "normal.txt": true}
if len(got) != len(want) {
var names []string
for _, e := range got {
names = append(names, e.Name)
}
t.Fatalf("got %d entries (%v), want %d", len(got), names, len(want))
}
}