feat: recursive WAV browsing in subdirectories

Handle ListWavs now uses filepath.WalkDir to find .wav files
in all subdirectories. Returns relative paths (e.g. Kicks/kick.wav).
Serves them correctly via /wavs/ prefix.

Fixed: WalkDir swallows root errors differently than ReadDir —
now detects and reports non-existent root directory errors.

Added test for recursive subdirectory traversal.
This commit is contained in:
2026-06-22 01:05:44 -07:00
parent 371feaf0cb
commit fe3e92ce33
2 changed files with 58 additions and 8 deletions
+38
View File
@@ -473,6 +473,41 @@ func TestHandleListWavs_ReturnsWavFiles(t *testing.T) {
}
}
func TestHandleListWavs_RecursiveSubdirs(t *testing.T) {
tmp := t.TempDir()
wavDir := filepath.Join(tmp, "wavs")
subDir := filepath.Join(wavDir, "Kicks")
if err := os.MkdirAll(subDir, 0755); err != nil {
t.Fatal(err)
}
fd, _ := os.Create(filepath.Join(wavDir, "root.wav"))
_ = fd.Close()
fd2, _ := os.Create(filepath.Join(subDir, "kick1.wav"))
_ = fd2.Close()
req := httptest.NewRequest("GET", "/api/list-wavs?dir="+wavDir, nil)
rr := httptest.NewRecorder()
handleListWavs(rr, req)
var files []string
if err := json.Unmarshal(rr.Body.Bytes(), &files); err != nil {
t.Fatalf("invalid JSON: %v", err)
}
if len(files) != 2 {
t.Errorf("expected 2 wav files, got %d: %v", len(files), files)
}
found := make(map[string]bool)
for _, f := range files {
found[f] = true
}
if !found["root.wav"] {
t.Errorf("missing root.wav, got %v", files)
}
if !found[filepath.Join("Kicks", "kick1.wav")] {
t.Errorf("missing Kicks/kick1.wav, got %v", files)
}
}
func TestHandleListWavs_EmptyDir(t *testing.T) {
tmp := t.TempDir()
req := httptest.NewRequest("GET", "/api/list-wavs?dir="+tmp, nil)
@@ -486,6 +521,9 @@ func TestHandleListWavs_EmptyDir(t *testing.T) {
if err := json.Unmarshal(rr.Body.Bytes(), &files); err != nil {
t.Fatalf("invalid JSON: %v", err)
}
if files == nil {
t.Fatal("expected empty array [], got null")
}
if len(files) != 0 {
t.Errorf("expected 0 files, got %d", len(files))
}