| @@ -0,0 +1,73 @@ |
| |
1 | package httpd |
| |
2 | |
| |
3 | import ( |
| |
4 | "html/template" |
| |
5 | "strings" |
| |
6 | "testing" |
| |
7 | |
| |
8 | "gitbay.org/gitbay/internal/store" |
| |
9 | "gitbay.org/gitbay/internal/web" |
| |
10 | ) |
| |
11 | |
| |
12 | // issue close/reopen and mr close/draft allow the author as well as |
| |
13 | // writers (authorOrWrite), so an author without write access sees those |
| |
14 | // controls; review and merge stay with writers (#311). |
| |
15 | |
| |
16 | func renderIssueFor(t *testing.T, canEdit, canWrite bool) string { |
| |
17 | t.Helper() |
| |
18 | var sb strings.Builder |
| |
19 | if err := web.Render(&sb, "issue.html", struct { |
| |
20 | repoPage |
| |
21 | Issue store.Issue |
| |
22 | BodyHTML template.HTML |
| |
23 | Comments []renderedComment |
| |
24 | CanEdit bool |
| |
25 | CanWrite bool |
| |
26 | Milestones []store.Milestone |
| |
27 | Notice string |
| |
28 | LabelColors map[string]template.CSS |
| |
29 | Draft *draft |
| |
30 | Reactions map[int64]reactionBar |
| |
31 | }{repoPage: testRepoPage(), Issue: store.Issue{Number: 2, Title: "test issue", Author: "cmc", State: "open"}, |
| |
32 | CanEdit: canEdit, CanWrite: canWrite, Reactions: map[int64]reactionBar{0: {}}}); err != nil { |
| |
33 | t.Fatalf("render: %v", err) |
| |
34 | } |
| |
35 | return sb.String() |
| |
36 | } |
| |
37 | |
| |
38 | func TestIssueCloseShownToAuthorWithoutWrite(t *testing.T) { |
| |
39 | if !strings.Contains(renderIssueFor(t, true, false), "Close issue") { |
| |
40 | t.Error("the author cannot close their own issue from the web") |
| |
41 | } |
| |
42 | if strings.Contains(renderIssueFor(t, false, false), "Close issue") { |
| |
43 | t.Error("a reader who is not the author sees Close issue") |
| |
44 | } |
| |
45 | } |
| |
46 | |
| |
47 | func renderMRFor(t *testing.T, canEdit, canWrite bool) string { |
| |
48 | t.Helper() |
| |
49 | var sb strings.Builder |
| |
50 | if err := web.Render(&sb, "mr.html", mrPageData{ |
| |
51 | repoPage: testRepoPage(), MR: testMR("open"), View: "conversation", |
| |
52 | CanEdit: canEdit, CanWrite: canWrite, |
| |
53 | }); err != nil { |
| |
54 | t.Fatalf("render: %v", err) |
| |
55 | } |
| |
56 | return sb.String() |
| |
57 | } |
| |
58 | |
| |
59 | func TestMRCloseShownToAuthorWithoutWrite(t *testing.T) { |
| |
60 | author := renderMRFor(t, true, false) |
| |
61 | if !strings.Contains(author, "Close without merging") { |
| |
62 | t.Error("the author cannot close their own merge request from the web") |
| |
63 | } |
| |
64 | if !strings.Contains(author, "Convert to draft") { |
| |
65 | t.Error("the author cannot convert their own merge request to a draft") |
| |
66 | } |
| |
67 | if strings.Contains(author, "Approve") || strings.Contains(author, ">Merge</button>") { |
| |
68 | t.Error("the author without write access sees review or merge controls") |
| |
69 | } |
| |
70 | if strings.Contains(renderMRFor(t, false, false), "Close without merging") { |
| |
71 | t.Error("a reader who is not the author sees Close without merging") |
| |
72 | } |
| |
73 | } |