126 lines
3.4 KiB
Go
126 lines
3.4 KiB
Go
package service
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/freefire/jiang13-bbs/model"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func staffDeletedComment() model.Comment {
|
|
uid := uint(7)
|
|
c := model.Comment{
|
|
ID: 11,
|
|
PostID: 22,
|
|
UserID: uid,
|
|
Content: "不该出现在公开 JSON",
|
|
Status: model.ContentStatusPublished,
|
|
DeletedBy: 9,
|
|
User: model.User{
|
|
ID: uid,
|
|
Username: "alice",
|
|
Nickname: "爱丽丝",
|
|
Avatar: "/uploads/avatars/alice.jpg",
|
|
},
|
|
}
|
|
c.DeletedAt = gorm.DeletedAt{Time: time.Now(), Valid: true}
|
|
c.CreatedAt = time.Now().Add(-time.Hour)
|
|
c.UpdatedAt = c.CreatedAt
|
|
return c
|
|
}
|
|
|
|
func marshalNode(t *testing.T, n CommentNode) map[string]any {
|
|
t.Helper()
|
|
b, err := json.Marshal(n)
|
|
if err != nil {
|
|
t.Fatalf("marshal: %v", err)
|
|
}
|
|
var raw map[string]any
|
|
if err := json.Unmarshal(b, &raw); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
return raw
|
|
}
|
|
|
|
func TestToCommentNodeHidesStaffDeletedAuthorFromPublic(t *testing.T) {
|
|
c := staffDeletedComment()
|
|
raw := marshalNode(t, toCommentNode(c, nil, false, 0, nil))
|
|
if _, ok := raw["user"]; ok {
|
|
t.Fatalf("公众 JSON 不应含 user: %v", raw["user"])
|
|
}
|
|
if _, ok := raw["user_id"]; ok {
|
|
t.Fatalf("公众 JSON 不应含 user_id: %v", raw["user_id"])
|
|
}
|
|
if raw["staff_deleted"] != true {
|
|
t.Fatalf("staff_deleted=%v", raw["staff_deleted"])
|
|
}
|
|
if s, _ := raw["content"].(string); s != "" {
|
|
t.Fatalf("公众不应看到正文: %q", s)
|
|
}
|
|
blob, _ := json.Marshal(raw)
|
|
for _, leak := range []string{"alice", "爱丽丝", "/uploads/avatars/alice.jpg"} {
|
|
if strings.Contains(string(blob), leak) {
|
|
t.Fatalf("公众 JSON 泄漏身份 %q: %s", leak, blob)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestToCommentNodeKeepsAuthorForCommenter(t *testing.T) {
|
|
c := staffDeletedComment()
|
|
raw := marshalNode(t, toCommentNode(c, nil, false, 7, nil))
|
|
if raw["user_id"] != float64(7) {
|
|
t.Fatalf("评论者应看到 user_id: %v", raw["user_id"])
|
|
}
|
|
user, ok := raw["user"].(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("评论者应看到 user")
|
|
}
|
|
if user["username"] != "alice" {
|
|
t.Fatalf("username=%v", user["username"])
|
|
}
|
|
if raw["content"] != "不该出现在公开 JSON" {
|
|
t.Fatalf("评论者应看到原文, got %v", raw["content"])
|
|
}
|
|
}
|
|
|
|
func TestToCommentNodeKeepsAuthorForModerator(t *testing.T) {
|
|
c := staffDeletedComment()
|
|
raw := marshalNode(t, toCommentNode(c, nil, true, 99, nil))
|
|
if raw["user_id"] != float64(7) {
|
|
t.Fatalf("版主应看到 user_id")
|
|
}
|
|
if _, ok := raw["user"]; !ok {
|
|
t.Fatal("版主应看到 user")
|
|
}
|
|
if raw["content"] != "不该出现在公开 JSON" {
|
|
t.Fatalf("版主应看到原文, got %v", raw["content"])
|
|
}
|
|
}
|
|
|
|
func TestToCommentNodeSelfDeleteKeepsAuthor(t *testing.T) {
|
|
c := staffDeletedComment()
|
|
c.DeletedBy = c.UserID
|
|
raw := marshalNode(t, toCommentNode(c, nil, false, 0, nil))
|
|
if raw["staff_deleted"] != nil && raw["staff_deleted"] != false {
|
|
t.Fatalf("自删不应标 staff_deleted: %v", raw["staff_deleted"])
|
|
}
|
|
if raw["user_id"] != float64(7) {
|
|
t.Fatalf("自删应保留作者: %v", raw["user_id"])
|
|
}
|
|
if s, _ := raw["content"].(string); s != "" {
|
|
t.Fatalf("公众不应看到自删正文: %q", s)
|
|
}
|
|
}
|
|
|
|
func TestToCommentNodeSelfDeleteKeepsContentForCommenter(t *testing.T) {
|
|
c := staffDeletedComment()
|
|
c.DeletedBy = c.UserID
|
|
raw := marshalNode(t, toCommentNode(c, nil, false, 7, nil))
|
|
if raw["content"] != "不该出现在公开 JSON" {
|
|
t.Fatalf("自删评论者应看到原文, got %v", raw["content"])
|
|
}
|
|
}
|