ajhahn.de
← eeco
Go 75 lines
package workflow

import (
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/ajhahnde/eeco/internal/cockpit"
	"github.com/ajhahnde/eeco/internal/playbooks"
)

// TestCockpitSync_EmptyLedgerCleanNoQueue: on a repo where the cockpit was
// never generated, the builtin is a silent clean no-op and writes nothing to
// the queue (the empty-ledger gate — what makes it safe in the post-merge
// default).
func TestCockpitSync_EmptyLedgerCleanNoQueue(t *testing.T) {
	cfg := newCfg(t)
	res, err := cockpitSync{}.Run(Env{Config: cfg})
	if err != nil {
		t.Fatal(err)
	}
	if res.Code != CodeClean {
		t.Errorf("Code = %d, want %d (%q)", res.Code, CodeClean, res.Summary)
	}
	if q := queueBody(t, cfg); q != "" {
		t.Errorf("queue should be empty on an unused cockpit, got:\n%s", q)
	}
}

// TestCockpitSync_DriftFindingIdempotent: a hand-edited artifact yields a
// CodeFinding and one queued cockpit-sync item; a repeated run does not pile
// up a duplicate (AppendUnique).
func TestCockpitSync_DriftFindingIdempotent(t *testing.T) {
	cfg := newCfg(t)
	// newCfg leaves UserDir empty; point it at a private tree beside the repo
	// so Generate can emit an artifact the builtin then verifies.
	cfg.UserDir = filepath.Join(cfg.RepoRoot, "tester")
	if err := cockpit.SaveSelection(cfg, cockpit.Selection{Targets: []string{"claude"}}); err != nil {
		t.Fatal(err)
	}
	pb, err := playbooks.Get("handover")
	if err != nil {
		t.Fatal(err)
	}
	if _, err := cockpit.Generate(cfg, pb, "claude"); err != nil {
		t.Fatalf("generate: %v", err)
	}
	dst := filepath.Join(cfg.UserDir, ".claude", "skills", "handover", "SKILL.md")
	if err := os.WriteFile(dst, []byte("edited\n"), 0o644); err != nil {
		t.Fatal(err)
	}

	res, err := cockpitSync{}.Run(Env{Config: cfg})
	if err != nil {
		t.Fatal(err)
	}
	if res.Code != CodeFinding {
		t.Fatalf("Code = %d, want %d (%q)", res.Code, CodeFinding, res.Summary)
	}
	body := queueBody(t, cfg)
	n1 := strings.Count(body, "**cockpit-sync**")
	if n1 == 0 {
		t.Fatalf("queue missing a cockpit-sync item:\n%s", body)
	}

	if _, rerr := (cockpitSync{}).Run(Env{Config: cfg}); rerr != nil {
		t.Fatal(rerr)
	}
	n2 := strings.Count(queueBody(t, cfg), "**cockpit-sync**")
	if n1 != n2 {
		t.Errorf("AppendUnique not idempotent: %d cockpit-sync item(s) → %d", n1, n2)
	}
}