File view with blame information shown in the left gutter beside each line.

barerepo / server / e2e/runner_setup_test.go
197 lines · 6.1kb · 133728eaa05486504991b230f9d4c7e986b7defc
log files threads runs releases config jump to file t
133728e barerepo 1mo
1
package e2e
133728e barerepo 1mo
2
133728e barerepo 1mo
3
import (
133728e barerepo 1mo
4
"io"
133728e barerepo 1mo
5
"net/http"
133728e barerepo 1mo
6
"os/exec"
133728e barerepo 1mo
7
"strings"
133728e barerepo 1mo
8
"testing"
133728e barerepo 1mo
9
133728e barerepo 1mo
10
bartoken "github.com/barerepo/server/internal/token"
133728e barerepo 1mo
11
)
133728e barerepo 1mo
12
133728e barerepo 1mo
13
// readAll drains a response body and returns it as a string.
133728e barerepo 1mo
14
func readAll(t *testing.T, resp *http.Response) string {
133728e barerepo 1mo
15
t.Helper()
133728e barerepo 1mo
16
body, err := io.ReadAll(resp.Body)
133728e barerepo 1mo
17
if err != nil {
133728e barerepo 1mo
18
t.Fatal(err)
133728e barerepo 1mo
19
}
133728e barerepo 1mo
20
return string(body)
133728e barerepo 1mo
21
}
133728e barerepo 1mo
22
133728e barerepo 1mo
23
// Chapter 24: three commands, all visible at once, token inside. A button to reveal them is a step.
133728e barerepo 1mo
24
func TestAddingARunnerIsOnePageAndNoClicks(t *testing.T) {
133728e barerepo 1mo
25
if _, err := exec.LookPath("git"); err != nil {
133728e barerepo 1mo
26
t.Skip("git is not installed")
133728e barerepo 1mo
27
}
133728e barerepo 1mo
28
in := newInstance(t)
133728e barerepo 1mo
29
john := in.account("john")
133728e barerepo 1mo
30
seed(t, in, john, "john", "johnbot")
133728e barerepo 1mo
31
133728e barerepo 1mo
32
token, err := in.db.NewSession(t.Context(), "john")
133728e barerepo 1mo
33
if err != nil {
133728e barerepo 1mo
34
t.Fatal(err)
133728e barerepo 1mo
35
}
133728e barerepo 1mo
36
req, err := http.NewRequest(http.MethodGet, in.http.URL+"/john/johnbot/runners/new", nil)
133728e barerepo 1mo
37
if err != nil {
133728e barerepo 1mo
38
t.Fatal(err)
133728e barerepo 1mo
39
}
133728e barerepo 1mo
40
req.AddCookie(&http.Cookie{Name: "barerepo_session", Value: token})
133728e barerepo 1mo
41
resp, err := http.DefaultClient.Do(req)
133728e barerepo 1mo
42
if err != nil {
133728e barerepo 1mo
43
t.Fatal(err)
133728e barerepo 1mo
44
}
133728e barerepo 1mo
45
defer resp.Body.Close()
133728e barerepo 1mo
46
body := readAll(t, resp)
133728e barerepo 1mo
47
133728e barerepo 1mo
48
if strings.Contains(body, "new runner token") {
133728e barerepo 1mo
49
t.Error("the page asks for a click before it shows the commands, which chapter 24 forbids")
133728e barerepo 1mo
50
}
133728e barerepo 1mo
51
for _, want := range []string{"runner.sh", "runner.ps1", "barerepo-runner ", "rt_live_"} {
133728e barerepo 1mo
52
if !strings.Contains(body, want) {
133728e barerepo 1mo
53
t.Errorf("the page is missing %q:\n%s", want, body)
133728e barerepo 1mo
54
}
133728e barerepo 1mo
55
}
133728e barerepo 1mo
56
// The three facts chapter 24 asks for, in the mockup's words.
133728e barerepo 1mo
57
for _, want := range []string{"dials out", "scopes to this repo", "shown once"} {
133728e barerepo 1mo
58
if !strings.Contains(body, want) {
133728e barerepo 1mo
59
t.Errorf("the page does not say %q", want)
133728e barerepo 1mo
60
}
133728e barerepo 1mo
61
}
133728e barerepo 1mo
62
133728e barerepo 1mo
63
// A reload must not revoke the line the reader just copied.
133728e barerepo 1mo
64
first := tokenIn(t, body)
133728e barerepo 1mo
65
req2, _ := http.NewRequest(http.MethodGet, in.http.URL+"/john/johnbot/runners/new", nil)
133728e barerepo 1mo
66
req2.AddCookie(&http.Cookie{Name: "barerepo_session", Value: token})
133728e barerepo 1mo
67
resp2, err := http.DefaultClient.Do(req2)
133728e barerepo 1mo
68
if err != nil {
133728e barerepo 1mo
69
t.Fatal(err)
133728e barerepo 1mo
70
}
133728e barerepo 1mo
71
defer resp2.Body.Close()
133728e barerepo 1mo
72
readAll(t, resp2)
133728e barerepo 1mo
73
133728e barerepo 1mo
74
if _, err := in.db.AccountForToken(t.Context(), bartoken.Runner, first); err != nil {
133728e barerepo 1mo
75
t.Errorf("reloading the page revoked the token the reader had already copied: %v", err)
133728e barerepo 1mo
76
}
133728e barerepo 1mo
77
}
133728e barerepo 1mo
78
133728e barerepo 1mo
79
func tokenIn(t *testing.T, body string) string {
133728e barerepo 1mo
80
t.Helper()
133728e barerepo 1mo
81
i := strings.Index(body, "rt_live_")
133728e barerepo 1mo
82
if i < 0 {
133728e barerepo 1mo
83
t.Fatal("no runner token on the page")
133728e barerepo 1mo
84
}
133728e barerepo 1mo
85
rest := body[i:]
133728e barerepo 1mo
86
end := strings.IndexAny(rest, "< \n")
133728e barerepo 1mo
87
if end < 0 {
133728e barerepo 1mo
88
t.Fatal("the token does not end")
133728e barerepo 1mo
89
}
133728e barerepo 1mo
90
return rest[:end]
133728e barerepo 1mo
91
}
133728e barerepo 1mo
92
133728e barerepo 1mo
93
// Chapter 24 puts a description on the new repository form, and only the pasted block can store it.
133728e barerepo 1mo
94
func TestTheNewRepositoryDescriptionReachesThePasteBlock(t *testing.T) {
133728e barerepo 1mo
95
if _, err := exec.LookPath("git"); err != nil {
133728e barerepo 1mo
96
t.Skip("git is not installed")
133728e barerepo 1mo
97
}
133728e barerepo 1mo
98
in := newInstance(t)
133728e barerepo 1mo
99
in.account("john")
133728e barerepo 1mo
100
133728e barerepo 1mo
101
session, err := in.db.NewSession(t.Context(), "john")
133728e barerepo 1mo
102
if err != nil {
133728e barerepo 1mo
103
t.Fatal(err)
133728e barerepo 1mo
104
}
133728e barerepo 1mo
105
form := "name=johnbot&description=irc+bot+that+refuses+to+leave&visibility=public&default_branch=master"
133728e barerepo 1mo
106
req, err := http.NewRequest(http.MethodPost, in.http.URL+"/new", strings.NewReader(form))
133728e barerepo 1mo
107
if err != nil {
133728e barerepo 1mo
108
t.Fatal(err)
133728e barerepo 1mo
109
}
133728e barerepo 1mo
110
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
133728e barerepo 1mo
111
req.AddCookie(&http.Cookie{Name: "barerepo_session", Value: session})
133728e barerepo 1mo
112
client := &http.Client{CheckRedirect: func(*http.Request, []*http.Request) error {
133728e barerepo 1mo
113
return http.ErrUseLastResponse
133728e barerepo 1mo
114
}}
133728e barerepo 1mo
115
resp, err := client.Do(req)
133728e barerepo 1mo
116
if err != nil {
133728e barerepo 1mo
117
t.Fatal(err)
133728e barerepo 1mo
118
}
133728e barerepo 1mo
119
resp.Body.Close()
133728e barerepo 1mo
120
if resp.StatusCode != http.StatusFound {
133728e barerepo 1mo
121
t.Fatalf("creating answered %d", resp.StatusCode)
133728e barerepo 1mo
122
}
133728e barerepo 1mo
123
133728e barerepo 1mo
124
// The repository is private until the config is pushed, so the empty page needs the session.
133728e barerepo 1mo
125
page, err := http.NewRequest(http.MethodGet, in.http.URL+resp.Header.Get("Location"), nil)
133728e barerepo 1mo
126
if err != nil {
133728e barerepo 1mo
127
t.Fatal(err)
133728e barerepo 1mo
128
}
133728e barerepo 1mo
129
page.AddCookie(&http.Cookie{Name: "barerepo_session", Value: session})
133728e barerepo 1mo
130
shown, err := http.DefaultClient.Do(page)
133728e barerepo 1mo
131
if err != nil {
133728e barerepo 1mo
132
t.Fatal(err)
133728e barerepo 1mo
133
}
133728e barerepo 1mo
134
defer shown.Body.Close()
133728e barerepo 1mo
135
if shown.StatusCode != http.StatusOK {
133728e barerepo 1mo
136
t.Fatalf("the empty page answered %d", shown.StatusCode)
133728e barerepo 1mo
137
}
133728e barerepo 1mo
138
body := readAll(t, shown)
133728e barerepo 1mo
139
if !strings.Contains(body, `description = "irc bot that refuses to leave"`) {
133728e barerepo 1mo
140
t.Errorf("the description is not in the block the reader pastes:\n%s", body)
133728e barerepo 1mo
141
}
133728e barerepo 1mo
142
// A quoted heredoc passes every character through, which printf with escapes does not.
133728e barerepo 1mo
143
if !strings.Contains(body, "&lt;&lt;'EOF'") {
133728e barerepo 1mo
144
t.Errorf("the block is not a quoted heredoc, so a quote in the description would break it")
133728e barerepo 1mo
145
}
133728e barerepo 1mo
146
if !strings.Contains(body, `visibility = "public"`) {
133728e barerepo 1mo
147
t.Errorf("the block does not carry the visibility the form was told:\n%s", body)
133728e barerepo 1mo
148
}
133728e barerepo 1mo
149
}
133728e barerepo 1mo
150
133728e barerepo 1mo
151
// The block writes the file, so it has to write the visibility that was asked for and not a default.
133728e barerepo 1mo
152
func TestADescribedPrivateRepositoryStaysPrivateInThePasteBlock(t *testing.T) {
133728e barerepo 1mo
153
if _, err := exec.LookPath("git"); err != nil {
133728e barerepo 1mo
154
t.Skip("git is not installed")
133728e barerepo 1mo
155
}
133728e barerepo 1mo
156
in := newInstance(t)
133728e barerepo 1mo
157
in.account("john")
133728e barerepo 1mo
158
133728e barerepo 1mo
159
session, err := in.db.NewSession(t.Context(), "john")
133728e barerepo 1mo
160
if err != nil {
133728e barerepo 1mo
161
t.Fatal(err)
133728e barerepo 1mo
162
}
133728e barerepo 1mo
163
form := "name=johnbot&description=irc+bot&visibility=private&default_branch=master"
133728e barerepo 1mo
164
req, err := http.NewRequest(http.MethodPost, in.http.URL+"/new", strings.NewReader(form))
133728e barerepo 1mo
165
if err != nil {
133728e barerepo 1mo
166
t.Fatal(err)
133728e barerepo 1mo
167
}
133728e barerepo 1mo
168
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
133728e barerepo 1mo
169
req.AddCookie(&http.Cookie{Name: "barerepo_session", Value: session})
133728e barerepo 1mo
170
client := &http.Client{CheckRedirect: func(*http.Request, []*http.Request) error {
133728e barerepo 1mo
171
return http.ErrUseLastResponse
133728e barerepo 1mo
172
}}
133728e barerepo 1mo
173
resp, err := client.Do(req)
133728e barerepo 1mo
174
if err != nil {
133728e barerepo 1mo
175
t.Fatal(err)
133728e barerepo 1mo
176
}
133728e barerepo 1mo
177
resp.Body.Close()
133728e barerepo 1mo
178
133728e barerepo 1mo
179
page, err := http.NewRequest(http.MethodGet, in.http.URL+resp.Header.Get("Location"), nil)
133728e barerepo 1mo
180
if err != nil {
133728e barerepo 1mo
181
t.Fatal(err)
133728e barerepo 1mo
182
}
133728e barerepo 1mo
183
page.AddCookie(&http.Cookie{Name: "barerepo_session", Value: session})
133728e barerepo 1mo
184
shown, err := http.DefaultClient.Do(page)
133728e barerepo 1mo
185
if err != nil {
133728e barerepo 1mo
186
t.Fatal(err)
133728e barerepo 1mo
187
}
133728e barerepo 1mo
188
defer shown.Body.Close()
133728e barerepo 1mo
189
body := readAll(t, shown)
133728e barerepo 1mo
190
133728e barerepo 1mo
191
if !strings.Contains(body, `visibility = "private"`) {
133728e barerepo 1mo
192
t.Errorf("a repository asked to be private is told to write public:\n%s", body)
133728e barerepo 1mo
193
}
133728e barerepo 1mo
194
if strings.Contains(body, `visibility = "public"`) {
133728e barerepo 1mo
195
t.Errorf("the block writes public for a repository that asked to be private:\n%s", body)
133728e barerepo 1mo
196
}
133728e barerepo 1mo
197
}
history · rawbarerepo 0.1.0