package httpx import ( "encoding/json" "fmt" "net/http" "testing" "go.uber.org/zap" "spark-server/internal/infrastructure/id" authlogic "spark-server/internal/module/auth/logic" authlogictest "spark-server/internal/module/auth/logictest" convlogic "spark-server/internal/module/conversation/logic" convmodel "spark-server/internal/module/conversation/model" delivermodel "spark-server/internal/module/deliver/model" friendlogic "spark-server/internal/module/friend/logic" friendmodel "spark-server/internal/module/friend/model" msglogic "spark-server/internal/module/message/logic" msgmodel "spark-server/internal/module/message/model" "spark-server/internal/module/user/logictest" ) func testMessageEngine(t *testing.T) http.Handler { t.Helper() j, err := authlogic.NewJWT(&authlogic.Options{Secret: "test-secret-test-secret", Issuer: "spark-im"}) if err != nil { t.Fatal(err) } ids, err := id.New(1) if err != nil { t.Fatal(err) } users, _ := logictest.UsersAndSMS(ids, nil) chats := convmodel.NewMemoryP2P() p2p := convlogic.NewP2PService(chats, ids) q := delivermodel.NewMemoryQueue() store := msgmodel.NewMemoryRepo() friends := friendlogic.NewService( friendmodel.NewMemoryRepo(), users, ids, friendlogic.NewGreeter(p2p, store, ids, q), ) msgs := msglogic.NewService(store, chats, p2p, friends, nil, ids, q) return NewEngine(zap.NewNop(), &EngineDeps{ Auth: j, Login: authlogictest.LoginService(j, users), Users: users, Friends: friends, Messages: msgs, }) } func TestMessageSendHistoryRecallDeleteHTTP(t *testing.T) { h := testMessageEngine(t) a := loginUser(t, h, "test01@spark.com", 1) b := loginUser(t, h, "test02@spark.com", 2) apply := authJSON(t, h, &a, http.MethodPost, "/v1/friends/requests", `{"email":"test02@spark.com","reason":"hi"}`) if apply.Code != "0" { t.Fatalf("apply %+v", apply) } var applied friendlogic.ApplyResult if err := json.Unmarshal(apply.Data, &applied); err != nil { t.Fatal(err) } acc := authJSON(t, h, &b, http.MethodPost, "/v1/friends", fmt.Sprintf(`{"request_id":%d}`, applied.RequestID)) if acc.Code != "0" { t.Fatalf("accept %+v", acc) } sent := authJSON(t, h, &a, http.MethodPost, "/v1/messages", fmt.Sprintf(`{"peer_id":%d,"client_msg_id":"c1","content":{"t":1,"text":{"body":"hi"}}}`, b.UserID)) if sent.Code != "0" { t.Fatalf("send %+v", sent) } var ack msglogic.SendResponse if err := json.Unmarshal(sent.Data, &ack); err != nil || ack.MsgID == 0 || ack.ConversationID == 0 { t.Fatalf("ack %+v %v", ack, err) } replyBody := fmt.Sprintf(`{"peer_id":%d,"client_msg_id":"c2","content":{"t":1,"reply_to":%d,"text":{"body":"re"}}}`, a.UserID, ack.MsgID) re := authJSON(t, h, &b, http.MethodPost, "/v1/messages", replyBody) if re.Code != "0" { t.Fatalf("reply %+v", re) } var reAck msglogic.SendResponse if err := json.Unmarshal(re.Data, &reAck); err != nil { t.Fatal(err) } hist := authJSON(t, h, &a, http.MethodGet, fmt.Sprintf("/v1/messages?conversation_id=%d", ack.ConversationID), "") if hist.Code != "0" { t.Fatalf("history %+v", hist) } rec := authJSON(t, h, &a, http.MethodPost, fmt.Sprintf("/v1/messages/%d/recall", ack.MsgID), "") if rec.Code != "0" { t.Fatalf("recall %+v", rec) } del := authJSON(t, h, &a, http.MethodDelete, fmt.Sprintf("/v1/messages/%d", reAck.MsgID), "") if del.Code != "0" { t.Fatalf("delete %+v", del) } }