~bigbes/sr-ht-spec

ref: 128d72963281e275bb1ec3be2bdb8653a2bb0c78 sr-ht-spec/cmd/specsrht/token_test.go -rw-r--r-- 2.3 KiB
128d7296 — Eugene Blikh ci: cache Go module and build dirs via cacher 13 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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)
	}
}