mirror of
https://github.com/matrix-org/sliding-sync.git
synced 2025-03-10 13:37:11 +00:00
223 lines
5.9 KiB
Go
223 lines
5.9 KiB
Go
package syncv3
|
|
|
|
import (
|
|
"encoding/json"
|
|
"sort"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/matrix-org/sliding-sync/sync2"
|
|
"github.com/matrix-org/sliding-sync/sync3"
|
|
"github.com/matrix-org/sliding-sync/testutils"
|
|
)
|
|
|
|
type FlushEnum int
|
|
|
|
var (
|
|
NoFlush FlushEnum = 1
|
|
Flush FlushEnum = 2
|
|
)
|
|
|
|
type testRig struct {
|
|
V2 *testV2Server
|
|
V3 *testV3Server
|
|
tokens map[string]string
|
|
}
|
|
|
|
func (r *testRig) Finish() {
|
|
r.V2.close()
|
|
r.V3.close()
|
|
}
|
|
|
|
func (r *testRig) Token(userID string) string {
|
|
return r.tokens[userID]
|
|
}
|
|
|
|
func (r *testRig) SetupV2RoomsForUser(t *testing.T, v2UserID string, f FlushEnum, data map[string]RoomDescriptor) {
|
|
// allocate a user
|
|
_, userExists := r.tokens[v2UserID]
|
|
if !userExists {
|
|
r.tokens[v2UserID] = "access_token_for_" + v2UserID
|
|
r.V2.addAccount(t, v2UserID, r.tokens[v2UserID])
|
|
}
|
|
inviteRooms := make(map[string]sync2.SyncV2InviteResponse)
|
|
joinRooms := make(map[string]sync2.SyncV2JoinResponse)
|
|
roomIDs := make([]string, len(data))
|
|
i := 0
|
|
for roomID := range data {
|
|
roomIDs[i] = roomID
|
|
i++
|
|
}
|
|
sort.Strings(roomIDs) // ensure we always create rooms deterministically
|
|
for _, roomID := range roomIDs {
|
|
time.Sleep(time.Millisecond)
|
|
descriptor := data[roomID]
|
|
if descriptor.MembershipOfSyncer == "" {
|
|
descriptor.MembershipOfSyncer = "join"
|
|
}
|
|
switch descriptor.MembershipOfSyncer {
|
|
case "invite":
|
|
inviteRooms[roomID] = sync2.SyncV2InviteResponse{
|
|
InviteState: sync2.EventsResponse{
|
|
Events: []json.RawMessage{testutils.NewStateEvent(t, "m.room.member", v2UserID, "@inviter:localhost", map[string]interface{}{
|
|
"membership": "invite",
|
|
})},
|
|
},
|
|
}
|
|
case "join":
|
|
creator := descriptor.Creator
|
|
if creator == "" {
|
|
creator = v2UserID
|
|
}
|
|
timestamp := time.Now()
|
|
// configure the room
|
|
var timeline []json.RawMessage
|
|
if descriptor.IsEncrypted {
|
|
timeline = append(timeline, testutils.NewStateEvent(
|
|
t, "m.room.encryption", "", creator, map[string]interface{}{
|
|
"algorithm": "m.megolm.v1.aes-sha2",
|
|
"rotation_period_ms": 604800000,
|
|
"rotation_period_msgs": 100,
|
|
},
|
|
))
|
|
}
|
|
if descriptor.Name != "" {
|
|
timeline = append(timeline, testutils.NewStateEvent(
|
|
t, "m.room.name", "", creator, map[string]interface{}{
|
|
"name": descriptor.Name,
|
|
},
|
|
))
|
|
}
|
|
for _, userID := range descriptor.InvitedUsers {
|
|
timeline = append(timeline, testutils.NewStateEvent(
|
|
t, "m.room.member", userID, creator, map[string]interface{}{
|
|
"membership": "invite",
|
|
},
|
|
))
|
|
}
|
|
for _, userID := range descriptor.JoinedUsers {
|
|
timeline = append(timeline, testutils.NewJoinEvent(
|
|
t, userID,
|
|
))
|
|
}
|
|
var stateBlock []json.RawMessage
|
|
if descriptor.RoomType != "" {
|
|
stateBlock = createRoomStateWithCreateEvent(t, creator,
|
|
testutils.NewStateEvent(t, "m.room.create", "", creator, map[string]interface{}{"creator": creator, "type": descriptor.RoomType}, testutils.WithTimestamp(timestamp)),
|
|
timestamp)
|
|
} else {
|
|
stateBlock = createRoomState(t, creator, timestamp)
|
|
}
|
|
// A valid v2 response always has a timeline entry with state.
|
|
if len(timeline) == 0 {
|
|
timeline = []json.RawMessage{
|
|
stateBlock[len(stateBlock)-1],
|
|
}
|
|
stateBlock = stateBlock[:len(stateBlock)-1]
|
|
}
|
|
joinRooms[roomID] = sync2.SyncV2JoinResponse{
|
|
State: sync2.EventsResponse{
|
|
Events: stateBlock,
|
|
},
|
|
Timeline: sync2.TimelineResponse{
|
|
Events: timeline,
|
|
},
|
|
}
|
|
if len(descriptor.Tags) > 0 {
|
|
tagContent := make(map[string]interface{})
|
|
for tagName, order := range descriptor.Tags {
|
|
tagContent[tagName] = map[string]interface{}{
|
|
"order": order,
|
|
}
|
|
}
|
|
jr := joinRooms[roomID]
|
|
jr.AccountData = sync2.EventsResponse{
|
|
Events: []json.RawMessage{testutils.NewAccountData(
|
|
t, "m.tag", map[string]interface{}{
|
|
"tags": tagContent,
|
|
},
|
|
)},
|
|
}
|
|
joinRooms[roomID] = jr
|
|
}
|
|
default:
|
|
t.Fatalf("unknown value for descriptor.MembershipOfSyncer")
|
|
}
|
|
}
|
|
r.V2.queueResponse(v2UserID, sync2.SyncResponse{
|
|
Rooms: sync2.SyncRoomsResponse{
|
|
Invite: inviteRooms,
|
|
Join: joinRooms,
|
|
},
|
|
})
|
|
if f == Flush {
|
|
if !userExists {
|
|
// do a single request to flush it
|
|
_ = r.V3.mustDoV3Request(t, r.tokens[v2UserID], sync3.Request{})
|
|
} else {
|
|
// there is already a poller running for this user, wait for it to get the data.
|
|
r.V2.waitUntilEmpty(t, v2UserID)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (r *testRig) JoinRoom(t *testing.T, userID, roomID string) {
|
|
r.FlushEvent(t, userID, roomID, testutils.NewJoinEvent(t, userID))
|
|
}
|
|
|
|
func (r *testRig) EncryptRoom(t *testing.T, userID, roomID string) {
|
|
r.FlushEvent(t, userID, roomID, testutils.NewStateEvent(
|
|
t, "m.room.encryption", "", userID, map[string]interface{}{
|
|
"algorithm": "m.megolm.v1.aes-sha2",
|
|
"rotation_period_ms": 604800000,
|
|
"rotation_period_msgs": 100,
|
|
},
|
|
))
|
|
}
|
|
|
|
func (r *testRig) FlushText(t *testing.T, userID, roomID, text string) {
|
|
r.FlushEvent(t, userID, roomID, testutils.NewMessageEvent(t, userID, text))
|
|
}
|
|
|
|
func (r *testRig) FlushEvent(t *testing.T, userID, roomID string, event json.RawMessage) {
|
|
r.V2.queueResponse(userID, sync2.SyncResponse{
|
|
Rooms: sync2.SyncRoomsResponse{
|
|
Join: v2JoinTimeline(roomEvents{
|
|
roomID: roomID,
|
|
events: []json.RawMessage{event},
|
|
}),
|
|
},
|
|
})
|
|
r.V2.waitUntilEmpty(t, userID)
|
|
}
|
|
|
|
func (r *testRig) Room(roomID string) *TestRoom {
|
|
return nil
|
|
}
|
|
|
|
func NewTestRig(t testutils.TestBenchInterface) *testRig {
|
|
pqString := testutils.PrepareDBConnectionString()
|
|
// setup code
|
|
v2 := runTestV2Server(t)
|
|
rig := &testRig{
|
|
V2: v2,
|
|
V3: runTestServer(t, v2, pqString),
|
|
tokens: make(map[string]string),
|
|
}
|
|
return rig
|
|
}
|
|
|
|
type RoomDescriptor struct {
|
|
Creator string
|
|
JoinedUsers []string
|
|
InvitedUsers []string
|
|
MembershipOfSyncer string
|
|
IsEncrypted bool
|
|
RoomType string
|
|
Name string
|
|
Tags map[string]float64
|
|
}
|
|
|
|
type TestRoom struct {
|
|
}
|