aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--matrix/matrix.go4
-rw-r--r--matrix/sync.go3
-rw-r--r--matrix/sync_test.go184
3 files changed, 187 insertions, 4 deletions
diff --git a/matrix/matrix.go b/matrix/matrix.go
index 2e97ef4..ee5d9bd 100644
--- a/matrix/matrix.go
+++ b/matrix/matrix.go
@@ -295,9 +295,7 @@ func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) {
func (c *Container) HandleMembership(evt *gomatrix.Event) {
if evt.StateKey != nil && *evt.StateKey == c.config.Session.UserID {
c.processOwnMembershipChange(evt)
- }
-
- if !c.config.Session.InitialSyncDone /*&& evt.Timestamp < time.Now().Add(-1*time.Hour).Unix()*/ {
+ } else if !c.config.Session.InitialSyncDone /*&& evt.Timestamp < time.Now().Add(-1*time.Hour).Unix()*/ {
// We don't care about other users' membership events in the initial sync.
return
}
diff --git a/matrix/sync.go b/matrix/sync.go
index 8ad7ad5..8ff3d39 100644
--- a/matrix/sync.go
+++ b/matrix/sync.go
@@ -74,7 +74,8 @@ func (s *GomuksSyncer) ProcessResponse(res *gomatrix.RespSync, since string) (er
for roomID, roomData := range res.Rooms.Leave {
room := s.Session.GetRoom(roomID)
- s.processSyncEvents(room, roomData.Timeline.Events, true, true)
+ s.processSyncEvents(room, roomData.State.Events, true, true)
+ s.processSyncEvents(room, roomData.Timeline.Events, false, false)
if len(room.PrevBatch) == 0 {
room.PrevBatch = roomData.Timeline.PrevBatch
diff --git a/matrix/sync_test.go b/matrix/sync_test.go
index 886e168..14f8969 100644
--- a/matrix/sync_test.go
+++ b/matrix/sync_test.go
@@ -17,9 +17,119 @@
package matrix_test
import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "maunium.net/go/gomatrix"
+ "maunium.net/go/gomuks/matrix"
"maunium.net/go/gomuks/matrix/rooms"
)
+func TestGomuksSyncer_ProcessResponse_Initial(t *testing.T) {
+ syncer := matrix.NewGomuksSyncer(&mockSyncerSession{})
+ var initDoneCalled = false
+ syncer.InitDoneCallback = func() {
+ initDoneCalled = true
+ }
+
+ syncer.ProcessResponse(newRespSync(), "")
+ assert.True(t, syncer.FirstSyncDone)
+ assert.True(t, initDoneCalled)
+}
+
+func TestGomuksSyncer_ProcessResponse(t *testing.T) {
+ mss := &mockSyncerSession{
+ userID: "@tulir:maunium.net",
+ rooms: map[string]*rooms.Room{
+ "!foo:maunium.net": {
+ Room: gomatrix.NewRoom("!foo:maunium.net"),
+ },
+ "!bar:maunium.net": {
+ Room: gomatrix.NewRoom("!bar:maunium.net"),
+ },
+ "!test:maunium.net": {
+ Room: gomatrix.NewRoom("!test:maunium.net"),
+ },
+ },
+ }
+ ml := &mockListener{}
+ syncer := matrix.NewGomuksSyncer(mss)
+ syncer.OnEventType("m.room.member", ml.receive)
+ syncer.OnEventType("m.room.message", ml.receive)
+
+ joinEvt := &gomatrix.Event{
+ ID: "!join:maunium.net",
+ Type: "m.room.member",
+ Sender: "@tulir:maunium.net",
+ StateKey: ptr("̣@tulir:maunium.net"),
+ Content: map[string]interface{}{
+ "membership": "join",
+ },
+ }
+ messageEvt := &gomatrix.Event{
+ ID: "!msg:maunium.net",
+ Type: "m.room.message",
+ Content: map[string]interface{}{
+ "body": "foo",
+ "msgtype": "m.text",
+ },
+ }
+ unhandledEvt := &gomatrix.Event{
+ ID: "!unhandled:maunium.net",
+ Type: "m.room.unhandled_event",
+ }
+ inviteEvt := &gomatrix.Event{
+ ID: "!invite:matrix.org",
+ Type: "m.room.member",
+ Sender: "@you:matrix.org",
+ StateKey: ptr("̣@tulir:maunium.net"),
+ Content: map[string]interface{}{
+ "membership": "invite",
+ },
+ }
+ leaveEvt := &gomatrix.Event{
+ ID: "!leave:matrix.org",
+ Type: "m.room.member",
+ Sender: "@you:matrix.org",
+ StateKey: ptr("̣@tulir:maunium.net"),
+ Content: map[string]interface{}{
+ "membership": "leave",
+ },
+ }
+
+ resp := newRespSync()
+ resp.Rooms.Join["!foo:maunium.net"] = join{
+ State: events{Events: []*gomatrix.Event{joinEvt}},
+ Timeline: timeline{Events: []*gomatrix.Event{messageEvt, unhandledEvt}},
+ }
+ resp.Rooms.Invite["!bar:maunium.net"] = struct {
+ State struct {
+ Events []*gomatrix.Event `json:"events"`
+ } `json:"invite_state"`
+ }{
+ State: events{Events: []*gomatrix.Event{inviteEvt}},
+ }
+ resp.Rooms.Leave["!test:maunium.net"] = struct {
+ State struct {
+ Events []*gomatrix.Event `json:"events"`
+ } `json:"state"`
+ Timeline struct {
+ Events []*gomatrix.Event `json:"events"`
+ Limited bool `json:"limited"`
+ PrevBatch string `json:"prev_batch"`
+ } `json:"timeline"`
+ }{
+ State: events{Events: []*gomatrix.Event{leaveEvt}},
+ }
+
+ syncer.ProcessResponse(resp, "since")
+ assert.Contains(t, ml.received, joinEvt, joinEvt.ID)
+ assert.Contains(t, ml.received, messageEvt, messageEvt.ID)
+ assert.NotContains(t, ml.received, unhandledEvt, unhandledEvt.ID)
+ assert.Contains(t, ml.received, inviteEvt, inviteEvt.ID)
+ assert.Contains(t, ml.received, leaveEvt, leaveEvt.ID)
+}
+
type mockSyncerSession struct {
rooms map[string]*rooms.Room
userID string
@@ -32,3 +142,77 @@ func (mss *mockSyncerSession) GetRoom(id string) *rooms.Room {
func (mss *mockSyncerSession) GetUserID() string {
return mss.userID
}
+
+type events struct {
+ Events []*gomatrix.Event `json:"events"`
+}
+
+type timeline struct {
+ Events []*gomatrix.Event `json:"events"`
+ Limited bool `json:"limited"`
+ PrevBatch string `json:"prev_batch"`
+}
+type join struct {
+ State struct {
+ Events []*gomatrix.Event `json:"events"`
+ } `json:"state"`
+ Timeline struct {
+ Events []*gomatrix.Event `json:"events"`
+ Limited bool `json:"limited"`
+ PrevBatch string `json:"prev_batch"`
+ } `json:"timeline"`
+ Ephemeral struct {
+ Events []*gomatrix.Event `json:"events"`
+ } `json:"ephemeral"`
+ AccountData struct {
+ Events []*gomatrix.Event `json:"events"`
+ } `json:"account_data"`
+}
+
+func ptr(text string) *string {
+ return &text
+}
+
+type mockListener struct {
+ received []*gomatrix.Event
+}
+
+func (ml *mockListener) receive(evt *gomatrix.Event) {
+ ml.received = append(ml.received, evt)
+}
+
+func newRespSync() *gomatrix.RespSync {
+ resp := &gomatrix.RespSync{NextBatch: "123"}
+ resp.Rooms.Join = make(map[string]struct {
+ State struct {
+ Events []*gomatrix.Event `json:"events"`
+ } `json:"state"`
+ Timeline struct {
+ Events []*gomatrix.Event `json:"events"`
+ Limited bool `json:"limited"`
+ PrevBatch string `json:"prev_batch"`
+ } `json:"timeline"`
+ Ephemeral struct {
+ Events []*gomatrix.Event `json:"events"`
+ } `json:"ephemeral"`
+ AccountData struct {
+ Events []*gomatrix.Event `json:"events"`
+ } `json:"account_data"`
+ })
+ resp.Rooms.Invite = make(map[string]struct {
+ State struct {
+ Events []*gomatrix.Event `json:"events"`
+ } `json:"invite_state"`
+ })
+ resp.Rooms.Leave = make(map[string]struct {
+ State struct {
+ Events []*gomatrix.Event `json:"events"`
+ } `json:"state"`
+ Timeline struct {
+ Events []*gomatrix.Event `json:"events"`
+ Limited bool `json:"limited"`
+ PrevBatch string `json:"prev_batch"`
+ } `json:"timeline"`
+ })
+ return resp
+}