internal/httpd/mrslist_test.go
102 lines · 2879 bytes
1package httpd
2
3import (
4 "net/http"
5 "net/http/httptest"
6 "strings"
7 "testing"
8 "time"
9
10 "gitbay.org/gitbay/internal/config"
11 "gitbay.org/gitbay/internal/store"
12)
13
14// A repository's MR list offers the right next step by access level: a
15// writer gets "New merge request", a signed-in reader without push gets
16// a fork link, and a signed-out visitor gets a sign-in prompt (#270).
17func TestMRsListContributionHintByAccess(t *testing.T) {
18 st, err := store.Open(":memory:")
19 if err != nil {
20 t.Fatal(err)
21 }
22 defer st.Close()
23 if err := st.MigrateUp(); err != nil {
24 t.Fatal(err)
25 }
26 owner, err := st.CreateUser("alice", false)
27 if err != nil {
28 t.Fatal(err)
29 }
30 reader, err := st.CreateUser("bob", false)
31 if err != nil {
32 t.Fatal(err)
33 }
34 forker, err := st.CreateUser("carol", false)
35 if err != nil {
36 t.Fatal(err)
37 }
38 repoID, err := st.CreateRepo("user", owner, "app", "public")
39 if err != nil {
40 t.Fatal(err)
41 }
42 if _, err := st.CreateFork("user", forker, "app", "public", repoID); err != nil {
43 t.Fatal(err)
44 }
45
46 cfg := config.Default()
47 cfg.Web.Mode = "accounts"
48 s := New(cfg, st, nil)
49
50 // mrs reads the viewer through s.viewer(r), which resolves a
51 // session cookie (internal/httpd/accounts.go:37-47) rather than
52 // taking the viewer as a parameter the way a POST handler test
53 // does. Give a real viewer a real session; leave the request
54 // cookie-less for the anonymous case.
55 sessionFor := func(uid int64) *http.Cookie {
56 tok, hash, err := store.NewToken()
57 if err != nil {
58 t.Fatal(err)
59 }
60 if err := st.CreateWebSession(hash, uid, time.Hour); err != nil {
61 t.Fatal(err)
62 }
63 return s.sessionCookieFor(tok)
64 }
65
66 get := func(uid int64) string {
67 req := httptest.NewRequest("GET", "/alice/app/mrs", nil)
68 req.SetPathValue("owner", "alice")
69 req.SetPathValue("repo", "app")
70 if uid != 0 {
71 req.AddCookie(sessionFor(uid))
72 }
73 rr := httptest.NewRecorder()
74 s.mrs(rr, req)
75 return rr.Body.String()
76 }
77 anonymous := get(0)
78 if !strings.Contains(anonymous, "Sign in to propose a change") {
79 t.Errorf("signed-out visitor: missing sign-in prompt:\n%s", anonymous)
80 }
81 if strings.Contains(anonymous, "New merge request") {
82 t.Error("signed-out visitor should not see New merge request")
83 }
84
85 readerOut := get(reader)
86 if !strings.Contains(readerOut, "Fork this repository to propose a change") {
87 t.Errorf("reader without push: missing fork hint:\n%s", readerOut)
88 }
89
90 ownerOut := get(owner)
91 if !strings.Contains(ownerOut, "New merge request") {
92 t.Errorf("owner: missing New merge request link:\n%s", ownerOut)
93 }
94
95 forkerOut := get(forker)
96 if !strings.Contains(forkerOut, "New merge request") {
97 t.Errorf("reader with a writable fork: missing New merge request link:\n%s", forkerOut)
98 }
99 if strings.Contains(forkerOut, "Fork this repository to propose a change") {
100 t.Error("reader with a writable fork should not see the fork hint")
101 }
102}