f580d88a14
gates / gates (push) Successful in 45s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
99 lines
3.7 KiB
Go
99 lines
3.7 KiB
Go
package mediawire
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"sync"
|
|
"testing"
|
|
)
|
|
|
|
// newLayoutBox: Sonarr runs the NEW template — no /media bind, the drive's media at the same path.
|
|
type newLayoutBox struct{ fakeBox }
|
|
|
|
func (b *newLayoutBox) Mounts(string) map[string]string {
|
|
return map[string]string{"/mnt/felhom-drives/hdd_1/userdata/media": "/mnt/felhom-drives/hdd_1/userdata/media"}
|
|
}
|
|
|
|
// TestRepairOldRoot_K7 pins R-1047 with the bench's measured sequence (K7): an install from before bc54c01 stored its
|
|
// library at /media/tv; after the update the repair adds the same-path root, moves the series' root with
|
|
// moveFiles=false, rescans, and deletes the old root — and a second run does nothing.
|
|
//
|
|
// COMPANION RED-PROOF (2026-10-15): send moveFiles=true → this test fails (a file move is never allowed). Restored.
|
|
func TestRepairOldRoot_K7(t *testing.T) {
|
|
var mu sync.Mutex
|
|
roots := []map[string]interface{}{{"id": 1, "path": "/media/tv"}}
|
|
series := []map[string]interface{}{{"id": 7, "path": "/media/tv/Problem Child"}}
|
|
var calls []string
|
|
srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
j := func(v interface{}) { _ = json.NewEncoder(rw).Encode(v) }
|
|
switch p := r.URL.Path; {
|
|
case p == "/api/v3/series":
|
|
j(series)
|
|
case p == "/api/v3/rootfolder" && r.Method == "GET":
|
|
j(roots)
|
|
case p == "/api/v3/rootfolder" && r.Method == "POST":
|
|
var in map[string]interface{}
|
|
_ = json.NewDecoder(r.Body).Decode(&in)
|
|
in["id"] = 2
|
|
roots = append(roots, in)
|
|
calls = append(calls, "add root "+in["path"].(string))
|
|
case p == "/api/v3/series/editor":
|
|
var in map[string]interface{}
|
|
_ = json.NewDecoder(r.Body).Decode(&in)
|
|
if in["moveFiles"] != false {
|
|
t.Errorf("the repair asked the app to MOVE FILES: %v", in)
|
|
}
|
|
for _, s := range series {
|
|
s["path"] = strings.Replace(s["path"].(string), "/media/tv", in["rootFolderPath"].(string), 1)
|
|
}
|
|
calls = append(calls, "editor "+in["rootFolderPath"].(string))
|
|
case p == "/api/v3/command":
|
|
calls = append(calls, "rescan")
|
|
case p == "/api/v3/rootfolder/1" && r.Method == "DELETE":
|
|
roots = roots[1:]
|
|
calls = append(calls, "delete old root")
|
|
default:
|
|
rw.WriteHeader(404)
|
|
}
|
|
}))
|
|
defer srv.Close()
|
|
w := &Wirer{Box: &newLayoutBox{}, Logger: log.New(io.Discard, "", 0), HTTP: srv.Client(), URL: func(string, int) string { return srv.URL }}
|
|
var r Result
|
|
if err := w.repairOldRoot("sonarr", srv.URL+"/api/v3", nil, "tv", &r); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
want := "add root /mnt/felhom-drives/hdd_1/userdata/media/tv|editor /mnt/felhom-drives/hdd_1/userdata/media/tv|rescan|delete old root"
|
|
if got := strings.Join(calls, "|"); got != want {
|
|
t.Fatalf("repair calls:\n got %s\n want %s", got, want)
|
|
}
|
|
if series[0]["path"] != "/mnt/felhom-drives/hdd_1/userdata/media/tv/Problem Child" {
|
|
t.Fatalf("the series' stored path did not move: %v", series[0]["path"])
|
|
}
|
|
n := len(calls)
|
|
if err := w.repairOldRoot("sonarr", srv.URL+"/api/v3", nil, "tv", &r); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(calls) != n {
|
|
t.Fatalf("a second repair run wrote again: %v", calls[n:])
|
|
}
|
|
}
|
|
|
|
// The OLD template still running (/media bound): nothing is touched.
|
|
func TestRepairOldRoot_OldTemplateUntouched(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
|
t.Errorf("no call may reach an app still on the old template: %s %s", r.Method, r.URL.Path)
|
|
}))
|
|
defer srv.Close()
|
|
w := &Wirer{Box: &fakeBox{}, Logger: log.New(io.Discard, "", 0), HTTP: srv.Client(), URL: func(string, int) string { return srv.URL }}
|
|
var r Result
|
|
if err := w.repairOldRoot("sonarr", srv.URL+"/api/v3", nil, "tv", &r); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|