154 lines
4.4 KiB
Go
154 lines
4.4 KiB
Go
package roomnotice
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
roomeventsv1 "hyapp.local/api/proto/events/room/v1"
|
|
"hyapp/pkg/tencentim"
|
|
)
|
|
|
|
func TestProcessRoomKickNoticesPublishesPrivateIM(t *testing.T) {
|
|
repo := &fakeRepository{
|
|
events: []RoomKickEvent{{
|
|
AppCode: "lalu",
|
|
EventID: "evt-room-kick-1",
|
|
EventType: "RoomUserKicked",
|
|
RoomID: "room_10001",
|
|
RoomVersion: 18,
|
|
ActorUserID: 10001,
|
|
TargetUserID: 20001,
|
|
OccurredAtMS: 1710000000123,
|
|
CreatedAtMS: 1710000000124,
|
|
}},
|
|
}
|
|
publisher := &fakePublisher{}
|
|
service := New(Config{NodeID: "notice-test"}, repo, publisher)
|
|
|
|
processed, err := service.ProcessRoomKickNotices(context.Background(), RoomNoticeWorkerOptions{
|
|
WorkerID: "room-notice-test",
|
|
BatchSize: 10,
|
|
LockTTL: time.Second,
|
|
PublishTimeout: time.Second,
|
|
MaxRetryCount: 3,
|
|
InitialBackoff: time.Second,
|
|
MaxBackoff: time.Second,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("ProcessRoomKickNotices failed: %v", err)
|
|
}
|
|
if processed != 1 {
|
|
t.Fatalf("processed=%d, want 1", processed)
|
|
}
|
|
if len(publisher.messages) != 1 {
|
|
t.Fatalf("published messages=%d, want 1", len(publisher.messages))
|
|
}
|
|
message := publisher.messages[0]
|
|
if message.ToAccount != "20001" || message.EventID != "evt-room-kick-1" || message.Ext != "room_notice" || message.Desc != "room_user_kicked" {
|
|
t.Fatalf("unexpected message: %+v", message)
|
|
}
|
|
if repo.deliveredEventID != "evt-room-kick-1" {
|
|
t.Fatalf("delivered event id=%q", repo.deliveredEventID)
|
|
}
|
|
|
|
var payload map[string]any
|
|
if err := json.Unmarshal(message.PayloadJSON, &payload); err != nil {
|
|
t.Fatalf("decode payload: %v", err)
|
|
}
|
|
if payload["event_type"] != "room_user_kicked" || payload["room_id"] != "room_10001" {
|
|
t.Fatalf("unexpected payload: %+v", payload)
|
|
}
|
|
if payload["target_user_id"].(float64) != 20001 || payload["actor_user_id"].(float64) != 10001 {
|
|
t.Fatalf("unexpected user payload: %+v", payload)
|
|
}
|
|
}
|
|
|
|
func TestProcessRoomKickNoticesMarksRetryableOnPublishError(t *testing.T) {
|
|
repo := &fakeRepository{
|
|
events: []RoomKickEvent{{
|
|
AppCode: "lalu",
|
|
EventID: "evt-room-kick-2",
|
|
EventType: "RoomUserKicked",
|
|
RoomID: "room_10001",
|
|
ActorUserID: 10001,
|
|
TargetUserID: 20001,
|
|
RetryCount: 1,
|
|
}},
|
|
}
|
|
service := New(Config{NodeID: "notice-test"}, repo, &fakePublisher{err: errors.New("im timeout")})
|
|
|
|
processed, err := service.ProcessRoomKickNotices(context.Background(), RoomNoticeWorkerOptions{
|
|
WorkerID: "room-notice-test",
|
|
BatchSize: 10,
|
|
LockTTL: time.Second,
|
|
PublishTimeout: time.Second,
|
|
MaxRetryCount: 3,
|
|
InitialBackoff: time.Second,
|
|
MaxBackoff: time.Second,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("ProcessRoomKickNotices failed: %v", err)
|
|
}
|
|
if processed != 1 {
|
|
t.Fatalf("processed=%d, want 1", processed)
|
|
}
|
|
if repo.retryEventID != "evt-room-kick-2" || repo.retryCount != 2 {
|
|
t.Fatalf("retry marker event=%q count=%d", repo.retryEventID, repo.retryCount)
|
|
}
|
|
if repo.failedEventID != "" {
|
|
t.Fatalf("event should be retryable, got failed=%q", repo.failedEventID)
|
|
}
|
|
}
|
|
|
|
type fakeRepository struct {
|
|
events []RoomKickEvent
|
|
deliveredEventID string
|
|
retryEventID string
|
|
failedEventID string
|
|
retryCount int
|
|
}
|
|
|
|
func (r *fakeRepository) ClaimRoomKickEvents(context.Context, string, int, time.Duration) ([]RoomKickEvent, error) {
|
|
return r.events, nil
|
|
}
|
|
|
|
func (r *fakeRepository) ClaimRoomKickEnvelope(context.Context, string, *roomeventsv1.EventEnvelope, time.Duration) (RoomKickEvent, bool, error) {
|
|
if len(r.events) == 0 {
|
|
return RoomKickEvent{}, false, nil
|
|
}
|
|
return r.events[0], true, nil
|
|
}
|
|
|
|
func (r *fakeRepository) MarkRoomKickDelivered(_ context.Context, event RoomKickEvent, _ []byte, _ int64) error {
|
|
r.deliveredEventID = event.EventID
|
|
return nil
|
|
}
|
|
|
|
func (r *fakeRepository) MarkRoomKickRetryable(_ context.Context, event RoomKickEvent, retryCount int, _ int64, _ string, _ int64) error {
|
|
r.retryEventID = event.EventID
|
|
r.retryCount = retryCount
|
|
return nil
|
|
}
|
|
|
|
func (r *fakeRepository) MarkRoomKickFailed(_ context.Context, event RoomKickEvent, retryCount int, _ string, _ int64) error {
|
|
r.failedEventID = event.EventID
|
|
r.retryCount = retryCount
|
|
return nil
|
|
}
|
|
|
|
type fakePublisher struct {
|
|
messages []tencentim.CustomUserMessage
|
|
err error
|
|
}
|
|
|
|
func (p *fakePublisher) PublishUserCustomMessage(_ context.Context, message tencentim.CustomUserMessage) error {
|
|
if p.err != nil {
|
|
return p.err
|
|
}
|
|
p.messages = append(p.messages, message)
|
|
return nil
|
|
}
|