| 1 | package cli |
| 2 | |
| 3 | import ( |
| 4 | "encoding/json" |
| 5 | "path/filepath" |
| 6 | "reasonix/internal/pluginpkg" |
| 7 | "strings" |
| 8 | "testing" |
| 9 | ) |
| 10 | |
| 11 | func TestPluginDryRunPreservesApprovalPlan(t *testing.T) { |
| 12 | t.Setenv("REASONIX_HOME", t.TempDir()) |
| 13 | t.Chdir(t.TempDir()) |
| 14 | source := filepath.Join(t.TempDir(), "demo") |
| 15 | writePluginTestFile(t, filepath.Join(source, pluginpkg.CodexManifest), `{"name":"demo","version":"1.0.0","description":"Demo","skills":"skills"}`) |
| 16 | writePluginTestFile(t, filepath.Join(source, "skills", "helper", "SKILL.md"), "---\nname: helper\ndescription: Help\n---\nHelp.") |
| 17 | out := captureStdout(t, func() { |
| 18 | if code := pluginCommand([]string{"install", source, "--dry-run"}); code != 0 { |
| 19 | t.Errorf("exit %d", code) |
| 20 | } |
| 21 | }) |
| 22 | var result struct { |
| 23 | Actions []json.RawMessage `json:"actions"` |
| 24 | PlanID string `json:"planId"` |
| 25 | } |
| 26 | if err := json.Unmarshal([]byte(out), &result); err != nil { |
| 27 | t.Fatal(err) |
| 28 | } |
| 29 | if len(result.Actions) == 0 || !strings.HasPrefix(result.PlanID, "hmac-v1:") || len(result.PlanID) != 72 { |
| 30 | t.Fatalf("dry-run lost reviewable plan: %s", out) |
| 31 | } |
| 32 | } |
| 33 |