package main
import (
"strings"
"testing"
"time"
"sourcecraft.dev/bigbes/sr-ht-spec/service"
)
func TestParseTokenIDRejectsWhatIsNotAnID(t *testing.T) {
for _, in := range []string{"", "0", "-1", "3.0", "abc", " 3", "3 "} {
if _, err := parseTokenID(in); err == nil {
t.Errorf("parseTokenID(%q) was accepted", in)
}
}
id, err := parseTokenID("42")
if err != nil {
t.Fatalf("parseTokenID(\"42\"): %v", err)
}
if id != 42 {
t.Errorf("parseTokenID(\"42\") = %d want 42", id)
}
}
// TestParseTokenIDPointsAtTheListing keeps the failure actionable: an operator
// who mistyped an id needs to be told where the ids come from, not just that
// this one was wrong.
func TestParseTokenIDPointsAtTheListing(t *testing.T) {
_, err := parseTokenID("nope")
if err == nil {
t.Fatal("parseTokenID accepted a non-numeric id")
}
if !strings.Contains(err.Error(), "specsrht token list") {
t.Errorf("the error does not say how to find the ids:\n%v", err)
}
}
func TestFormatTokenRow(t *testing.T) {
created := time.Date(2026, 8, 5, 9, 30, 0, 0, time.UTC)
revoked := created.Add(24 * time.Hour)
active := formatTokenRow(service.AgentToken{ID: 1, Name: "claude", Created: created})
if want := "1\tclaude\t2026-08-05T09:30:00Z\tactive"; active != want {
t.Errorf("active row = %q want %q", active, want)
}
dead := formatTokenRow(service.AgentToken{ID: 2, Name: "old", Created: created, Revoked: &revoked})
if want := "2\told\t2026-08-05T09:30:00Z\trevoked 2026-08-06T09:30:00Z"; dead != want {
t.Errorf("revoked row = %q want %q", dead, want)
}
}
// There is no test that the listing keeps the stored hash out: service.AgentToken
// has no hash field, so the type is the guarantee and a test would only assert
// that Go's struct literals work.
// TestRunTokenRejectsBadInvocationsBeforeTheDatabase guards the ordering that
// makes this command usable on a workstation: a usage error must be reported
// without a config file or a Postgres connection, which is what an operator
// typing it blind has.
func TestRunTokenRejectsBadInvocationsBeforeTheDatabase(t *testing.T) {
err := runToken(nil)
if err == nil {
t.Fatal("runToken accepted an empty argument list")
}
if err.Error() != tokenUsage {
t.Errorf("empty invocation did not print the usage line:\n%v", err)
}
}