133728e barerepo 1mo
1
package httpd
133728e barerepo 1mo
3
import (
133728e barerepo 1mo
4
"testing"
133728e barerepo 1mo
6
"github.com/barerepo/server/internal/repocfg"
133728e barerepo 1mo
7
"github.com/barerepo/server/internal/store"
133728e barerepo 1mo
10
// A hook gets the events it named and no others, because chapter 23.2 makes the list the filter.
133728e barerepo 1mo
11
func TestAHookOnlyGetsTheEventsItNamed(t *testing.T) {
133728e barerepo 1mo
12
cfg := repocfg.Config{Webhook: []repocfg.Webhook{
133728e barerepo 1mo
13
{URL: "https://deploy.example/hook", Events: []string{"push"}},
133728e barerepo 1mo
14
{URL: "https://chat.example/hook", Events: []string{"proposal.opened", "thread.opened"}},
133728e barerepo 1mo
15
{URL: "https://nothing.example/hook"},
133728e barerepo 1mo
16
}}
133728e barerepo 1mo
17
cases := []struct {
133728e barerepo 1mo
18
kind string
133728e barerepo 1mo
19
want []string
133728e barerepo 1mo
20
}{
133728e barerepo 1mo
21
{store.Pushed, []string{"https://deploy.example/hook"}},
133728e barerepo 1mo
22
{store.ProposalOpened, []string{"https://chat.example/hook"}},
133728e barerepo 1mo
23
{store.ThreadOpened, []string{"https://chat.example/hook"}},
133728e barerepo 1mo
24
{store.RunFailed, nil},
133728e barerepo 1mo
26
for _, c := range cases {
133728e barerepo 1mo
27
var got []string
133728e barerepo 1mo
28
for _, h := range hooksFor(cfg, c.kind) {
133728e barerepo 1mo
29
got = append(got, h.URL)
133728e barerepo 1mo
31
if len(got) != len(c.want) {
133728e barerepo 1mo
32
t.Errorf("%s went to %v, wanted %v", c.kind, got, c.want)
133728e barerepo 1mo
33
continue
133728e barerepo 1mo
35
for i := range got {
133728e barerepo 1mo
36
if got[i] != c.want[i] {
133728e barerepo 1mo
37
t.Errorf("%s went to %v, wanted %v", c.kind, got, c.want)
133728e barerepo 1mo
38
break
133728e barerepo 1mo
44
// A url with no scheme cannot be delivered to, and a hook with no url is a line somebody started.
133728e barerepo 1mo
45
func TestAHookWithNoURLIsNotDelivered(t *testing.T) {
133728e barerepo 1mo
46
cfg := repocfg.Config{Webhook: []repocfg.Webhook{{Events: []string{"push"}}}}
133728e barerepo 1mo
47
if got := hooksFor(cfg, store.Pushed); len(got) != 0 {
133728e barerepo 1mo
48
t.Errorf("a hook with no url was selected: %v", got)
133728e barerepo 1mo
52
// The file names a secret and the server holds the value, so a missing value must say so. 23.2.
133728e barerepo 1mo
53
func TestAMissingSecretIsAnErrorAndNotAnUnsignedDelivery(t *testing.T) {
133728e barerepo 1mo
54
_, err := hookSecret(repocfg.Webhook{URL: "https://x.example", SecretEnv: "BAREREPO_TEST_ABSENT"})
133728e barerepo 1mo
55
if err == nil {
133728e barerepo 1mo
56
t.Fatal("a named secret that is not set delivered anyway, unsigned")
133728e barerepo 1mo
59
t.Setenv("BAREREPO_TEST_PRESENT", "swordfish")
133728e barerepo 1mo
60
got, err := hookSecret(repocfg.Webhook{URL: "https://x.example", SecretEnv: "BAREREPO_TEST_PRESENT"})
133728e barerepo 1mo
61
if err != nil {
133728e barerepo 1mo
62
t.Fatal(err)
133728e barerepo 1mo
64
if got != "swordfish" {
133728e barerepo 1mo
65
t.Errorf("the secret read as %q", got)
133728e barerepo 1mo
68
// No secret named is a choice, not a mistake, so it delivers unsigned.
133728e barerepo 1mo
69
got, err = hookSecret(repocfg.Webhook{URL: "https://x.example"})
133728e barerepo 1mo
70
if err != nil || got != "" {
133728e barerepo 1mo
71
t.Errorf("an unnamed secret gave %q, %v", got, err)
133728e barerepo 1mo
75
func TestSplitRepo(t *testing.T) {
133728e barerepo 1mo
76
cases := []struct {
133728e barerepo 1mo
77
in string
133728e barerepo 1mo
78
owner, name string
133728e barerepo 1mo
79
ok bool
133728e barerepo 1mo
80
}{
133728e barerepo 1mo
81
{"john/johnbot", "john", "johnbot", true},
133728e barerepo 1mo
82
{"john", "", "", false},
133728e barerepo 1mo
83
{"/johnbot", "", "", false},
133728e barerepo 1mo
84
{"john/", "", "", false},
133728e barerepo 1mo
86
for _, c := range cases {
133728e barerepo 1mo
87
owner, name, ok := splitRepo(c.in)
133728e barerepo 1mo
88
if ok != c.ok || (ok && (owner != c.owner || name != c.name)) {
133728e barerepo 1mo
89
t.Errorf("%q gave %q %q %v", c.in, owner, name, ok)
133728e barerepo 1mo
94
// Chapter 23.1 calls a webhook the escape hatch, and a file that accepts a name nothing sends is not one.
133728e barerepo 1mo
95
func TestAHookNamingAnEventBarerepoNeverSendsSaysSo(t *testing.T) {
133728e barerepo 1mo
96
got := unknownEvents([]string{"push", "proposal.opened"})
133728e barerepo 1mo
97
if len(got) != 0 {
133728e barerepo 1mo
98
t.Errorf("real event names were reported as unknown: %v", got)
133728e barerepo 1mo
100
// The near misses are the ones that matter, because a reader's eye passes over them.
133728e barerepo 1mo
101
got = unknownEvents([]string{"push", "proposal.open", "run.succeeded", "thread.reply"})
133728e barerepo 1mo
102
want := []string{"proposal.open", "run.succeeded", "thread.reply"}
133728e barerepo 1mo
103
if len(got) != len(want) {
133728e barerepo 1mo
104
t.Fatalf("got %v, wanted %v", got, want)
133728e barerepo 1mo
105
}
133728e barerepo 1mo
106
for i := range want {
133728e barerepo 1mo
107
if got[i] != want[i] {
133728e barerepo 1mo
108
t.Fatalf("got %v, wanted %v", got, want)
133728e barerepo 1mo
109
}
133728e barerepo 1mo
110
}
133728e barerepo 1mo
111
// run.succeeded is the sharpest of them: chapter 19.1 names it only to say it is not an event.
133728e barerepo 1mo
112
if store.KnownKind("run.succeeded") {
133728e barerepo 1mo
113
t.Error("run.succeeded is an event kind, and chapter 19.1 says a green build is not news")
133728e barerepo 1mo
114
}
133728e barerepo 1mo
115
for _, k := range store.Kinds {
133728e barerepo 1mo
116
if !store.KnownKind(k) {
133728e barerepo 1mo
117
t.Errorf("%s is in the list and not known by the check that reads it", k)
133728e barerepo 1mo
118
}
133728e barerepo 1mo
119
}