-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathread_path_blacklist_test.go
More file actions
151 lines (126 loc) · 6.34 KB
/
Copy pathread_path_blacklist_test.go
File metadata and controls
151 lines (126 loc) · 6.34 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package thread
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/Mininglamp-OSS/octo-lib/common"
"github.com/Mininglamp-OSS/octo-lib/config"
"github.com/Mininglamp-OSS/octo-lib/pkg/util"
"github.com/Mininglamp-OSS/octo-lib/server"
"github.com/Mininglamp-OSS/octo-lib/testutil"
"github.com/Mininglamp-OSS/octo-server/modules/group"
"github.com/Mininglamp-OSS/octo-server/modules/user"
"github.com/Mininglamp-OSS/octo-server/pkg/errcode"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// setupReadPathBlacklistData 建一个父群(登录用户 testutil.UID 为正常成员、且是
// 子区创建者),返回 server/ctx/groupNo/子区 shortID。读路径门禁(list/get/
// listMembers/getThreadSimple)都查 testutil.UID 的父群 active 成员身份;测试通过
// 把它的 group_member.status 切到 Blacklist 来验证「normal → later blacklisted」
// 转换后读路径直接 deny(#345 复审 + ReviewBot P2-test 点名补强)。
func setupReadPathBlacklistData(t *testing.T) (*server.Server, *config.Context, string, string) {
t.Helper()
s, ctx := testutil.NewTestServer()
require.NoError(t, testutil.CleanAllTables(ctx))
userDB := user.NewDB(ctx)
require.NoError(t, userDB.Insert(&user.Model{UID: testutil.UID, Name: "登录用户", ShortNo: "sn_login"}))
groupNo := strings.ReplaceAll(util.GenerUUID(), "-", "")
groupDB := group.NewDB(ctx)
require.NoError(t, groupDB.Insert(&group.Model{GroupNo: groupNo, Name: "父群", Creator: testutil.UID, Status: 1, Version: 1}))
require.NoError(t, groupDB.InsertMember(&group.MemberModel{
GroupNo: groupNo, UID: testutil.UID, Role: group.MemberRoleCreator,
Status: int(common.GroupMemberStatusNormal), Version: 1, Vercode: util.GenerUUID(),
}))
// 由登录用户建一个子区作为读目标。
svc := NewService(ctx).(*Service)
th, err := svc.CreateThread(&CreateThreadReq{
GroupNo: groupNo, Name: "读目标子区", CreatorUID: testutil.UID, CreatorName: "登录用户",
})
require.NoError(t, err)
require.NotNil(t, th)
return s, ctx, groupNo, th.ShortID
}
func blacklistLoginUser(t *testing.T, ctx *config.Context, groupNo string) {
t.Helper()
_, err := ctx.DB().UpdateBySql(
"UPDATE group_member SET status=? WHERE group_no=? AND uid=?",
int(common.GroupMemberStatusBlacklist), groupNo, testutil.UID,
).Exec()
require.NoError(t, err)
}
func doGet(t *testing.T, s *server.Server, path string) *httptest.ResponseRecorder {
t.Helper()
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", path, nil)
req.Header.Set("token", testutil.Token)
s.GetRoute().ServeHTTP(w, req)
return w
}
// assertBlacklistDenied 收紧版 deny 断言(issue #353 P2):原先四处裸
// assert.NotEqual(200) 会把 404/500 等无关失败也当成"门禁生效"。deny 必须是
// 成员门禁产生的业务错误——legacy D14 兼容下 ResponseErrorL wire=400,且 body
// 文案是预期错误码的 DefaultMessage(testutil 服务器用默认 renderer,只透出
// msg/status,不带 i18n code id)。
func assertBlacklistDenied(t *testing.T, w *httptest.ResponseRecorder, wantMsg, hint string) {
t.Helper()
assert.Equal(t, http.StatusBadRequest, w.Code,
"%s(deny 走 ResponseErrorL,legacy D14 wire=400),body=%s", hint, w.Body.String())
assert.Contains(t, w.Body.String(), wantMsg,
"%s:deny 原因应是成员门禁而非其它失败", hint)
}
// TestReadPath_ListThreads_BlacklistTransition 列表读路径:normal 放行,
// 被拉黑后直接 deny。
func TestReadPath_ListThreads_BlacklistTransition(t *testing.T) {
s, ctx, groupNo, _ := setupReadPathBlacklistData(t)
path := "/v1/groups/" + groupNo + "/threads"
w := doGet(t, s, path)
assert.Equal(t, http.StatusOK, w.Code, "正常成员应能列出子区")
blacklistLoginUser(t, ctx, groupNo)
w = doGet(t, s, path)
assertBlacklistDenied(t, w, errcode.ErrThreadNotGroupMember.DefaultMessage, "被拉黑后列子区必须被拒")
}
// TestReadPath_GetThread_BlacklistTransition 详情读路径转换。
func TestReadPath_GetThread_BlacklistTransition(t *testing.T) {
s, ctx, groupNo, shortID := setupReadPathBlacklistData(t)
path := "/v1/groups/" + groupNo + "/threads/" + shortID
w := doGet(t, s, path)
assert.Equal(t, http.StatusOK, w.Code, "正常成员应能读子区详情")
blacklistLoginUser(t, ctx, groupNo)
w = doGet(t, s, path)
assertBlacklistDenied(t, w, errcode.ErrThreadNotGroupMember.DefaultMessage, "被拉黑后读详情必须被拒")
}
// TestReadPath_ListMembers_BlacklistTransition 成员列表读路径转换。
func TestReadPath_ListMembers_BlacklistTransition(t *testing.T) {
s, ctx, groupNo, shortID := setupReadPathBlacklistData(t)
path := "/v1/groups/" + groupNo + "/threads/" + shortID + "/members"
w := doGet(t, s, path)
assert.Equal(t, http.StatusOK, w.Code, "正常成员应能列子区成员")
blacklistLoginUser(t, ctx, groupNo)
w = doGet(t, s, path)
assertBlacklistDenied(t, w, errcode.ErrThreadNotGroupMember.DefaultMessage, "被拉黑后列成员必须被拒")
}
// TestReadPath_GetThreadSimple_BlacklistTransition 简化路由读路径转换。
func TestReadPath_GetThreadSimple_BlacklistTransition(t *testing.T) {
s, ctx, groupNo, shortID := setupReadPathBlacklistData(t)
path := "/v1/threads/" + shortID
w := doGet(t, s, path)
assert.Equal(t, http.StatusOK, w.Code, "正常成员应能读子区(简化路由)")
blacklistLoginUser(t, ctx, groupNo)
w = doGet(t, s, path)
assertBlacklistDenied(t, w, errcode.ErrThreadNotGroupMember.DefaultMessage, "被拉黑后读子区(简化路由)必须被拒")
}
// TestReadPath_ThreadMdGet_BlacklistTransition 子区 GROUP.md 读路径转换
// (issue #353 P2 点名补强:threadMdGet 返回 GROUP.md 正文,越权读面与
// 列表/详情同级,此前没有 blacklist 覆盖)。deny 码与其它读路径不同——
// threadMdGet 的非活跃成员走 ErrThreadPermissionDenied。
func TestReadPath_ThreadMdGet_BlacklistTransition(t *testing.T) {
s, ctx, groupNo, shortID := setupReadPathBlacklistData(t)
path := "/v1/groups/" + groupNo + "/threads/" + shortID + "/md"
w := doGet(t, s, path)
assert.Equal(t, http.StatusOK, w.Code, "正常成员应能读子区 GROUP.md(无内容时返回空 content)")
blacklistLoginUser(t, ctx, groupNo)
w = doGet(t, s, path)
assertBlacklistDenied(t, w, errcode.ErrThreadPermissionDenied.DefaultMessage, "被拉黑后读子区 GROUP.md 必须被拒")
}