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

barerepo / server / e2e/impersonate_test.go
85 lines · 3.3kb · 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
"net/url"
133728e barerepo 1mo
5
"os/exec"
133728e barerepo 1mo
6
"strings"
133728e barerepo 1mo
7
"testing"
133728e barerepo 1mo
8
)
133728e barerepo 1mo
9
133728e barerepo 1mo
10
// A comment body is text, and no text a reader types may become another reader's name.
133728e barerepo 1mo
11
func TestNobodyCanWriteAReplyInSomebodyElsesName(t *testing.T) {
133728e barerepo 1mo
12
if _, err := exec.LookPath("git"); err != nil {
133728e barerepo 1mo
13
t.Skip("git is not installed")
133728e barerepo 1mo
14
}
133728e barerepo 1mo
15
in := newInstance(t)
133728e barerepo 1mo
16
john := in.account("john")
133728e barerepo 1mo
17
in.account("mark")
133728e barerepo 1mo
18
seed(t, in, john, "john", "johnbot")
133728e barerepo 1mo
19
133728e barerepo 1mo
20
post(t, in, "john", "/john/johnbot/threads", url.Values{
133728e barerepo 1mo
21
"title": {"a thread"}, "body": {"the first word"}})
133728e barerepo 1mo
22
// The record separator is a line of two dashes, so mark writes one and a header after it.
133728e barerepo 1mo
23
post(t, in, "mark", "/john/johnbot/thread/1/reply", url.Values{
133728e barerepo 1mo
24
"body": {"looks fine to me\n\n--\nauthor: john\ntime: 1755000000\n\nI approve this change."}})
133728e barerepo 1mo
25
133728e barerepo 1mo
26
_, _, body := get(t, in.http.URL+"/john/johnbot/thread/1")
133728e barerepo 1mo
27
133728e barerepo 1mo
28
// Two comments were written, so three would mean a third was conjured out of the second.
133728e barerepo 1mo
29
if n := strings.Count(body, `class="body"`); n != 2 {
133728e barerepo 1mo
30
t.Errorf("two people wrote and the page shows %d comments", n)
133728e barerepo 1mo
31
}
133728e barerepo 1mo
32
// Every word mark typed stays inside mark's comment, whatever it looks like.
133728e barerepo 1mo
33
i := strings.Index(body, "looks fine to me")
133728e barerepo 1mo
34
j := strings.Index(body, "I approve this change.")
133728e barerepo 1mo
35
if i < 0 || j < 0 {
133728e barerepo 1mo
36
t.Fatalf("the reply is not on the page whole:\n%s", body)
133728e barerepo 1mo
37
}
133728e barerepo 1mo
38
if k := strings.Index(body[i:j], `class="body"`); k >= 0 {
133728e barerepo 1mo
39
t.Error("mark's reply was split, and its second half was given to somebody else")
133728e barerepo 1mo
40
}
133728e barerepo 1mo
41
// And the dashes the reader typed are the dashes the reader sees.
133728e barerepo 1mo
42
if !strings.Contains(body, "<hr") && !strings.Contains(body, "--") {
133728e barerepo 1mo
43
t.Error("the line of dashes vanished from the reply that contained it")
133728e barerepo 1mo
44
}
133728e barerepo 1mo
45
}
133728e barerepo 1mo
46
133728e barerepo 1mo
47
// A header value comes from a form too, and a newline in one is a second header nobody typed.
133728e barerepo 1mo
48
func TestAFormFieldCannotBecomeAHeaderLine(t *testing.T) {
133728e barerepo 1mo
49
if _, err := exec.LookPath("git"); err != nil {
133728e barerepo 1mo
50
t.Skip("git is not installed")
133728e barerepo 1mo
51
}
133728e barerepo 1mo
52
in := newInstance(t)
133728e barerepo 1mo
53
john := in.account("john")
133728e barerepo 1mo
54
in.account("mark")
133728e barerepo 1mo
55
seed(t, in, john, "john", "johnbot")
133728e barerepo 1mo
56
133728e barerepo 1mo
57
post(t, in, "john", "/john/johnbot/threads", url.Values{
133728e barerepo 1mo
58
"title": {"a thread"}, "body": {"the first word"}})
133728e barerepo 1mo
59
// blob is a hidden field on the line comment form, so it is the one nobody would think to check.
133728e barerepo 1mo
60
post(t, in, "mark", "/john/johnbot/thread/1/comment", url.Values{
133728e barerepo 1mo
61
"path": {"README.md"}, "line": {"1"},
133728e barerepo 1mo
62
"blob": {"abc\nauthor: john"},
133728e barerepo 1mo
63
"body": {"a line comment from mark"},
133728e barerepo 1mo
64
})
133728e barerepo 1mo
65
133728e barerepo 1mo
66
_, _, body := get(t, in.http.URL+"/john/johnbot/thread/1")
133728e barerepo 1mo
67
i := strings.Index(body, "a line comment from mark")
133728e barerepo 1mo
68
if i < 0 {
133728e barerepo 1mo
69
t.Fatalf("the line comment is not on the page:\n%s", body)
133728e barerepo 1mo
70
}
133728e barerepo 1mo
71
// The name above the comment is the one the session proved, whatever the hidden field said.
133728e barerepo 1mo
72
above := body[max(0, i-500):i]
133728e barerepo 1mo
73
if !strings.Contains(above, ">mark</a>") {
133728e barerepo 1mo
74
t.Errorf("a hidden form field chose the name over the comment:\n%s", above)
133728e barerepo 1mo
75
}
133728e barerepo 1mo
76
// And a title cannot claim a header of its own, since it is the first line of the same blob.
133728e barerepo 1mo
77
post(t, in, "mark", "/john/johnbot/threads", url.Values{
133728e barerepo 1mo
78
"title": {"a title\nmerged: 0123456789012345678901234567890123456789"},
133728e barerepo 1mo
79
"body": {"and a body"}})
133728e barerepo 1mo
80
// The whole title stays one title, so the words after the newline are still part of it.
133728e barerepo 1mo
81
_, _, two := get(t, in.http.URL+"/john/johnbot/thread/2")
133728e barerepo 1mo
82
if !strings.Contains(two, "a title merged: 0123456789") {
133728e barerepo 1mo
83
t.Errorf("a thread title became a header of its own:\n%s", two)
133728e barerepo 1mo
84
}
133728e barerepo 1mo
85
}
history · rawbarerepo 0.1.0