Skip to content
quarry Artifact [ddf8736c52]
Login

Artifact [ddf8736c52]

Artifact ddf8736c5241ea7dbddc67b253289cb1d6141978fa33674f9da17930851c1041:


package web

import (
	"net/http/httptest"
	"path/filepath"
	"strings"
	"testing"
	"time"

	"craftdesign.group/quarry/internal/api"
	"craftdesign.group/quarry/internal/ci"
	"craftdesign.group/quarry/internal/oltp"
	"craftdesign.group/quarry/internal/ops"
)

// THE RUN PAGE SAYS WHAT LETTERS EACH JOB'S RUN TOKEN CARRIED, AND
// WHETHER IT IS OVER; NEVER THE VALUE (RFC 0021 §runs).
func TestTheRunPageNamesItsTokensLetters(t *testing.T) {
	db, err := oltp.Open(filepath.Join(t.TempDir(), "o.db"))
	if err != nil {
		t.Fatal(err)
	}
	t.Cleanup(func() { db.Close() })
	db.SyncProjectCode = func(string) (string, bool) { return "CODE", true }
	for _, id := range []string{"run-1", "run-2"} {
		if err := db.AddCIRun(oltp.CIRun{RunID: id, Repo: "alpha", Checkin: "abc", Workflow: "quarry", Pipeline: "ci/release.yml", Status: "running"}); err != nil {
			t.Fatal(err)
		}
	}
	_, value, _, err := db.MintRunToken(oltp.RunTokenSpec{Run: "run-1", Repo: "alpha", Job: "publish", Letters: "y", Expires: time.Now().Add(time.Hour)})
	if err != nil {
		t.Fatal(err)
	}
	runs := []api.CIRun{
		{RunID: "run-1", Checkin: "abc", Workflow: "quarry", Pipeline: "ci/release.yml", Status: "running", Started: "2026-10-02T01:00:00Z"},
		{RunID: "run-2", Checkin: "abc", Workflow: "quarry", Pipeline: "ci/release.yml", Status: "running", Started: "2026-10-02T01:00:00Z"},
	}
	r := ops.NewRegistry()
	deps := api.Deps{Version: "v",
		Repos:   api.NewRepos(map[string]*api.Repo{"alpha": {Index: landingIndex(t, false)}}),
		CI:      fakeCI{runs: runs},
		Secrets: db,
	}
	if err := api.RegisterAll(r, deps); err != nil {
		t.Fatal(err)
	}
	srv := httptest.NewServer(HandlerWith(r, nil, nil, []Option{
		WithSessions(fakeSessions{user: "dan", roles: map[string]ops.Auth{"alpha": ops.Admin}}),
		WithCaps(stubCaps{letters: "i8"}), WithEngine(fakeEngine{run: ci.Run{RunID: "run-1", Workflow: "quarry", Status: "running"}})},
		Verify(func(string, string, string, ops.Auth) api.Decision { return api.Denied })))
	t.Cleanup(srv.Close)

	page := asDan(t, srv, "/r/alpha/ci/run/run-1")
	got := hookAttrs(page, "run-token-job")
	if len(got) != 1 || got[0]["data-job"] != "publish" || got[0]["data-letters"] != "goy" || got[0]["data-state"] != "live" {
		t.Errorf("FAIL: a live run's token line %v; want publish carrying goy, live", got)
	}
	if strings.Contains(page, value) {
		t.Errorf("FAIL: the run page carries the token's value")
	}
	if err := db.CompleteCIRun("run-1", "succeeded", ""); err != nil {
		t.Fatal(err)
	}
	if got := hookAttrs(asDan(t, srv, "/r/alpha/ci/run/run-1"), "run-token-job"); len(got) != 1 || got[0]["data-state"] != "revoked" {
		t.Errorf("FAIL: after close the line %v; want revoked", got)
	}
	if got := hookAttrs(asDan(t, srv, "/r/alpha/ci/run/run-2"), "run-token"); len(got) != 0 {
		t.Errorf("FAIL: a run that minted nothing shows %d token lines; want none", len(got))
	}
	t.Log("ok: the run page names each job's letters and state, and no value")
}