Skip to content

Commit 46504bb

Browse files
Tests to make sure right event is returned when all of the events have the same timestamps - MSC3030 (#457)
Synapse changes: matrix-org/synapse#13658 Part of matrix-org/matrix-spec-proposals#3030
1 parent 074eb01 commit 46504bb

File tree

1 file changed

+69
-19
lines changed

1 file changed

+69
-19
lines changed

tests/msc3030_test.go

Lines changed: 69 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,45 @@ func TestJumpToDateEndpoint(t *testing.T) {
6363
mustCheckEventisReturnedForTime(t, alice, roomID, eventB.AfterTimestamp, "f", "")
6464
})
6565

66+
t.Run("should find next event topologically before given timestamp when all message timestamps are the same", func(t *testing.T) {
67+
t.Parallel()
68+
roomID, _, _ := createTestRoom(t, alice)
69+
70+
// Join from the application service bridge user so we can use to send
71+
// some messages at a specific time.
72+
as.JoinRoom(t, roomID, []string{"hs1"})
73+
74+
// Send a couple messages with the same timestamp after the other test
75+
// messages in the room.
76+
timeBeforeMessageCreation := time.Now()
77+
sendMessageWithTimestamp(t, as, alice, roomID, timeBeforeMessageCreation, "messageWithSameTime1")
78+
messageIDWithSameTime2 := sendMessageWithTimestamp(t, as, alice, roomID, timeBeforeMessageCreation, "messageWithSameTime2")
79+
80+
// Looking backwards from the time the messages were sent, we should find
81+
// message2. A naive MSC3030 implementation that only sorts by timestamp
82+
// will probably return message1 since it's the first one in the database.
83+
mustCheckEventisReturnedForTime(t, alice, roomID, timeBeforeMessageCreation, "b", messageIDWithSameTime2)
84+
})
85+
86+
t.Run("should find next event topologically after given timestmap when all message timestamps are the same", func(t *testing.T) {
87+
t.Parallel()
88+
roomID, _, _ := createTestRoom(t, alice)
89+
90+
// Join from the application service bridge user so we can use to send
91+
// some messages at a specific time.
92+
as.JoinRoom(t, roomID, []string{"hs1"})
93+
94+
// Send a couple messages with the same timestamp after the other test
95+
// messages in the room.
96+
timeBeforeMessageCreation := time.Now()
97+
messageIDWithSameTime1 := sendMessageWithTimestamp(t, as, alice, roomID, timeBeforeMessageCreation, "messageWithSameTime1")
98+
sendMessageWithTimestamp(t, as, alice, roomID, timeBeforeMessageCreation, "messageWithSameTime2")
99+
100+
// Looking forwards from the time the messages were sent, we should find
101+
// message1.
102+
mustCheckEventisReturnedForTime(t, alice, roomID, timeBeforeMessageCreation, "f", messageIDWithSameTime1)
103+
})
104+
66105
// Just a sanity check that we're not leaking anything from the `/timestamp_to_event` endpoint
67106
t.Run("should not be able to query a private room you are not a member of", func(t *testing.T) {
68107
t.Parallel()
@@ -139,28 +178,13 @@ func TestJumpToDateEndpoint(t *testing.T) {
139178
timeBeforeRoomCreation := time.Now()
140179
roomID, _, _ := createTestRoom(t, alice)
141180

142-
// Join from the application service bridge user
181+
// Join from the application service bridge user so we can use it to send
182+
// some messages at a specific time.
143183
as.JoinRoom(t, roomID, []string{"hs1"})
144184

145-
// Import a message in the room before the room was created. We have to
146-
// use an application service user because they are the only one
147-
// allowed to use the `?ts` query parameter.
185+
// Import a message in the room before the room was created
148186
importTime := time.Date(2022, 01, 03, 0, 0, 0, 0, time.Local)
149-
importTimestamp := makeTimestampFromTime(importTime)
150-
timestampString := strconv.FormatInt(importTimestamp, 10)
151-
// We can't use as.SendEventSynced(...) because application services can't use the /sync API
152-
sendRes := as.DoFunc(t, "PUT", []string{"_matrix", "client", "v3", "rooms", roomID, "send", "m.room.message", getTxnID("findEventBeforeCreation-txn")}, client.WithContentType("application/json"), client.WithJSONBody(t, map[string]interface{}{
153-
"body": "old imported event",
154-
"msgtype": "m.text",
155-
}), client.WithQueries(url.Values{
156-
"ts": []string{timestampString},
157-
}))
158-
sendBody := client.ParseJSON(t, sendRes)
159-
importedEventID := client.GetJSONFieldStr(t, sendBody, "event_id")
160-
// Make sure the imported event has reached the homeserver
161-
alice.MustSyncUntil(t, client.SyncReq{}, client.SyncTimelineHas(roomID, func(ev gjson.Result) bool {
162-
return ev.Get("event_id").Str == importedEventID
163-
}))
187+
importedEventID := sendMessageWithTimestamp(t, as, alice, roomID, importTime, "old imported event")
164188

165189
remoteCharlie.JoinRoom(t, roomID, []string{"hs1"})
166190
mustCheckEventisReturnedForTime(t, remoteCharlie, roomID, timeBeforeRoomCreation, "b", importedEventID)
@@ -237,6 +261,32 @@ func createTestRoom(t *testing.T, c *client.CSAPI) (roomID string, eventA, event
237261
return roomID, eventA, eventB
238262
}
239263

264+
func sendMessageWithTimestamp(t *testing.T, as *client.CSAPI, c *client.CSAPI, roomID string, messageTime time.Time, message string) (messageEventID string) {
265+
t.Helper()
266+
267+
timestamp := makeTimestampFromTime(messageTime)
268+
timestampString := strconv.FormatInt(timestamp, 10)
269+
// We have to use an application service user because they are the only one
270+
// allowed to use the `?ts` query parameter.
271+
//
272+
// We can't use as.SendEventSynced(...) because application services can't use
273+
// the /sync API.
274+
sendRes := as.DoFunc(t, "PUT", []string{"_matrix", "client", "v3", "rooms", roomID, "send", "m.room.message", getTxnID("sendMessageWithTimestamp-txn")}, client.WithContentType("application/json"), client.WithJSONBody(t, map[string]interface{}{
275+
"body": message,
276+
"msgtype": "m.text",
277+
}), client.WithQueries(url.Values{
278+
"ts": []string{timestampString},
279+
}))
280+
sendBody := client.ParseJSON(t, sendRes)
281+
messageEventID = client.GetJSONFieldStr(t, sendBody, "event_id")
282+
// Make sure the imported event has reached the homeserver
283+
c.MustSyncUntil(t, client.SyncReq{}, client.SyncTimelineHas(roomID, func(ev gjson.Result) bool {
284+
return ev.Get("event_id").Str == messageEventID
285+
}))
286+
287+
return
288+
}
289+
240290
// Fetch event from /timestamp_to_event and ensure it matches the expectedEventId
241291
func mustCheckEventisReturnedForTime(t *testing.T, c *client.CSAPI, roomID string, givenTime time.Time, direction string, expectedEventId string) {
242292
t.Helper()

0 commit comments

Comments
 (0)