(t *testing.T)
| 216 | } |
| 217 | |
| 218 | func TestSaveFetchToScratch(t *testing.T) { |
| 219 | scratch := t.TempDir() |
| 220 | t.Setenv("CHATCLI_AGENT_TMPDIR", scratch) |
| 221 | |
| 222 | t.Run("no save requested returns empty", func(t *testing.T) { |
| 223 | path, err := saveFetchToScratch(fetchArgs{SaveToFile: false}, "body") |
| 224 | if err != nil || path != "" { |
| 225 | t.Fatalf("expected empty path no error, got %q, %v", path, err) |
| 226 | } |
| 227 | }) |
| 228 | |
| 229 | t.Run("writes confined to scratch", func(t *testing.T) { |
| 230 | path, err := saveFetchToScratch(fetchArgs{SaveToFile: true, SavePath: "ok.txt"}, "data") |
| 231 | if err != nil { |
| 232 | t.Fatalf("save: %v", err) |
| 233 | } |
| 234 | if !strings.HasPrefix(path, scratch) { |
| 235 | t.Fatalf("path %q not under scratch %q", path, scratch) |
| 236 | } |
| 237 | }) |
| 238 | |
| 239 | t.Run("absolute escape path is reduced to basename", func(t *testing.T) { |
| 240 | // filepath.Base strips the directory, so this stays inside scratch. |
| 241 | path, err := saveFetchToScratch(fetchArgs{SaveToFile: true, SavePath: "/etc/passwd"}, "data") |
| 242 | if err != nil { |
| 243 | t.Fatalf("save: %v", err) |
| 244 | } |
| 245 | if !strings.HasPrefix(path, scratch) { |
| 246 | t.Fatalf("escape not contained: %q", path) |
| 247 | } |
| 248 | }) |
| 249 | } |
nothing calls this directly
no test coverage detected