aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTill <2353100+S7evinK@users.noreply.github.com>2023-03-06 12:43:59 +0100
committerGitHub <noreply@github.com>2023-03-06 12:43:59 +0100
commit7d83f8b6332cc41f0ac721d014aaad535069282f (patch)
tree79c348b9c2aaf2a812f3f3ee2654f6da406f8b79
parent7fc839f7519fe9af10ce438df6270cba96148872 (diff)
Add tests for `UpdateRelations` (#2999)
This also fixes an issue regarding updates to relations for invalid events, which could result in us retrying said event over and over again, if we fail to unmarshal the event to `gomatrixserverlib.RelationContent`, this was discovered by `@sleroq:virto.community`
-rw-r--r--syncapi/storage/shared/storage_consumer.go9
-rw-r--r--syncapi/syncapi_test.go88
2 files changed, 93 insertions, 4 deletions
diff --git a/syncapi/storage/shared/storage_consumer.go b/syncapi/storage/shared/storage_consumer.go
index aeeebb1d..18802d0c 100644
--- a/syncapi/storage/shared/storage_consumer.go
+++ b/syncapi/storage/shared/storage_consumer.go
@@ -567,9 +567,14 @@ func (d *Database) ReIndex(ctx context.Context, limit, afterID int64) (map[int64
}
func (d *Database) UpdateRelations(ctx context.Context, event *gomatrixserverlib.HeaderedEvent) error {
+ // No need to unmarshal if the event is a redaction
+ if event.Type() == gomatrixserverlib.MRoomRedaction {
+ return nil
+ }
var content gomatrixserverlib.RelationContent
if err := json.Unmarshal(event.Content(), &content); err != nil {
- return fmt.Errorf("json.Unmarshal: %w", err)
+ logrus.WithError(err).Error("unable to unmarshal relation content")
+ return nil
}
switch {
case content.Relations == nil:
@@ -578,8 +583,6 @@ func (d *Database) UpdateRelations(ctx context.Context, event *gomatrixserverlib
return nil
case content.Relations.RelationType == "":
return nil
- case event.Type() == gomatrixserverlib.MRoomRedaction:
- return nil
default:
return d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
return d.Relations.InsertRelation(
diff --git a/syncapi/syncapi_test.go b/syncapi/syncapi_test.go
index e748660f..1cb82ce1 100644
--- a/syncapi/syncapi_test.go
+++ b/syncapi/syncapi_test.go
@@ -10,11 +10,13 @@ import (
"testing"
"time"
- "github.com/matrix-org/dendrite/syncapi/routing"
"github.com/matrix-org/gomatrixserverlib"
"github.com/nats-io/nats.go"
"github.com/tidwall/gjson"
+ "github.com/matrix-org/dendrite/syncapi/routing"
+ "github.com/matrix-org/dendrite/syncapi/storage"
+
"github.com/matrix-org/dendrite/clientapi/producers"
"github.com/matrix-org/dendrite/roomserver"
"github.com/matrix-org/dendrite/roomserver/api"
@@ -1074,6 +1076,90 @@ func testContext(t *testing.T, dbType test.DBType) {
}
}
+func TestUpdateRelations(t *testing.T) {
+ testCases := []struct {
+ name string
+ eventContent map[string]interface{}
+ eventType string
+ }{
+ {
+ name: "empty event content should not error",
+ },
+ {
+ name: "unable to unmarshal event should not error",
+ eventContent: map[string]interface{}{
+ "m.relates_to": map[string]interface{}{
+ "event_id": map[string]interface{}{}, // this should be a string and not struct
+ },
+ },
+ },
+ {
+ name: "empty event ID is ignored",
+ eventContent: map[string]interface{}{
+ "m.relates_to": map[string]interface{}{
+ "event_id": "",
+ },
+ },
+ },
+ {
+ name: "empty rel_type is ignored",
+ eventContent: map[string]interface{}{
+ "m.relates_to": map[string]interface{}{
+ "event_id": "$randomEventID",
+ "rel_type": "",
+ },
+ },
+ },
+ {
+ name: "redactions are ignored",
+ eventType: gomatrixserverlib.MRoomRedaction,
+ eventContent: map[string]interface{}{
+ "m.relates_to": map[string]interface{}{
+ "event_id": "$randomEventID",
+ "rel_type": "m.replace",
+ },
+ },
+ },
+ {
+ name: "valid event is correctly written",
+ eventContent: map[string]interface{}{
+ "m.relates_to": map[string]interface{}{
+ "event_id": "$randomEventID",
+ "rel_type": "m.replace",
+ },
+ },
+ },
+ }
+
+ ctx := context.Background()
+
+ alice := test.NewUser(t)
+ room := test.NewRoom(t, alice)
+
+ test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) {
+ base, shutdownBase := testrig.CreateBaseDendrite(t, dbType)
+ t.Cleanup(shutdownBase)
+ db, err := storage.NewSyncServerDatasource(base, &base.Cfg.SyncAPI.Database)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ evType := "m.room.message"
+ if tc.eventType != "" {
+ evType = tc.eventType
+ }
+ ev := room.CreateEvent(t, alice, evType, tc.eventContent)
+ err = db.UpdateRelations(ctx, ev)
+ if err != nil {
+ t.Fatal(err)
+ }
+ })
+ }
+ })
+}
+
func syncUntil(t *testing.T,
base *base.BaseDendrite, accessToken string,
skip bool,