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

barerepo / server / e2e/feeds_test.go
148 lines · 4.8kb · 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
"context"
133728e barerepo 1mo
5
"io"
133728e barerepo 1mo
6
"net/http"
133728e barerepo 1mo
7
"os/exec"
133728e barerepo 1mo
8
"strings"
133728e barerepo 1mo
9
"testing"
133728e barerepo 1mo
10
133728e barerepo 1mo
11
"github.com/barerepo/server/internal/store"
133728e barerepo 1mo
12
)
133728e barerepo 1mo
13
133728e barerepo 1mo
14
// get reads a page and returns its status, content type and body.
133728e barerepo 1mo
15
func get(t *testing.T, url string) (int, string, string) {
133728e barerepo 1mo
16
t.Helper()
133728e barerepo 1mo
17
resp, err := http.Get(url)
133728e barerepo 1mo
18
if err != nil {
133728e barerepo 1mo
19
t.Fatal(err)
133728e barerepo 1mo
20
}
133728e barerepo 1mo
21
defer resp.Body.Close()
133728e barerepo 1mo
22
body, _ := io.ReadAll(resp.Body)
133728e barerepo 1mo
23
return resp.StatusCode, resp.Header.Get("Content-Type"), string(body)
133728e barerepo 1mo
24
}
133728e barerepo 1mo
25
133728e barerepo 1mo
26
// Chapter 39.4 tells a reader to paste these urls into a feed reader, so all three must answer.
133728e barerepo 1mo
27
func TestEveryPublicFeedInChapter39Answers(t *testing.T) {
133728e barerepo 1mo
28
if _, err := exec.LookPath("git"); err != nil {
133728e barerepo 1mo
29
t.Skip("git is not installed")
133728e barerepo 1mo
30
}
133728e barerepo 1mo
31
ctx := context.Background()
133728e barerepo 1mo
32
in := newInstance(t)
133728e barerepo 1mo
33
john := in.account("john")
133728e barerepo 1mo
34
seed(t, in, john, "john", "johnbot")
133728e barerepo 1mo
35
133728e barerepo 1mo
36
if err := in.db.Record(ctx, store.Event{Kind: store.ThreadOpened, Actor: "lisa",
133728e barerepo 1mo
37
Repo: "john/johnbot", Number: 47, Title: "the log page is slow"}); err != nil {
133728e barerepo 1mo
38
t.Fatal(err)
133728e barerepo 1mo
39
}
133728e barerepo 1mo
40
133728e barerepo 1mo
41
for _, path := range []string{"/john.atom", "/john/johnbot.atom", "/john/johnbot/threads.atom"} {
133728e barerepo 1mo
42
code, ctype, body := get(t, in.http.URL+path)
133728e barerepo 1mo
43
if code != http.StatusOK {
133728e barerepo 1mo
44
t.Errorf("%s answered %d, and chapter 39.4 hands this url out", path, code)
133728e barerepo 1mo
45
continue
133728e barerepo 1mo
46
}
133728e barerepo 1mo
47
if !strings.HasPrefix(ctype, "application/atom+xml") {
133728e barerepo 1mo
48
t.Errorf("%s came back as %q, which no feed reader will take", path, ctype)
133728e barerepo 1mo
49
}
133728e barerepo 1mo
50
if !strings.Contains(body, "<feed") {
133728e barerepo 1mo
51
t.Errorf("%s is not a feed:\n%s", path, body)
133728e barerepo 1mo
52
}
133728e barerepo 1mo
53
}
133728e barerepo 1mo
54
}
133728e barerepo 1mo
55
133728e barerepo 1mo
56
// The threads feed is the discussion alone, so a push must not appear in it. 19.5.
133728e barerepo 1mo
57
func TestTheThreadsFeedCarriesThreadsAndNotPushes(t *testing.T) {
133728e barerepo 1mo
58
if _, err := exec.LookPath("git"); err != nil {
133728e barerepo 1mo
59
t.Skip("git is not installed")
133728e barerepo 1mo
60
}
133728e barerepo 1mo
61
ctx := context.Background()
133728e barerepo 1mo
62
in := newInstance(t)
133728e barerepo 1mo
63
john := in.account("john")
133728e barerepo 1mo
64
seed(t, in, john, "john", "johnbot")
133728e barerepo 1mo
65
133728e barerepo 1mo
66
if err := in.db.Record(ctx, store.Event{Kind: store.ThreadOpened, Actor: "lisa",
133728e barerepo 1mo
67
Repo: "john/johnbot", Number: 47, Title: "the log page is slow"}); err != nil {
133728e barerepo 1mo
68
t.Fatal(err)
133728e barerepo 1mo
69
}
133728e barerepo 1mo
70
133728e barerepo 1mo
71
_, _, repoFeed := get(t, in.http.URL+"/john/johnbot.atom")
133728e barerepo 1mo
72
if !strings.Contains(repoFeed, "pushed") {
133728e barerepo 1mo
73
t.Errorf("the repository feed lost the push:\n%s", repoFeed)
133728e barerepo 1mo
74
}
133728e barerepo 1mo
75
if !strings.Contains(repoFeed, "opened thread 47") {
133728e barerepo 1mo
76
t.Errorf("the repository feed lost the thread:\n%s", repoFeed)
133728e barerepo 1mo
77
}
133728e barerepo 1mo
78
133728e barerepo 1mo
79
_, _, threadFeed := get(t, in.http.URL+"/john/johnbot/threads.atom")
133728e barerepo 1mo
80
if !strings.Contains(threadFeed, "opened thread 47") {
133728e barerepo 1mo
81
t.Errorf("the threads feed lost the thread:\n%s", threadFeed)
133728e barerepo 1mo
82
}
133728e barerepo 1mo
83
if strings.Contains(threadFeed, "pushed") {
133728e barerepo 1mo
84
t.Errorf("the threads feed carried a push:\n%s", threadFeed)
133728e barerepo 1mo
85
}
133728e barerepo 1mo
86
}
133728e barerepo 1mo
87
133728e barerepo 1mo
88
// A private repository has no public feed, and a 404 is what a stranger gets. 19.5.
133728e barerepo 1mo
89
func TestAPrivateRepositoryHasNoPublicFeed(t *testing.T) {
133728e barerepo 1mo
90
if _, err := exec.LookPath("git"); err != nil {
133728e barerepo 1mo
91
t.Skip("git is not installed")
133728e barerepo 1mo
92
}
133728e barerepo 1mo
93
in := newInstance(t)
133728e barerepo 1mo
94
john := in.account("john")
133728e barerepo 1mo
95
work := t.TempDir()
133728e barerepo 1mo
96
run(t, work, "git", "init", "-q", "-b", "master")
133728e barerepo 1mo
97
write(t, work, "config.go", "package main\n")
133728e barerepo 1mo
98
write(t, work, ".barerepo/config", "[repo]\nvisibility = \"private\"\n")
133728e barerepo 1mo
99
run(t, work, "git", "add", "-A")
133728e barerepo 1mo
100
run(t, work, "git", "commit", "-qm", "first")
133728e barerepo 1mo
101
run(t, work, "git", "push", "-q", in.url(john, "/john/secret"), "master")
133728e barerepo 1mo
102
133728e barerepo 1mo
103
for _, path := range []string{"/john/secret.atom", "/john/secret/threads.atom"} {
133728e barerepo 1mo
104
if code, _, _ := get(t, in.http.URL+path); code != http.StatusNotFound {
133728e barerepo 1mo
105
t.Errorf("%s answered %d to a stranger, wanted 404", path, code)
133728e barerepo 1mo
106
}
133728e barerepo 1mo
107
}
133728e barerepo 1mo
108
}
133728e barerepo 1mo
109
133728e barerepo 1mo
110
// The inbox page links to its own feed, and a link that can only fail is not a link. Chapter 19.5.
133728e barerepo 1mo
111
func TestTheInboxFeedOpensForTheReaderLookingAtIt(t *testing.T) {
133728e barerepo 1mo
112
if _, err := exec.LookPath("git"); err != nil {
133728e barerepo 1mo
113
t.Skip("git is not installed")
133728e barerepo 1mo
114
}
133728e barerepo 1mo
115
in := newInstance(t)
133728e barerepo 1mo
116
john := in.account("john")
133728e barerepo 1mo
117
seed(t, in, john, "john", "johnbot")
133728e barerepo 1mo
118
133728e barerepo 1mo
119
// A feed reader has no session and must still be refused without a token.
133728e barerepo 1mo
120
if code, _, _ := get(t, in.http.URL+"/inbox.atom"); code != http.StatusUnauthorized {
133728e barerepo 1mo
121
t.Errorf("an anonymous request for the inbox feed answered %d", code)
133728e barerepo 1mo
122
}
133728e barerepo 1mo
123
if code, _, _ := get(t, in.http.URL+"/inbox.atom?token=ft_live_nonsense"); code != http.StatusUnauthorized {
133728e barerepo 1mo
124
t.Errorf("a wrong token answered %d", code)
133728e barerepo 1mo
125
}
133728e barerepo 1mo
126
133728e barerepo 1mo
127
session, err := in.db.NewSession(t.Context(), "john")
133728e barerepo 1mo
128
if err != nil {
133728e barerepo 1mo
129
t.Fatal(err)
133728e barerepo 1mo
130
}
133728e barerepo 1mo
131
req, err := http.NewRequest(http.MethodGet, in.http.URL+"/inbox.atom", nil)
133728e barerepo 1mo
132
if err != nil {
133728e barerepo 1mo
133
t.Fatal(err)
133728e barerepo 1mo
134
}
133728e barerepo 1mo
135
req.AddCookie(&http.Cookie{Name: "barerepo_session", Value: session})
133728e barerepo 1mo
136
resp, err := http.DefaultClient.Do(req)
133728e barerepo 1mo
137
if err != nil {
133728e barerepo 1mo
138
t.Fatal(err)
133728e barerepo 1mo
139
}
133728e barerepo 1mo
140
defer resp.Body.Close()
133728e barerepo 1mo
141
body := readAll(t, resp)
133728e barerepo 1mo
142
if resp.StatusCode != http.StatusOK {
133728e barerepo 1mo
143
t.Fatalf("the reader's own inbox feed answered %d:\n%s", resp.StatusCode, body)
133728e barerepo 1mo
144
}
133728e barerepo 1mo
145
if !strings.Contains(body, "barerepo inbox for john") {
133728e barerepo 1mo
146
t.Errorf("the feed is not john's:\n%s", body)
133728e barerepo 1mo
147
}
133728e barerepo 1mo
148
}
history · rawbarerepo 0.1.0