~gitpocket/gitpocket

8
ca96986a2b8a683049db1edfcd185b75870b05ee
mainfeed-discovery
gitpocket/forge/feature_test.go -rw-r--r--3.4 KiB ViewLogBlameView rawPermalink ca96986a2b feat(moderation): add reports, account blocks and hourly thread limits 20 hours ago
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package forge

import (
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"testing"
)

func TestModeration(t *testing.T) {
	s, h := testServer(t)
	alice, _ := s.store.CreateUser("alice", "correct horse")
	bob, _ := s.store.CreateUser("bob", "correct horse")
	boss, _ := s.store.CreateUser("boss", "correct horse")
	s.store.SetAdmin("boss", true)
	s.store.CreateRepo(alice, "proj", "", Public, "")
	s.store.CreateRepo(alice, "hidden", "", Private, "")
	a, _ := s.store.CreateSession(alice.ID)
	b, _ := s.store.CreateSession(bob.ID)
	admin, _ := s.store.CreateSession(boss.ID)

	if w := post(h, "/~alice/proj/issues/new", url.Values{"title": {"spam"}, "body": {"x"}}, b); w.Code != http.StatusSeeOther {
		t.Fatalf("issue: %d", w.Code)
	}
	if w := post(h, "/report", url.Values{"kind": {"issue"}, "target": {"alice/proj#1"}, "reason": {"spam"}}, a); w.Code != 200 {
		t.Fatalf("report: %d %s", w.Code, w.Body.String())
	}
	if w := post(h, "/report", url.Values{"kind": {"issue"}, "target": {"alice/proj#1"}, "reason": {"spam"}}, a); w.Code != 400 {
		t.Error("duplicate report accepted")
	}
	if w := post(h, "/report", url.Values{"kind": {"repo"}, "target": {"alice/hidden"}, "reason": {"x"}}, b); w.Code != 404 {
		t.Error("report reveals a private repository")
	}
	if w := get(h, "/admin?s=reports", admin); !strings.Contains(w.Body.String(), "alice/proj#1") {
		t.Error("report missing from admin")
	}
	if w := get(h, "/admin?s=reports", b); w.Code == 200 {
		t.Error("non-admin sees reports")
	}
	rep := s.store.Reports("open")[0]
	if w := post(h, "/admin", url.Values{"s": {"reports"}, "action": {"moderate"}, "report": {itoa(rep.ID)}, "do": {"ban"}}, admin); strings.Contains(w.Header().Get("Location"), "error") {
		t.Fatalf("ban: %s", w.Header().Get("Location"))
	}
	if !s.store.IsBanned(bob.ID) || s.store.IsBanned(alice.ID) {
		t.Error("ban hit the wrong account")
	}
	s.store.SetBanned("bob", false)
	b, _ = s.store.CreateSession(bob.ID)
	if len(s.store.Reports("open")) != 0 {
		t.Error("report still open")
	}

	if w := post(h, "/block", url.Values{"name": {"bob"}}, a); w.Code != http.StatusSeeOther {
		t.Fatalf("block: %d", w.Code)
	}
	if w := post(h, "/~alice/proj/issues/new", url.Values{"title": {"again"}}, b); w.Code != 403 {
		t.Errorf("blocked user opened an issue: %d", w.Code)
	}
	if w := post(h, "/~alice/proj/issues/1/comment", url.Values{"body": {"hi"}}, b); w.Code != 403 {
		t.Errorf("blocked user commented: %d", w.Code)
	}
	if w := post(h, "/~alice/proj/star", nil, b); w.Code != 403 {
		t.Errorf("blocked user starred: %d", w.Code)
	}
	if w := post(h, "/~alice/follow", nil, b); w.Code != 403 {
		t.Errorf("blocked user followed: %d", w.Code)
	}
	if w := post(h, "/~alice/proj/fork", nil, b); w.Code != 403 {
		t.Errorf("blocked user forked: %d", w.Code)
	}
	if !strings.Contains(get(h, "/settings", a).Body.String(), "~bob") {
		t.Error("blocked list missing from settings")
	}
	post(h, "/block", url.Values{"name": {"bob"}, "action": {"unblock"}}, a)
	if s.store.Blocked(alice.ID, bob.ID) {
		t.Error("unblock failed")
	}
	if w := post(h, "/block", url.Values{"name": {"bob"}}, b); w.Code != 400 {
		t.Error("blocked yourself")
	}

	for i := 0; i < threadsPerHour; i++ {
		s.store.CreateIssue(Repo{ID: 1}, bob, "t", "")
	}
	if w := post(h, "/~alice/proj/issues/new", url.Values{"title": {"flood"}}, b); w.Code != 429 {
		t.Errorf("issue flood not limited: %d", w.Code)
	}
}

func itoa(n int64) string { return strconv.FormatInt(n, 10) }