package main import ( "sync" "testing" "time" "github.com/tinode/chat/server/push" "github.com/tinode/chat/server/store/types" ) func TestDispatchPushAsyncDeliversToUserUpdater(t *testing.T) { oldUsersUpdate := globals.usersUpdate globals.usersUpdate = make(chan *UserCacheReq, 1) t.Cleanup(func() { globals.usersUpdate = oldUsersUpdate }) uid := types.Uid(101) rcpt := &push.Receipt{ TenantID: 1, To: map[types.Uid]push.Recipient{uid: {Delivered: 1}}, Payload: push.Payload{What: push.ActMsg, Topic: "grpAsync"}, } if !dispatchPushAsync(rcpt, false) { t.Fatal("push dispatch was not enqueued") } select { case req := <-globals.usersUpdate: if req.PushRcpt != rcpt { t.Fatal("user updater received the wrong receipt") } case <-time.After(time.Second): t.Fatal("timed out waiting for asynchronous push dispatch") } } func TestDeferredPresenceCoalescesAndRetries(t *testing.T) { tenantID := types.TenantID(1) topicName := "grpDeferred" topic := &Topic{tenantID: tenantID, name: topicName, serverMsg: make(chan *ServerComMessage, 1)} topic.serverMsg <- &ServerComMessage{TenantID: tenantID, RcptTo: topicName} hub := &Hub{ topics: &sync.Map{}, deferredPresence: make(chan *ServerComMessage, 4), deferredPresenceStop: make(chan struct{}), } hub.topicPut(types.TopicKey{TenantID: tenantID, Topic: topicName}, topic) go hub.runDeferredPresence() t.Cleanup(func() { close(hub.deferredPresenceStop) }) off := &ServerComMessage{TenantID: tenantID, RcptTo: topicName, Pres: &MsgServerPres{What: "off", Src: "usrA"}} on := &ServerComMessage{TenantID: tenantID, RcptTo: topicName, Pres: &MsgServerPres{What: "on", Src: "usrA"}} if !hub.deferPresence(off) || !hub.deferPresence(on) { t.Fatal("failed to enqueue deferred presence") } time.Sleep(20 * time.Millisecond) <-topic.serverMsg select { case got := <-topic.serverMsg: if got.Pres == nil || got.Pres.What != "on" { t.Fatalf("expected latest coalesced presence, got %#v", got.Pres) } case <-time.After(time.Second): t.Fatal("timed out waiting for deferred presence retry") } }