package overlay import ( "context" "os" "path/filepath" "strings" "testing" "sub2api-cn-relay-manager/internal/pack" ) func TestApplyCopiesSourceAndAppliesPatch(t *testing.T) { sourceDir := t.TempDir() if err := os.MkdirAll(filepath.Join(sourceDir, "backend"), 0o755); err != nil { t.Fatalf("MkdirAll() error = %v", err) } if err := os.WriteFile(filepath.Join(sourceDir, "backend", "hello.txt"), []byte("hello\n"), 0o644); err != nil { t.Fatalf("WriteFile() error = %v", err) } packDir := t.TempDir() patchBody := strings.Join([]string{ "diff --git a/backend/hello.txt b/backend/hello.txt", "--- a/backend/hello.txt", "+++ b/backend/hello.txt", "@@ -1 +1 @@", "-hello", "+patched", "", }, "\n") patchPath := filepath.Join(packDir, "overlays", "sample.patch") if err := os.MkdirAll(filepath.Dir(patchPath), 0o755); err != nil { t.Fatalf("MkdirAll() error = %v", err) } if err := os.WriteFile(patchPath, []byte(patchBody), 0o644); err != nil { t.Fatalf("WriteFile() error = %v", err) } result, err := Apply(context.Background(), ApplyRequest{ PackDir: packDir, SourceDir: sourceDir, Overlays: []pack.HostOverlay{{ OverlayID: "sample", PatchPath: "overlays/sample.patch", }}, }) if err != nil { t.Fatalf("Apply() error = %v", err) } body, err := os.ReadFile(filepath.Join(result.OutputDir, "backend", "hello.txt")) if err != nil { t.Fatalf("ReadFile() error = %v", err) } if string(body) != "patched\n" { t.Fatalf("patched file = %q, want %q", string(body), "patched\n") } if _, err := os.Stat(result.MetadataFilePath); err != nil { t.Fatalf("Stat(metadata) error = %v", err) } } func TestApplySupportsRelativePackDir(t *testing.T) { workspaceDir := t.TempDir() originalWD, err := os.Getwd() if err != nil { t.Fatalf("Getwd() error = %v", err) } if err := os.Chdir(workspaceDir); err != nil { t.Fatalf("Chdir() error = %v", err) } t.Cleanup(func() { _ = os.Chdir(originalWD) }) sourceDir := filepath.Join(workspaceDir, "source") if err := os.MkdirAll(filepath.Join(sourceDir, "backend"), 0o755); err != nil { t.Fatalf("MkdirAll() error = %v", err) } if err := os.WriteFile(filepath.Join(sourceDir, "backend", "hello.txt"), []byte("hello\n"), 0o644); err != nil { t.Fatalf("WriteFile() error = %v", err) } packDir := filepath.Join(workspaceDir, "pack") patchPath := filepath.Join(packDir, "overlays", "sample.patch") if err := os.MkdirAll(filepath.Dir(patchPath), 0o755); err != nil { t.Fatalf("MkdirAll() error = %v", err) } patchBody := strings.Join([]string{ "diff --git a/backend/hello.txt b/backend/hello.txt", "--- a/backend/hello.txt", "+++ b/backend/hello.txt", "@@ -1 +1 @@", "-hello", "+patched", "", }, "\n") if err := os.WriteFile(patchPath, []byte(patchBody), 0o644); err != nil { t.Fatalf("WriteFile() error = %v", err) } result, err := Apply(context.Background(), ApplyRequest{ PackDir: "pack", SourceDir: sourceDir, Overlays: []pack.HostOverlay{{ OverlayID: "sample", PatchPath: "overlays/sample.patch", }}, }) if err != nil { t.Fatalf("Apply() with relative pack dir error = %v", err) } body, err := os.ReadFile(filepath.Join(result.OutputDir, "backend", "hello.txt")) if err != nil { t.Fatalf("ReadFile() error = %v", err) } if string(body) != "patched\n" { t.Fatalf("patched file = %q, want %q", string(body), "patched\n") } } func TestFilterOverlaysRejectsMissingOverlayID(t *testing.T) { _, err := FilterOverlays([]pack.HostOverlay{{OverlayID: "sample"}}, "missing") if err == nil || !strings.Contains(err.Error(), `overlay "missing" did not match`) { t.Fatalf("FilterOverlays() error = %v, want missing overlay detail", err) } }