2021-11-03 11:07:01 +00:00
|
|
|
package syncv3
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2022-12-15 11:08:50 +00:00
|
|
|
"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"
|
2021-11-03 11:07:01 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Test that sort operations that favour notif counts always appear at the start of the list.
|
|
|
|
func TestNotificationsOnTop(t *testing.T) {
|
2021-11-09 10:15:48 +00:00
|
|
|
pqString := testutils.PrepareDBConnectionString()
|
2021-11-03 11:07:01 +00:00
|
|
|
// setup code
|
|
|
|
v2 := runTestV2Server(t)
|
|
|
|
v3 := runTestServer(t, v2, pqString)
|
|
|
|
defer v2.close()
|
|
|
|
defer v3.close()
|
|
|
|
bob := "@TestNotificationsOnTop_bob:localhost"
|
|
|
|
bingRoomID := "!TestNotificationsOnTop_bing:localhost"
|
|
|
|
noBingRoomID := "!TestNotificationsOnTop_nobing:localhost"
|
|
|
|
latestTimestamp := time.Now()
|
|
|
|
allRooms := []roomEvents{
|
|
|
|
// this room on top when sorted by recency
|
|
|
|
{
|
|
|
|
roomID: noBingRoomID,
|
|
|
|
events: append(createRoomState(t, alice, latestTimestamp), []json.RawMessage{
|
|
|
|
testutils.NewStateEvent(
|
|
|
|
t, "m.room.member", bob, bob, map[string]interface{}{"membership": "join", "displayname": "Bob"},
|
|
|
|
testutils.WithTimestamp(latestTimestamp.Add(5*time.Second)),
|
|
|
|
),
|
|
|
|
}...),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
roomID: bingRoomID,
|
|
|
|
events: append(createRoomState(t, alice, latestTimestamp), []json.RawMessage{
|
|
|
|
testutils.NewStateEvent(
|
|
|
|
t, "m.room.member", bob, bob, map[string]interface{}{"membership": "join", "displayname": "Bob"},
|
|
|
|
testutils.WithTimestamp(latestTimestamp),
|
|
|
|
),
|
|
|
|
}...),
|
|
|
|
},
|
|
|
|
}
|
2023-05-15 19:11:48 +01:00
|
|
|
v2.addAccount(t, alice, aliceToken)
|
2021-11-03 11:07:01 +00:00
|
|
|
v2.queueResponse(alice, sync2.SyncResponse{
|
|
|
|
Rooms: sync2.SyncRoomsResponse{
|
|
|
|
Join: v2JoinTimeline(allRooms...),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
// connect and make sure we get nobing, bing
|
|
|
|
syncRequestBody := sync3.Request{
|
2022-12-20 13:32:39 +00:00
|
|
|
Lists: map[string]sync3.RequestList{
|
|
|
|
"a": {
|
|
|
|
Ranges: sync3.SliceRanges{
|
|
|
|
[2]int64{0, int64(len(allRooms) - 1)}, // all rooms
|
|
|
|
},
|
|
|
|
RoomSubscription: sync3.RoomSubscription{
|
|
|
|
TimelineLimit: int64(100),
|
|
|
|
},
|
|
|
|
// prefer highlights/notifs/rest, and group them by recency not counts count first, THEN eventually recency
|
|
|
|
Sort: []string{sync3.SortByNotificationLevel, sync3.SortByRecency},
|
|
|
|
}},
|
2021-11-03 11:07:01 +00:00
|
|
|
}
|
|
|
|
res := v3.mustDoV3Request(t, aliceToken, syncRequestBody)
|
2022-12-20 13:32:39 +00:00
|
|
|
m.MatchResponse(t, res, m.MatchList("a", m.MatchV3Count(len(allRooms)), m.MatchV3Ops(
|
2022-12-14 18:53:55 +00:00
|
|
|
m.MatchV3SyncOp(0, int64(len(allRooms)-1), []string{noBingRoomID, bingRoomID}),
|
2022-07-12 17:12:01 +01:00
|
|
|
)))
|
2021-11-03 11:07:01 +00:00
|
|
|
|
|
|
|
// send a bing message into the bing room, make sure it comes through and is on top
|
2022-03-28 15:52:25 +01:00
|
|
|
bingEvent := testutils.NewEvent(t, "m.room.message", bob, map[string]interface{}{"body": "BING!"}, testutils.WithTimestamp(latestTimestamp.Add(1*time.Minute)))
|
2021-11-03 11:07:01 +00:00
|
|
|
v2.queueResponse(alice, sync2.SyncResponse{
|
|
|
|
Rooms: sync2.SyncRoomsResponse{
|
|
|
|
Join: map[string]sync2.SyncV2JoinResponse{
|
|
|
|
bingRoomID: {
|
|
|
|
UnreadNotifications: sync2.UnreadNotifications{
|
|
|
|
HighlightCount: ptr(1),
|
|
|
|
},
|
|
|
|
Timeline: sync2.TimelineResponse{
|
|
|
|
Events: []json.RawMessage{
|
2021-11-03 11:20:22 +00:00
|
|
|
bingEvent,
|
2021-11-03 11:07:01 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
v2.waitUntilEmpty(t, alice)
|
|
|
|
res = v3.mustDoV3RequestWithPos(t, aliceToken, res.Pos, syncRequestBody)
|
2022-12-20 13:32:39 +00:00
|
|
|
m.MatchResponse(t, res, m.MatchList("a", m.MatchV3Count(len(allRooms)),
|
2022-07-26 10:11:06 +01:00
|
|
|
m.MatchV3Ops(m.MatchV3DeleteOp(1), m.MatchV3InsertOp(0, bingRoomID)),
|
2023-01-16 12:21:48 +00:00
|
|
|
), m.MatchRoomSubscriptionsStrict(map[string][]m.RoomMatcher{
|
|
|
|
bingRoomID: {
|
|
|
|
m.MatchRoomHighlightCount(1),
|
|
|
|
},
|
|
|
|
}))
|
2021-11-03 11:07:01 +00:00
|
|
|
|
|
|
|
// send a message into the nobing room, it's position must not change due to our sort order
|
2022-03-28 15:52:25 +01:00
|
|
|
noBingEvent := testutils.NewEvent(t, "m.room.message", bob, map[string]interface{}{"body": "no bing"}, testutils.WithTimestamp(latestTimestamp.Add(2*time.Minute)))
|
2021-11-03 11:07:01 +00:00
|
|
|
v2.queueResponse(alice, sync2.SyncResponse{
|
|
|
|
Rooms: sync2.SyncRoomsResponse{
|
|
|
|
Join: map[string]sync2.SyncV2JoinResponse{
|
|
|
|
noBingRoomID: {
|
|
|
|
Timeline: sync2.TimelineResponse{
|
|
|
|
Events: []json.RawMessage{
|
2021-11-03 11:20:22 +00:00
|
|
|
noBingEvent,
|
2021-11-03 11:07:01 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
v2.waitUntilEmpty(t, alice)
|
|
|
|
res = v3.mustDoV3RequestWithPos(t, aliceToken, res.Pos, syncRequestBody)
|
2022-12-20 13:32:39 +00:00
|
|
|
m.MatchResponse(t, res, m.MatchList("a", m.MatchV3Count(len(allRooms))),
|
2022-07-26 10:11:06 +01:00
|
|
|
m.MatchNoV3Ops(),
|
2022-05-25 11:36:30 +01:00
|
|
|
)
|
2021-11-03 11:07:01 +00:00
|
|
|
|
|
|
|
// restart the server and sync from fresh again, it should still have the bing room on top
|
2021-11-03 11:20:22 +00:00
|
|
|
v3.restart(t, v2, pqString)
|
|
|
|
res = v3.mustDoV3Request(t, aliceToken, sync3.Request{
|
2022-12-20 13:32:39 +00:00
|
|
|
Lists: map[string]sync3.RequestList{
|
|
|
|
"a": {
|
|
|
|
Ranges: sync3.SliceRanges{
|
|
|
|
[2]int64{0, int64(len(allRooms) - 1)}, // all rooms
|
|
|
|
},
|
|
|
|
RoomSubscription: sync3.RoomSubscription{
|
|
|
|
TimelineLimit: int64(100),
|
|
|
|
},
|
|
|
|
// prefer highlight count first, THEN eventually recency
|
|
|
|
Sort: []string{sync3.SortByNotificationLevel, sync3.SortByRecency},
|
|
|
|
}},
|
2021-11-03 11:20:22 +00:00
|
|
|
})
|
2022-12-20 13:32:39 +00:00
|
|
|
m.MatchResponse(t, res, m.MatchList("a", m.MatchV3Count(len(allRooms)), m.MatchV3Ops(
|
2022-07-26 10:11:06 +01:00
|
|
|
m.MatchV3SyncOpFn(func(op *sync3.ResponseOpRange) error {
|
2022-05-27 09:54:17 +01:00
|
|
|
if len(op.RoomIDs) != len(allRooms) {
|
|
|
|
return fmt.Errorf("want %d rooms, got %d", len(allRooms), len(op.RoomIDs))
|
2021-11-03 11:20:22 +00:00
|
|
|
}
|
2022-05-27 15:23:31 +01:00
|
|
|
err := allRooms[1].MatchRoom(op.RoomIDs[0],
|
2022-05-27 09:54:17 +01:00
|
|
|
res.Rooms[op.RoomIDs[0]], // bing room is first
|
2022-07-26 10:11:06 +01:00
|
|
|
m.MatchRoomHighlightCount(1),
|
|
|
|
m.MatchRoomNotificationCount(0),
|
|
|
|
m.MatchRoomTimelineMostRecent(1, []json.RawMessage{bingEvent}),
|
2021-11-03 11:20:22 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-05-27 15:23:31 +01:00
|
|
|
err = allRooms[0].MatchRoom(op.RoomIDs[1],
|
2022-05-27 09:54:17 +01:00
|
|
|
res.Rooms[op.RoomIDs[1]], // no bing room is second
|
2022-07-26 10:11:06 +01:00
|
|
|
m.MatchRoomHighlightCount(0),
|
|
|
|
m.MatchRoomNotificationCount(0),
|
|
|
|
m.MatchRoomTimelineMostRecent(1, []json.RawMessage{noBingEvent}),
|
2021-11-03 11:20:22 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}),
|
2022-07-12 17:12:01 +01:00
|
|
|
)))
|
2021-11-03 11:07:01 +00:00
|
|
|
}
|