e369f398d8
- Added error_msg field to safewAPIResponse for better error descriptions. - Updated safewErrorDescription function to include error_msg in the output. - Introduced a new test to verify that error messages are included in Safew error descriptions. - Improved the polling mechanism in the Watcher to handle conflicts and ensure no overlapping polls occur.
128 lines
3.5 KiB
Go
128 lines
3.5 KiB
Go
package adapter
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestGroupsFromUpdatesKeepsGroupsDropsPrivate(t *testing.T) {
|
|
body := []byte(`{
|
|
"ok": true,
|
|
"result": [
|
|
{"update_id": 100000001, "message": {"chat": {"id": 10000778141, "type": "group", "title": "测试AI"}}},
|
|
{"update_id": 100000002, "message": {"chat": {"id": 11, "type": "private", "first_name": "u"}}},
|
|
{"update_id": 100000003, "my_chat_member": {"chat": {"id": 22, "type": "supergroup", "title": "SG", "username": "sg_name"}}}
|
|
]
|
|
}`)
|
|
chats, maxID, err := GroupsFromUpdates(body)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if maxID != 100000003 {
|
|
t.Fatalf("maxID=%d", maxID)
|
|
}
|
|
if len(chats) != 2 {
|
|
t.Fatalf("len=%d want 2: %#v", len(chats), chats)
|
|
}
|
|
byID := map[string]SafewChat{}
|
|
for _, c := range chats {
|
|
byID[c.ID] = c
|
|
}
|
|
g := byID["10000778141"]
|
|
if g.Type != "group" || g.Title != "测试AI" {
|
|
t.Fatalf("group: %#v", g)
|
|
}
|
|
raw, _ := json.Marshal(g)
|
|
var m map[string]any
|
|
_ = json.Unmarshal(raw, &m)
|
|
if _, ok := m["id"].(string); !ok {
|
|
t.Fatalf("id JSON type = %T, want string", m["id"])
|
|
}
|
|
sg := byID["22"]
|
|
if sg.Username == nil || *sg.Username != "sg_name" {
|
|
t.Fatalf("username: %#v", sg)
|
|
}
|
|
}
|
|
|
|
func TestFilterSafewChats(t *testing.T) {
|
|
chats := []SafewChat{
|
|
{ID: "10000778141", Type: "group", Title: "测试AI"},
|
|
{ID: "99", Type: "group", Title: "ops"},
|
|
}
|
|
got := FilterSafewChats(chats, "测试")
|
|
if len(got) != 1 || got[0].ID != "10000778141" {
|
|
t.Fatalf("%#v", got)
|
|
}
|
|
got = FilterSafewChats(chats, "10000778141")
|
|
if len(got) != 1 || got[0].Title != "测试AI" {
|
|
t.Fatalf("%#v", got)
|
|
}
|
|
got = FilterSafewChats(chats, "")
|
|
if len(got) != 2 {
|
|
t.Fatalf("empty q should keep all, got %d", len(got))
|
|
}
|
|
}
|
|
|
|
func TestPollGroupChatsSuccess(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path != "/bottok/getUpdates" {
|
|
t.Errorf("path=%s", r.URL.Path)
|
|
}
|
|
raw, _ := io.ReadAll(r.Body)
|
|
var body map[string]any
|
|
_ = json.Unmarshal(raw, &body)
|
|
if body["timeout"] != float64(0) {
|
|
t.Errorf("timeout=%v", body["timeout"])
|
|
}
|
|
if body["offset"] != float64(5) {
|
|
t.Errorf("offset=%v", body["offset"])
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write([]byte(`{"ok":true,"result":[{"update_id":10,"message":{"chat":{"id":10000778141,"type":"group","title":"测试AI"}}}]}`))
|
|
}))
|
|
defer srv.Close()
|
|
|
|
s := &SafeWSender{apiBase: srv.URL}
|
|
chats, next, err := s.PollGroupChats("tok", 5, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if next != 11 {
|
|
t.Fatalf("next=%d want 11", next)
|
|
}
|
|
if len(chats) != 1 || chats[0].ID != "10000778141" {
|
|
t.Fatalf("%#v", chats)
|
|
}
|
|
}
|
|
|
|
func TestSafewErrorDescriptionIncludesErrorMsg(t *testing.T) {
|
|
got := safewErrorDescription([]byte(`{"ok":false,"description":"BAD_REQUEST","error_msg":"Conflict: terminated by other getUpdates request"}`))
|
|
if !strings.Contains(got, "Conflict") {
|
|
t.Fatalf("got %q, want error_msg", got)
|
|
}
|
|
}
|
|
|
|
func TestPollGroupChatsUnauthorized(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
_, _ = w.Write([]byte(`{"ok":false,"error_code":401,"description":"BOT_TOKEN_INVALID"}`))
|
|
}))
|
|
defer srv.Close()
|
|
s := &SafeWSender{apiBase: srv.URL}
|
|
_, _, err := s.PollGroupChats("bad", 0, 0)
|
|
if err == nil {
|
|
t.Fatal("expected error")
|
|
}
|
|
ae, ok := err.(*SafewAuthError)
|
|
if !ok {
|
|
t.Fatalf("type %T %v", err, err)
|
|
}
|
|
if !strings.Contains(ae.Description, "BOT_TOKEN_INVALID") {
|
|
t.Fatalf("%q", ae.Description)
|
|
}
|
|
}
|