mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-10-03 07:43:58 +00:00
refactor: remove IO route mapping, add HTTP API tests, system prompt update
This commit is contained in:
@ -105,16 +105,19 @@ func (c *Client) reconnect() {
|
||||
|
||||
func (c *Client) readLoop() {
|
||||
defer c.connected.Store(false)
|
||||
defer c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
defer func() {
|
||||
if c.conn != nil {
|
||||
c.conn.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
_, message, err := c.conn.ReadMessage()
|
||||
c.mu.Lock()
|
||||
conn := c.conn
|
||||
c.mu.Unlock()
|
||||
|
||||
if conn == nil {
|
||||
log.Printf("[onebot] read loop: not connected")
|
||||
go c.reconnect()
|
||||
return
|
||||
}
|
||||
|
||||
_, message, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
log.Printf("[onebot] read error: %v", err)
|
||||
go c.reconnect()
|
||||
@ -125,7 +128,10 @@ func (c *Client) readLoop() {
|
||||
var resp ActionResponse
|
||||
if err := json.Unmarshal(message, &resp); err == nil && resp.Echo != "" {
|
||||
if ch, ok := c.pending.Load(resp.Echo); ok {
|
||||
ch.(chan *ActionResponse) <- &resp
|
||||
select {
|
||||
case ch.(chan *ActionResponse) <- &resp:
|
||||
default:
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@ -189,9 +189,7 @@ func (d *Device) handleEvent(evt *Event) {
|
||||
payload["label"] = fmt.Sprintf("private:%d", evt.UserID)
|
||||
}
|
||||
|
||||
d.iom.InjectText(source, text)
|
||||
// 同时注册输出路由:QQ 消息默认回复到 QQ 通道
|
||||
d.iom.RegisterOutputRoute(source, d.name)
|
||||
d.iom.InjectTextTo(source, d.name, text)
|
||||
|
||||
case "notice":
|
||||
log.Printf("[onebot] notice from %s: type=%s", d.name, evt.NoticeType)
|
||||
|
||||
165
internal/onebot/types_test.go
Normal file
165
internal/onebot/types_test.go
Normal file
@ -0,0 +1,165 @@
|
||||
package onebot
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMessageText(t *testing.T) {
|
||||
seg := MessageText("hello")
|
||||
if seg.Type != "text" {
|
||||
t.Errorf("expected type 'text', got %q", seg.Type)
|
||||
}
|
||||
if seg.Data["text"] != "hello" {
|
||||
t.Errorf("expected data.text 'hello', got %q", seg.Data["text"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessageImage(t *testing.T) {
|
||||
seg := MessageImage("test.jpg")
|
||||
if seg.Type != "image" {
|
||||
t.Errorf("expected 'image', got %q", seg.Type)
|
||||
}
|
||||
if seg.Data["file"] != "test.jpg" {
|
||||
t.Errorf("expected 'test.jpg', got %q", seg.Data["file"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessageAt(t *testing.T) {
|
||||
seg := MessageAt(123456)
|
||||
if seg.Type != "at" {
|
||||
t.Errorf("expected 'at', got %q", seg.Type)
|
||||
}
|
||||
if seg.Data["qq"] != "123456" {
|
||||
t.Errorf("expected '123456', got %q", seg.Data["qq"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestEventMarshal(t *testing.T) {
|
||||
evt := Event{
|
||||
Time: 1234567890,
|
||||
SelfID: 10001,
|
||||
PostType: "message",
|
||||
MessageType: "group",
|
||||
GroupID: 999,
|
||||
UserID: 777,
|
||||
RawMessage: "hello",
|
||||
Sender: &Sender{
|
||||
UserID: 777,
|
||||
Nickname: "TestUser",
|
||||
Role: "member",
|
||||
},
|
||||
}
|
||||
|
||||
data, err := json.Marshal(evt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var decoded Event
|
||||
if err := json.Unmarshal(data, &decoded); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if decoded.PostType != "message" {
|
||||
t.Errorf("expected 'message', got %q", decoded.PostType)
|
||||
}
|
||||
if decoded.GroupID != 999 {
|
||||
t.Errorf("expected 999, got %d", decoded.GroupID)
|
||||
}
|
||||
if decoded.Sender.Nickname != "TestUser" {
|
||||
t.Errorf("expected 'TestUser', got %q", decoded.Sender.Nickname)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEventMessagePrivate(t *testing.T) {
|
||||
evt := Event{
|
||||
PostType: "message",
|
||||
MessageType: "private",
|
||||
UserID: 123,
|
||||
RawMessage: "hi",
|
||||
}
|
||||
|
||||
if evt.PostType != "message" || evt.MessageType != "private" {
|
||||
t.Errorf("unexpected event type: %s/%s", evt.PostType, evt.MessageType)
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionMarshal(t *testing.T) {
|
||||
action := Action{
|
||||
Action: "send_private_msg",
|
||||
Params: map[string]interface{}{
|
||||
"user_id": 123,
|
||||
"message": "hello",
|
||||
},
|
||||
Echo: "1",
|
||||
}
|
||||
|
||||
data, err := json.Marshal(action)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var decoded Action
|
||||
if err := json.Unmarshal(data, &decoded); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if decoded.Action != "send_private_msg" {
|
||||
t.Errorf("expected 'send_private_msg', got %q", decoded.Action)
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionResponse(t *testing.T) {
|
||||
resp := ActionResponse{
|
||||
Status: "ok",
|
||||
RetCode: 0,
|
||||
Data: map[string]interface{}{
|
||||
"message_id": 12345,
|
||||
},
|
||||
Echo: "1",
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(resp)
|
||||
var decoded ActionResponse
|
||||
json.Unmarshal(data, &decoded)
|
||||
|
||||
if decoded.Status != "ok" {
|
||||
t.Errorf("expected 'ok', got %q", decoded.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatus(t *testing.T) {
|
||||
s := Status{
|
||||
AppInitialized: true,
|
||||
AppEnabled: true,
|
||||
Online: true,
|
||||
Good: true,
|
||||
}
|
||||
|
||||
if !s.Online || !s.Good {
|
||||
t.Error("status should be online and good")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEventMetaHeartbeat(t *testing.T) {
|
||||
evt := Event{
|
||||
PostType: "meta_event",
|
||||
MetaEventType: "heartbeat",
|
||||
Interval: 3000,
|
||||
Status: &Status{
|
||||
Online: true,
|
||||
Good: true,
|
||||
},
|
||||
}
|
||||
|
||||
if evt.PostType != "meta_event" {
|
||||
t.Errorf("expected 'meta_event', got %q", evt.PostType)
|
||||
}
|
||||
if evt.MetaEventType != "heartbeat" {
|
||||
t.Errorf("expected 'heartbeat', got %q", evt.MetaEventType)
|
||||
}
|
||||
if !evt.Status.Online {
|
||||
t.Error("should be online")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user