Go · 2097 bytes Raw Blame History
1 // SPDX-License-Identifier: AGPL-3.0-or-later
2
3 package protection
4
5 import (
6 "testing"
7
8 reposdb "github.com/tenseleyFlow/shithub/internal/repos/sqlc"
9 )
10
11 func TestMatchRule_LongestPrefixWins(t *testing.T) {
12 t.Parallel()
13 rules := []reposdb.BranchProtectionRule{
14 {ID: 1, Pattern: "*"},
15 {ID: 2, Pattern: "release/*"},
16 {ID: 3, Pattern: "release/v1.0"},
17 }
18 cases := []struct {
19 branch string
20 wantID int64
21 wantHit bool
22 }{
23 {"release/v1.0", 3, true},
24 {"release/beta", 2, true},
25 // `*` doesn't cross `/` per filepath.Match — no rule matches
26 // a slash-containing branch when no rule has a deeper pattern.
27 {"release/v1.0/sub", 0, false},
28 {"trunk", 1, true},
29 {"feature-x", 1, true},
30 }
31 for _, c := range cases {
32 got, ok := matchRule(rules, c.branch)
33 if ok != c.wantHit {
34 t.Errorf("branch %q: hit=%v want %v", c.branch, ok, c.wantHit)
35 continue
36 }
37 if !c.wantHit {
38 continue
39 }
40 if got.ID != c.wantID {
41 t.Errorf("branch %q: matched rule %d, want %d", c.branch, got.ID, c.wantID)
42 }
43 }
44 }
45
46 func TestMatchRule_NoMatchReturnsFalse(t *testing.T) {
47 t.Parallel()
48 rules := []reposdb.BranchProtectionRule{{Pattern: "release/*"}}
49 if _, ok := matchRule(rules, "trunk"); ok {
50 t.Errorf("expected no match for trunk against release/*")
51 }
52 }
53
54 func TestMatchRule_AlphabeticalTiebreak(t *testing.T) {
55 t.Parallel()
56 rules := []reposdb.BranchProtectionRule{
57 {ID: 1, Pattern: "feature/*"},
58 {ID: 2, Pattern: "feat[u]re/*"}, // same length matching same string
59 }
60 got, ok := matchRule(rules, "feature/foo")
61 if !ok {
62 t.Fatalf("expected match")
63 }
64 // Both patterns have same length; alphabetical tiebreak:
65 // "feat[u]re/*" < "feature/*" so the [u]re/* wins.
66 if got.ID != 2 {
67 t.Errorf("got rule %d, want 2 (alphabetical tiebreak)", got.ID)
68 }
69 }
70
71 func TestIsAllZeros(t *testing.T) {
72 t.Parallel()
73 if !isAllZeros("0000000000000000000000000000000000000000") {
74 t.Errorf("40 zeros → true")
75 }
76 if isAllZeros("0000000000000000000000000000000000000001") {
77 t.Errorf("39 zeros + 1 → false")
78 }
79 if isAllZeros("00000") {
80 t.Errorf("short string → false")
81 }
82 }
83