Skip to content
This repository was archived by the owner on Nov 25, 2024. It is now read-only.

Commit aa1bda4

Browse files
authored
Add AS invite test, fix issue with invitations being processed twice (#3020)
The AS roomserver consumer would receive the events twice, one time as type `OutputTypeNewInviteEvent` and the other time as `OutputTypeNewRoomEvent`. [skip ci]
1 parent e2d2482 commit aa1bda4

File tree

2 files changed

+85
-6
lines changed

2 files changed

+85
-6
lines changed

appservice/appservice_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ import (
1616
"github.com/matrix-org/dendrite/internal/caching"
1717
"github.com/matrix-org/dendrite/internal/sqlutil"
1818
"github.com/matrix-org/dendrite/roomserver"
19+
rsapi "github.com/matrix-org/dendrite/roomserver/api"
1920
"github.com/matrix-org/dendrite/setup/config"
2021
"github.com/matrix-org/dendrite/setup/jetstream"
2122
"github.com/matrix-org/dendrite/test"
2223
"github.com/matrix-org/dendrite/userapi"
24+
"github.com/matrix-org/gomatrixserverlib"
2325

2426
"github.com/matrix-org/dendrite/test/testrig"
2527
)
@@ -212,3 +214,86 @@ func testProtocol(t *testing.T, asAPI api.AppServiceInternalAPI, proto string, w
212214
t.Errorf("unexpected result for Protocols(%s): %+v, expected %+v", proto, protoResp.Protocols[proto], wantResult)
213215
}
214216
}
217+
218+
// Tests that the roomserver consumer only receives one invite
219+
func TestRoomserverConsumerOneInvite(t *testing.T) {
220+
221+
alice := test.NewUser(t)
222+
bob := test.NewUser(t)
223+
room := test.NewRoom(t, alice)
224+
225+
// Invite Bob
226+
room.CreateAndInsert(t, alice, gomatrixserverlib.MRoomMember, map[string]interface{}{
227+
"membership": "invite",
228+
}, test.WithStateKey(bob.ID))
229+
230+
test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) {
231+
cfg, processCtx, closeDB := testrig.CreateConfig(t, dbType)
232+
defer closeDB()
233+
cm := sqlutil.NewConnectionManager(processCtx, cfg.Global.DatabaseOptions)
234+
natsInstance := &jetstream.NATSInstance{}
235+
236+
evChan := make(chan struct{})
237+
// create a dummy AS url, handling the events
238+
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
239+
var txn gomatrixserverlib.ApplicationServiceTransaction
240+
err := json.NewDecoder(r.Body).Decode(&txn)
241+
if err != nil {
242+
t.Fatal(err)
243+
}
244+
for _, ev := range txn.Events {
245+
if ev.Type != gomatrixserverlib.MRoomMember {
246+
continue
247+
}
248+
// Usually we would check the event content for the membership, but since
249+
// we only invited bob, this should be fine for this test.
250+
if ev.StateKey != nil && *ev.StateKey == bob.ID {
251+
evChan <- struct{}{}
252+
}
253+
}
254+
}))
255+
defer srv.Close()
256+
257+
// Create a dummy application service
258+
cfg.AppServiceAPI.Derived.ApplicationServices = []config.ApplicationService{
259+
{
260+
ID: "someID",
261+
URL: srv.URL,
262+
ASToken: "",
263+
HSToken: "",
264+
SenderLocalpart: "senderLocalPart",
265+
NamespaceMap: map[string][]config.ApplicationServiceNamespace{
266+
"users": {{RegexpObject: regexp.MustCompile(bob.ID)}},
267+
"aliases": {{RegexpObject: regexp.MustCompile(room.ID)}},
268+
},
269+
},
270+
}
271+
272+
caches := caching.NewRistrettoCache(128*1024*1024, time.Hour, caching.DisableMetrics)
273+
// Create required internal APIs
274+
rsAPI := roomserver.NewInternalAPI(processCtx, cfg, cm, natsInstance, caches, caching.DisableMetrics)
275+
rsAPI.SetFederationAPI(nil, nil)
276+
usrAPI := userapi.NewInternalAPI(processCtx, cfg, cm, natsInstance, rsAPI, nil)
277+
// start the consumer
278+
appservice.NewInternalAPI(processCtx, cfg, natsInstance, usrAPI, rsAPI)
279+
280+
// Create the room
281+
if err := rsapi.SendEvents(context.Background(), rsAPI, rsapi.KindNew, room.Events(), "test", "test", "test", nil, false); err != nil {
282+
t.Fatalf("failed to send events: %v", err)
283+
}
284+
var seenInvitesForBob int
285+
waitLoop:
286+
for {
287+
select {
288+
case <-time.After(time.Millisecond * 50): // wait for the AS to process the events
289+
break waitLoop
290+
case <-evChan:
291+
seenInvitesForBob++
292+
if seenInvitesForBob != 1 {
293+
t.Fatalf("received unexpected invites: %d", seenInvitesForBob)
294+
}
295+
}
296+
}
297+
close(evChan)
298+
})
299+
}

appservice/consumers/roomserver.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,6 @@ func (s *OutputRoomEventConsumer) onMessage(
140140
}
141141
}
142142

143-
case api.OutputTypeNewInviteEvent:
144-
if output.NewInviteEvent == nil || !s.appserviceIsInterestedInEvent(ctx, output.NewInviteEvent.Event, state.ApplicationService) {
145-
continue
146-
}
147-
events = append(events, output.NewInviteEvent.Event)
148-
149143
default:
150144
continue
151145
}

0 commit comments

Comments
 (0)