internal/store/statuses_test.go
85 lines · 2684 bytes
1package store
2
3import "testing"
4
5// Checks carry the timing of the build behind them. Statuses posted from
6// outside CI have no build, and must not borrow one.
7func TestChecksForCommit(t *testing.T) {
8 s := open(t)
9 if err := s.MigrateUp(); err != nil {
10 t.Fatal(err)
11 }
12 uid, err := s.CreateUser("cmc", true)
13 if err != nil {
14 t.Fatal(err)
15 }
16 repoID, err := s.CreateRepo("user", uid, "lib", "public")
17 if err != nil {
18 t.Fatal(err)
19 }
20 if _, err := s.CreateBuild(repoID, "test", "abc123", "main", `["true"]`, "", true); err != nil {
21 t.Fatal(err)
22 }
23 if _, err := s.DB.Exec(`UPDATE builds SET started_at = '2026-08-28T04:42:54Z',
24 finished_at = '2026-08-28T04:44:06Z', status = 'success' WHERE number = 1`); err != nil {
25 t.Fatal(err)
26 }
27 for _, c := range []struct{ context, state string }{
28 {"ci/test", "success"},
29 {"ci/absent", "pending"}, // a status with no build of its own
30 {"external/lint", "success"},
31 } {
32 if err := s.SetCommitStatus(repoID, "abc123", c.context, c.state, "", "", uid); err != nil {
33 t.Fatal(err)
34 }
35 }
36
37 checks, combined, err := s.ChecksForCommit(repoID, "abc123")
38 if err != nil {
39 t.Fatal(err)
40 }
41 if combined != "pending" {
42 t.Fatalf("combined: %s", combined)
43 }
44 byContext := map[string]Check{}
45 for _, c := range checks {
46 if c.UpdatedAt == "" {
47 t.Errorf("%s has no timestamp", c.Context)
48 }
49 byContext[c.Context] = c
50 }
51 if got := byContext["ci/test"]; got.Build != 1 || got.Duration.String() != "1m12s" {
52 t.Errorf("ci/test timing: build %d, %s", got.Build, got.Duration)
53 }
54 for _, ctx := range []string{"ci/absent", "external/lint"} {
55 if got := byContext[ctx]; got.Build != 0 || got.Duration != 0 {
56 t.Errorf("%s borrowed timing: build %d, %s", ctx, got.Build, got.Duration)
57 }
58 }
59}
60
61// A job a path filter excluded records "skipped" rather than nothing at
62// all (#172). It must satisfy require_checks like any other green state,
63// without a failure or pending status elsewhere being masked by it.
64func TestCombinedStatusTreatsSkippedAsGreen(t *testing.T) {
65 only := []CommitStatus{{Context: "ci/unit", State: "skipped"}}
66 if got := CombinedStatus(only); got != "success" {
67 t.Fatalf("all-skipped combined status: %s", got)
68 }
69
70 withPending := []CommitStatus{
71 {Context: "ci/unit", State: "skipped"},
72 {Context: "ci/lint", State: "pending"},
73 }
74 if got := CombinedStatus(withPending); got != "pending" {
75 t.Fatalf("skipped plus pending combined status: %s", got)
76 }
77
78 withFailure := []CommitStatus{
79 {Context: "ci/unit", State: "skipped"},
80 {Context: "ci/lint", State: "failure"},
81 }
82 if got := CombinedStatus(withFailure); got != "failure" {
83 t.Fatalf("skipped plus failure combined status: %s", got)
84 }
85}