package api
import (
"context"
"path/filepath"
"testing"
"craftdesign.group/quarry/internal/index"
"craftdesign.group/quarry/internal/oltp"
"craftdesign.group/quarry/internal/ops"
)
// fakeExternal answers a fixed set of external checks for one subject.
type fakeExternal struct {
subject string
checks []oltp.ExternalCheck
}
func (f fakeExternal) CheckReporterToken(string, string) bool { return true }
func (f fakeExternal) UpsertExternalCheck(string, oltp.ExternalCheck) error { return nil }
func (f fakeExternal) MintReporterToken(string, string) (string, error) { return "", nil }
func (f fakeExternal) ReporterTokens(string) ([]oltp.ReporterToken, error) { return nil, nil }
func (f fakeExternal) RevokeReporterToken(string, string) error { return nil }
func (f fakeExternal) ExternalChecks(_, subject string) ([]oltp.ExternalCheck, error) {
if subject == f.subject {
return f.checks, nil
}
return nil, nil
}
const g65Checkin = "eb83336845e0eb83336845e0eb83336845e0eb83"
// An external check reported against a check-in shows on that
// check-in — whether or not a landing happens to be open on it.
//
// It used to show only on landing.get, the one reader that asked the
// external store; a check reported on a commit with no open landing
// was accepted with 200 and visible on no surface at all (ab50b6dd,
// G-65, measured by jva). checkin.get and landing.get now read the
// same producer.
func TestAnExternalCheckShowsOnItsCheckin(t *testing.T) {
ix, err := index.Open(filepath.Join(t.TempDir(), "index.db"))
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { ix.Close() })
if err := ix.FoldCheckins([]index.CheckinRecord{{Hash: g65Checkin, Date: "2026-01-01T00:00:00", User: "jan", Comment: "g65 probe"}}); err != nil {
t.Fatal(err)
}
r := ops.NewRegistry()
if err := RegisterAll(r, Deps{Version: "v", Repos: testRepos(ix), External: fakeExternal{
subject: g65Checkin,
checks: []oltp.ExternalCheck{{Subject: g65Checkin, Context: "external/g65-probe", State: "success", URL: "https://ci.example/1", Updated: "2026-01-01T01:00:00"}},
}}); err != nil {
t.Fatal(err)
}
got, err := r.Invoke(context.Background(), "checkin.get", checkinGetIn{Repo: "test", Hash: g65Checkin})
if err != nil {
t.Fatal(err)
}
out := got.(checkinGetOut)
if len(out.Checks) != 1 || out.Checks[0].Pipeline != "external" || out.Checks[0].Workflow != "external/g65-probe" || out.Checks[0].Status != "success" {
t.Fatalf("FAIL: checkin.get checks = %+v; want the external check", out.Checks)
}
t.Logf("ok: checkin.get carries %s %s (%s)", out.Checks[0].Pipeline, out.Checks[0].Workflow, out.Checks[0].Status)
// A check-in with nothing reported has an empty list, not null —
// null read as "this surface does not carry checks".
got, err = r.Invoke(context.Background(), "checkin.get", checkinGetIn{Repo: "test", Hash: g65Checkin[:12]})
if err != nil {
t.Fatal(err)
}
if out.Checks == nil {
t.Fatal("FAIL: checks is null")
}
t.Log("ok: checks is a list, never null")
}