286 lines
8.8 KiB
Go
286 lines
8.8 KiB
Go
package qq_obv11
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.yeij.top/AskaEth/Cyrene_v2/internal/channel/adapter"
|
|
)
|
|
|
|
func TestToUnifiedPrivateTextAndFace(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
a := NewAdapter(Config{})
|
|
raw := []byte(`{"post_type":"message","message_type":"private","time":1700000000,"self_id":100,"message_id":5,"user_id":200,"message":[{"type":"text","data":{"text":"hi "}},{"type":"face","data":{"id":1}}],"sender":{"user_id":200,"nickname":"Alice","role":"owner"}}`)
|
|
ev, err := parseEvent(raw)
|
|
if err != nil {
|
|
t.Fatalf("parseEvent error: %v", err)
|
|
}
|
|
msg := a.toUnified(ev, raw)
|
|
|
|
if msg.Platform != platformName {
|
|
t.Errorf("Platform = %q, want %q", msg.Platform, platformName)
|
|
}
|
|
if msg.ChannelType != adapter.ChannelDirect {
|
|
t.Errorf("ChannelType = %q, want %q", msg.ChannelType, adapter.ChannelDirect)
|
|
}
|
|
if msg.ChannelID != "200" || msg.SenderID != "200" {
|
|
t.Errorf("ChannelID/SenderID = %q/%q, want 200/200", msg.ChannelID, msg.SenderID)
|
|
}
|
|
if msg.SenderName != "Alice" {
|
|
t.Errorf("SenderName = %q, want Alice", msg.SenderName)
|
|
}
|
|
if msg.Content != "hi [表情]" {
|
|
t.Errorf("Content = %q, want %q", msg.Content, "hi [表情]")
|
|
}
|
|
if msg.ContentType != adapter.ContentText {
|
|
t.Errorf("ContentType = %q, want text", msg.ContentType)
|
|
}
|
|
if msg.MessageID != "5" {
|
|
t.Errorf("MessageID = %q, want 5", msg.MessageID)
|
|
}
|
|
if !msg.Timestamp.Equal(time.Unix(1700000000, 0)) {
|
|
t.Errorf("Timestamp = %v, want %v", msg.Timestamp, time.Unix(1700000000, 0))
|
|
}
|
|
if msg.Sender.Role != adapter.RoleOwner || !msg.Sender.IsOwner() {
|
|
t.Errorf("Sender.Role = %q, want owner", msg.Sender.Role)
|
|
}
|
|
}
|
|
|
|
func TestToUnifiedGroupWithMediaAndMention(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
a := NewAdapter(Config{Mode: "server"})
|
|
raw := []byte(`{"post_type":"message","message_type":"group","time":1700000001,"self_id":100,"message_id":9,"user_id":42,"group_id":123,"group_name":"Team","message":[{"type":"at","data":{"qq":"300"}},{"type":"text","data":{"text":" look "}},{"type":"image","data":{"file":"p.jpg","url":"http://cdn/p.jpg"}},{"type":"record","data":{"file":"v.amr"}}],"sender":{"user_id":42,"nickname":"Bob","card":"Bobby","role":"member"}}`)
|
|
ev, err := parseEvent(raw)
|
|
if err != nil {
|
|
t.Fatalf("parseEvent error: %v", err)
|
|
}
|
|
msg := a.toUnified(ev, raw)
|
|
|
|
if !msg.IsGroup() {
|
|
t.Fatal("expected group message")
|
|
}
|
|
if msg.ChannelType != adapter.ChannelGroup || msg.ChannelID != "123" || msg.GroupID != "123" {
|
|
t.Errorf("group fields = %q/%q/%q, want group/123/123", msg.ChannelType, msg.ChannelID, msg.GroupID)
|
|
}
|
|
if msg.GroupName != "Team" {
|
|
t.Errorf("GroupName = %q, want Team", msg.GroupName)
|
|
}
|
|
if msg.SenderName != "Bobby" {
|
|
t.Errorf("SenderName = %q, want Bobby (card)", msg.SenderName)
|
|
}
|
|
if msg.Sender.Role != adapter.RoleMember {
|
|
t.Errorf("Sender.Role = %q, want member", msg.Sender.Role)
|
|
}
|
|
if len(msg.Mentions) != 1 || msg.Mentions[0].UserID != "300" {
|
|
t.Errorf("Mentions = %+v, want one @300", msg.Mentions)
|
|
}
|
|
if len(msg.Media) != 2 {
|
|
t.Fatalf("Media len = %d, want 2", len(msg.Media))
|
|
}
|
|
if msg.Media[0].Kind != adapter.MediaImage || msg.Media[0].URL != "http://cdn/p.jpg" || msg.Media[0].Name != "p.jpg" {
|
|
t.Errorf("Media[0] = %+v, want image p.jpg", msg.Media[0])
|
|
}
|
|
if msg.Media[1].Kind != adapter.MediaVoice {
|
|
t.Errorf("Media[1].Kind = %q, want voice", msg.Media[1].Kind)
|
|
}
|
|
if msg.Content != "@300 look [图片][语音]" {
|
|
t.Errorf("Content = %q, want %q", msg.Content, "@300 look [图片][语音]")
|
|
}
|
|
}
|
|
|
|
func TestToUnifiedCQString(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
a := NewAdapter(Config{})
|
|
raw := []byte(`{"post_type":"message","message_type":"private","time":1700000002,"self_id":100,"message_id":7,"user_id":200,"message":"[CQ:at,qq=300]hello[CQ:image,file=a.jpg,url=http://cdn/a.jpg]","sender":{"user_id":200,"nickname":"Alice","role":""}}`)
|
|
ev, err := parseEvent(raw)
|
|
if err != nil {
|
|
t.Fatalf("parseEvent error: %v", err)
|
|
}
|
|
msg := a.toUnified(ev, raw)
|
|
|
|
if msg.Content != "@300hello[图片]" {
|
|
t.Errorf("Content = %q, want %q", msg.Content, "@300hello[图片]")
|
|
}
|
|
if len(msg.Mentions) != 1 || msg.Mentions[0].UserID != "300" {
|
|
t.Errorf("Mentions = %+v, want @300", msg.Mentions)
|
|
}
|
|
if len(msg.Media) != 1 || msg.Media[0].Kind != adapter.MediaImage || msg.Media[0].URL != "http://cdn/a.jpg" {
|
|
t.Errorf("Media = %+v, want image a.jpg", msg.Media)
|
|
}
|
|
if msg.Sender.Role != adapter.RoleUnknown {
|
|
t.Errorf("Sender.Role = %q, want unknown for empty role", msg.Sender.Role)
|
|
}
|
|
}
|
|
|
|
func TestContentTypePureImage(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
a := NewAdapter(Config{})
|
|
raw := []byte(`{"post_type":"message","message_type":"private","time":1700000003,"self_id":100,"message_id":8,"user_id":200,"message":[{"type":"image","data":{"file":"a.jpg"}}],"sender":{"user_id":200,"nickname":"Alice"}}`)
|
|
ev, err := parseEvent(raw)
|
|
if err != nil {
|
|
t.Fatalf("parseEvent error: %v", err)
|
|
}
|
|
msg := a.toUnified(ev, raw)
|
|
|
|
if msg.ContentType != adapter.ContentImage {
|
|
t.Errorf("ContentType = %q, want image", msg.ContentType)
|
|
}
|
|
if len(msg.Media) != 1 || msg.Media[0].Kind != adapter.MediaImage {
|
|
t.Errorf("Media = %+v, want one image", msg.Media)
|
|
}
|
|
}
|
|
|
|
func TestOutboundSegmentsTextAndImage(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
segs, err := outboundSegments(adapter.UnifiedMessage{
|
|
Content: "pong",
|
|
Media: []adapter.Media{{Kind: adapter.MediaImage, URL: "http://cdn/x.jpg"}},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("outboundSegments error: %v", err)
|
|
}
|
|
if len(segs) != 2 {
|
|
t.Fatalf("segs len = %d, want 2", len(segs))
|
|
}
|
|
if segs[0].Type != "text" || segs[0].Data["text"] != "pong" {
|
|
t.Errorf("segs[0] = %+v, want text pong", segs[0])
|
|
}
|
|
if segs[1].Type != "image" || segs[1].Data["file"] != "http://cdn/x.jpg" {
|
|
t.Errorf("segs[1] = %+v, want image", segs[1])
|
|
}
|
|
}
|
|
|
|
func TestOutboundSegmentsEmptyErrors(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := outboundSegments(adapter.UnifiedMessage{})
|
|
if err == nil {
|
|
t.Error("empty message: expected error, got nil")
|
|
}
|
|
}
|
|
|
|
func TestResolveTargetGroupAndPrivate(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
msg adapter.UnifiedMessage
|
|
wantType string
|
|
wantUser int64
|
|
wantGroup int64
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "group",
|
|
msg: adapter.UnifiedMessage{ChannelType: adapter.ChannelGroup, GroupID: "123", Content: "x"},
|
|
wantType: "group",
|
|
wantGroup: 123,
|
|
},
|
|
{
|
|
name: "private by channel id",
|
|
msg: adapter.UnifiedMessage{ChannelType: adapter.ChannelDirect, ChannelID: "200", Content: "x"},
|
|
wantType: "private",
|
|
wantUser: 200,
|
|
},
|
|
{
|
|
name: "private by sender",
|
|
msg: adapter.UnifiedMessage{ChannelType: adapter.ChannelDirect, SenderID: "300", Content: "x"},
|
|
wantType: "private",
|
|
wantUser: 300,
|
|
},
|
|
{
|
|
name: "group missing target",
|
|
msg: adapter.UnifiedMessage{ChannelType: adapter.ChannelGroup, Content: "x"},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "private missing target",
|
|
msg: adapter.UnifiedMessage{ChannelType: adapter.ChannelDirect, Content: "x"},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
gotType, gotUser, gotGroup, err := resolveTarget(tt.msg)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Fatalf("resolveTarget error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
if err != nil {
|
|
return
|
|
}
|
|
if gotType != tt.wantType || gotUser != tt.wantUser || gotGroup != tt.wantGroup {
|
|
t.Errorf("resolveTarget = %q/%d/%d, want %q/%d/%d", gotType, gotUser, gotGroup, tt.wantType, tt.wantUser, tt.wantGroup)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRoleFromOneBot(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
raw string
|
|
want adapter.Role
|
|
}{
|
|
{"owner", adapter.RoleOwner},
|
|
{"admin", adapter.RoleMember},
|
|
{"member", adapter.RoleMember},
|
|
{"", adapter.RoleUnknown},
|
|
{"bogus", adapter.RoleUnknown},
|
|
}
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.raw, func(t *testing.T) {
|
|
t.Parallel()
|
|
if got := roleFromOneBot(tt.raw); got != tt.want {
|
|
t.Errorf("roleFromOneBot(%q) = %q, want %q", tt.raw, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBuildSendReq(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
segs := []obSegment{{Type: "text", Data: map[string]any{"text": "hi"}}}
|
|
payload, err := buildSendReq("group", 0, 123, segs, "echo_1")
|
|
if err != nil {
|
|
t.Fatalf("buildSendReq error: %v", err)
|
|
}
|
|
if string(payload) == "" {
|
|
t.Fatal("empty payload")
|
|
}
|
|
}
|
|
|
|
func TestListChannelsCachesGroups(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
a := NewAdapter(Config{Mode: "server"})
|
|
a.rememberGroup("123", "Team")
|
|
a.rememberGroup("456", "Gamer")
|
|
|
|
channels, err := a.ListChannels(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("ListChannels error: %v", err)
|
|
}
|
|
if len(channels) != 2 {
|
|
t.Fatalf("channels len = %d, want 2", len(channels))
|
|
}
|
|
byID := map[string]adapter.ChannelInfo{}
|
|
for _, c := range channels {
|
|
byID[c.ChannelID] = c
|
|
}
|
|
if c := byID["123"]; c.GroupName != "Team" || c.ChannelType != adapter.ChannelGroup || c.GroupID != "123" {
|
|
t.Errorf("channel 123 = %+v", c)
|
|
}
|
|
}
|