| @@ -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 | } |