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`
This commit is contained in:
parent
7fc839f751
commit
7d83f8b633
|
@ -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 {
|
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
|
var content gomatrixserverlib.RelationContent
|
||||||
if err := json.Unmarshal(event.Content(), &content); err != nil {
|
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 {
|
switch {
|
||||||
case content.Relations == nil:
|
case content.Relations == nil:
|
||||||
|
@ -578,8 +583,6 @@ func (d *Database) UpdateRelations(ctx context.Context, event *gomatrixserverlib
|
||||||
return nil
|
return nil
|
||||||
case content.Relations.RelationType == "":
|
case content.Relations.RelationType == "":
|
||||||
return nil
|
return nil
|
||||||
case event.Type() == gomatrixserverlib.MRoomRedaction:
|
|
||||||
return nil
|
|
||||||
default:
|
default:
|
||||||
return d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
return d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
||||||
return d.Relations.InsertRelation(
|
return d.Relations.InsertRelation(
|
||||||
|
|
|
@ -10,11 +10,13 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/syncapi/routing"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
"github.com/tidwall/gjson"
|
"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/clientapi/producers"
|
||||||
"github.com/matrix-org/dendrite/roomserver"
|
"github.com/matrix-org/dendrite/roomserver"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"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,
|
func syncUntil(t *testing.T,
|
||||||
base *base.BaseDendrite, accessToken string,
|
base *base.BaseDendrite, accessToken string,
|
||||||
skip bool,
|
skip bool,
|
||||||
|
|
Loading…
Reference in a new issue