package handover import ( "testing" "time" ) func TestBuildHappyPath(t *testing.T) { in := Input{ DecisionID: "dec-1", PayloadHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ApprovalRef: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", TransformRef: "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", SinkID: "sink:dummy-sink", SinkRecordRef: "file:///data/dummy-sink/dec-1.json", Actor: "agent-dummy-sink", IssuedAt: time.Date(2026, 1, 2, 3, 4, 5, 0, time.UTC), } stmt, err := Build(in) if err != nil { t.Fatalf("Build: %v", err) } if stmt["predicateType"] != PredicateType { t.Fatalf("predicateType = %v, want %v", stmt["predicateType"], PredicateType) } pred := stmt["predicate"].(map[string]any) if pred["decision_id"] != "dec-1" { t.Fatalf("predicate.decision_id = %v", pred["decision_id"]) } if pred["approval_ref"] != in.ApprovalRef { t.Fatalf("predicate.approval_ref = %v", pred["approval_ref"]) } if pred["issued_at"] != "2026-01-02T03:04:05Z" { t.Fatalf("predicate.issued_at = %v", pred["issued_at"]) } subject := stmt["subject"].([]any)[0].(map[string]any) digest := subject["digest"].(map[string]any) wantHex := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" if digest["sha256"] != wantHex { t.Fatalf("digest.sha256 = %v, want %v", digest["sha256"], wantHex) } materials := pred["materials"].([]any) if len(materials) != 2 { t.Fatalf("materials len = %d, want 2", len(materials)) } } func TestBuildRequiresFields(t *testing.T) { _, err := Build(Input{}) if err == nil { t.Fatalf("Build empty: want err") } } func TestStripSha256Prefix(t *testing.T) { hex, err := StripSha256Prefix("sha256:abcd") if err != nil { t.Fatalf("StripSha256Prefix: %v", err) } if hex != "abcd" { t.Fatalf("hex = %q, want abcd", hex) } if _, err := StripSha256Prefix("sha512:abcd"); err == nil { t.Fatalf("sha512 prefix should error") } if _, err := StripSha256Prefix(""); err == nil { t.Fatalf("empty should error") } }