sliding-sync/tests-integration/slow_get_all_rooms_test.go
2023-05-15 19:14:09 +01:00

163 lines
6.3 KiB
Go

package syncv3
import (
"encoding/json"
"fmt"
"testing"
"time"
"github.com/matrix-org/sliding-sync/sync2"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils"
"github.com/matrix-org/sliding-sync/testutils/m"
)
// - Test that you can get all rooms initially for a list
// - Test that you can get all rooms initially for a list with specific filters
// - Test that newly joined rooms still include all state
// - Test that live updates just send the event and no ops
func TestSlowGetAllRoomsInitial(t *testing.T) {
boolTrue := true
numTimelineEventsPerRoom := 3
// setup code
v2 := runTestV2Server(t)
v3 := runTestServer(t, v2, "")
defer v2.close()
defer v3.close()
// make 20 rooms, last room is most recent, and send A,B,C into each room
allRooms := make([]roomEvents, 20)
allRoomIDs := make([]string, len(allRooms))
allRoomMatchers := make(map[string][]m.RoomMatcher)
latestTimestamp := time.Now()
for i := 0; i < len(allRooms); i++ {
ts := time.Now().Add(time.Duration(i) * time.Minute)
roomName := fmt.Sprintf("My Room %d", i)
allRooms[i] = roomEvents{
roomID: fmt.Sprintf("!TestSlowGetAllRoomsInitial_%d:localhost", i),
name: roomName,
events: append(createRoomState(t, alice, ts), []json.RawMessage{
testutils.NewStateEvent(t, "m.room.name", "", alice, map[string]interface{}{"name": roomName}, testutils.WithTimestamp(ts.Add(3*time.Second))),
testutils.NewEvent(t, "m.room.message", alice, map[string]interface{}{"body": "A"}, testutils.WithTimestamp(ts.Add(4*time.Second))),
testutils.NewEvent(t, "m.room.message", alice, map[string]interface{}{"body": "B"}, testutils.WithTimestamp(ts.Add(5*time.Second))),
testutils.NewEvent(t, "m.room.message", alice, map[string]interface{}{"body": "C"}, testutils.WithTimestamp(ts.Add(6*time.Second))),
}...),
}
allRoomIDs[i] = allRooms[i].roomID
if ts.After(latestTimestamp) {
latestTimestamp = ts.Add(10 * time.Second)
}
allRoomMatchers[allRooms[i].roomID] = []m.RoomMatcher{
m.MatchRoomInitial(true),
m.MatchRoomName(allRooms[i].name),
m.MatchRoomTimelineMostRecent(numTimelineEventsPerRoom, allRooms[i].events),
}
}
v2.addAccount(t, alice, aliceToken)
v2.queueResponse(alice, sync2.SyncResponse{
Rooms: sync2.SyncRoomsResponse{
Join: v2JoinTimeline(allRooms...),
},
})
// fetch all the rooms!
res := v3.mustDoV3Request(t, aliceToken, sync3.Request{
Lists: map[string]sync3.RequestList{
"a": {
Ranges: sync3.SliceRanges{
[2]int64{0, 3}, // these get ignored
},
SlowGetAllRooms: &boolTrue,
RoomSubscription: sync3.RoomSubscription{
TimelineLimit: int64(numTimelineEventsPerRoom),
},
}},
})
m.MatchResponse(t, res, m.MatchList("a", m.MatchV3Count(len(allRooms)), m.MatchV3Ops(
m.MatchV3SyncOp(0, int64(len(allRooms)-1), allRoomIDs, true),
)), m.MatchRoomSubscriptionsStrict(allRoomMatchers))
// now redo this but with a room name filter
res = v3.mustDoV3Request(t, aliceToken, sync3.Request{
Lists: map[string]sync3.RequestList{
"a": {
Ranges: sync3.SliceRanges{
[2]int64{0, 3}, // these get ignored
},
SlowGetAllRooms: &boolTrue,
Filters: &sync3.RequestFilters{
RoomNameFilter: "My Room 1", // returns 1,10,11,12,13,14 etc
},
RoomSubscription: sync3.RoomSubscription{
TimelineLimit: int64(numTimelineEventsPerRoom),
},
}},
})
// remove rooms that don't have a leading 1 index as they should be filtered out
for i := 0; i < 10; i++ {
if i == 1 {
continue
}
delete(allRoomMatchers, allRooms[i].roomID)
}
roomIDs := make([]string, 0, len(allRoomMatchers))
for roomID := range allRoomMatchers {
roomIDs = append(roomIDs, roomID)
}
m.MatchResponse(t, res, m.MatchList("a", m.MatchV3Count(len(allRoomMatchers)), m.MatchV3Ops(
m.MatchV3SyncOp(0, int64(len(allRoomMatchers)-1), roomIDs, true),
)), m.MatchRoomSubscriptionsStrict(allRoomMatchers))
t.Run("Newly joined rooms get all state", func(t *testing.T) {
ts := latestTimestamp
roomName := "My Room 111111"
newRoom := roomEvents{
roomID: fmt.Sprintf("!TestSlowGetAllRoomsInitial_%dNEW:localhost", len(allRooms)),
name: roomName,
events: append(createRoomState(t, alice, ts), []json.RawMessage{
testutils.NewStateEvent(t, "m.room.name", "", alice, map[string]interface{}{"name": roomName}, testutils.WithTimestamp(ts.Add(3*time.Second))),
testutils.NewEvent(t, "m.room.message", alice, map[string]interface{}{"body": "A"}, testutils.WithTimestamp(ts.Add(4*time.Second))),
testutils.NewEvent(t, "m.room.message", alice, map[string]interface{}{"body": "B"}, testutils.WithTimestamp(ts.Add(5*time.Second))),
testutils.NewEvent(t, "m.room.message", alice, map[string]interface{}{"body": "C"}, testutils.WithTimestamp(ts.Add(6*time.Second))),
}...),
}
v2.queueResponse(alice, sync2.SyncResponse{
Rooms: sync2.SyncRoomsResponse{
Join: v2JoinTimeline(newRoom),
},
})
v2.waitUntilEmpty(t, alice)
// reuse the position from the room name filter test, we should get this new room
res = v3.mustDoV3RequestWithPos(t, aliceToken, res.Pos, sync3.Request{
Lists: map[string]sync3.RequestList{},
})
m.MatchResponse(t, res, m.MatchList("a", m.MatchV3Count(len(allRoomMatchers)+1)), m.MatchNoV3Ops(), m.MatchRoomSubscriptionsStrict(map[string][]m.RoomMatcher{
newRoom.roomID: {
m.MatchRoomInitial(true),
m.MatchRoomName(roomName),
m.MatchRoomTimelineMostRecent(numTimelineEventsPerRoom, newRoom.events),
},
}))
})
t.Run("live updates just send event", func(t *testing.T) {
newEvent := testutils.NewEvent(t, "m.room.message", alice, map[string]interface{}{"body": "D"}, testutils.WithTimestamp(latestTimestamp.Add(6*time.Second)))
v2.queueResponse(alice, sync2.SyncResponse{
Rooms: sync2.SyncRoomsResponse{
Join: v2JoinTimeline(roomEvents{
roomID: allRooms[11].roomID, // 11 to be caught in the room name filter
events: []json.RawMessage{newEvent},
}),
},
})
v2.waitUntilEmpty(t, alice)
res = v3.mustDoV3RequestWithPos(t, aliceToken, res.Pos, sync3.Request{
Lists: map[string]sync3.RequestList{},
})
m.MatchResponse(t, res, m.MatchList("a", m.MatchV3Count(len(allRoomMatchers)+1)), m.MatchNoV3Ops(), m.MatchRoomSubscriptionsStrict(map[string][]m.RoomMatcher{
allRooms[11].roomID: {
m.MatchRoomInitial(false),
m.MatchRoomTimelineMostRecent(1, []json.RawMessage{newEvent}),
},
}))
})
}