@@ -375,42 +375,64 @@ void QMCTest::checkFileSendingOutcome(const QString& txnId,
375375void QMCTest::setTopic ()
376376{
377377 static const char * const stateTestName = " State setting test" ;
378- static const char * const fakeStateTestName =
379- " Fake state event immunity test" ;
380378 running.push_back (stateTestName);
381- running.push_back (fakeStateTestName);
382379 auto initialTopic = targetRoom->topic ();
383380
384- const auto newTopic = c->generateTxnId ();
381+ const auto newTopic = c->generateTxnId (); // Just a way to get a unique id
385382 targetRoom->setTopic (newTopic); // Sets the state by proper means
386383 const auto fakeTopic = c->generateTxnId ();
387- targetRoom->postJson (RoomTopicEvent::matrixTypeId (), // Fake state event
388- RoomTopicEvent (fakeTopic).contentJson ());
384+ const auto fakeTxnId =
385+ targetRoom->postJson (RoomTopicEvent::matrixTypeId (), // Fake state event
386+ RoomTopicEvent (fakeTopic).contentJson ());
389387
390388 connectUntil (targetRoom, &Room::topicChanged, this ,
391389 [this , newTopic, fakeTopic, initialTopic] {
392390 if (targetRoom->topic () == newTopic) {
393391 QMC_CHECK (stateTestName, true );
394- // Don't reset the topic yet if the negative test still
395- // runs
396- if (!running.contains (fakeStateTestName))
397- targetRoom->setTopic (initialTopic);
398-
399392 return true ;
400393 }
401394 return false ;
402395 });
403396
404- connectUntil (targetRoom, &Room::pendingEventAboutToMerge, this ,
405- [this , fakeTopic, initialTopic](const RoomEvent* e, int ) {
406- if (e->contentJson ().value (" topic" ).toString () != fakeTopic)
407- return false ; // Wait on for the right event
397+ // Older Synapses allowed sending fake state events through, although
398+ // did not process them; // https://github.com/matrix-org/synapse/pull/5805
399+ // changed that and now Synapse 400's in response to fake state events.
400+ // The following two-step approach handles both cases, assuming that
401+ // Room::pendingEventChanged() with EventStatus::ReachedServer is guaranteed
402+ // to be emitted before Room::pendingEventAboutToMerge.
403+ connectUntil (
404+ targetRoom, &Room::pendingEventChanged, this ,
405+ [this , fakeTopic, initialTopic, fakeTxnId](int pendingIdx) {
406+ const auto & pendingEvents = targetRoom->pendingEvents ();
407+ Q_ASSERT (pendingIdx >= 0 && pendingIdx < int (pendingEvents.size ()));
408+ const auto & evt = pendingEvents[pendingIdx];
409+ if (evt->transactionId () != fakeTxnId)
410+ return false ;
408411
409- QMC_CHECK (fakeStateTestName, !e->isStateEvent ());
410- if (!running.contains (fakeStateTestName))
411- targetRoom->setTopic (initialTopic);
412- return true ;
413- });
412+ if (evt.deliveryStatus () == EventStatus::SendingFailed) {
413+ QMC_CHECK (" Fake state event immunity test" , true );
414+ return true ;
415+ }
416+ if (evt.deliveryStatus () != EventStatus::ReachedServer)
417+ return false ;
418+
419+ // All before was just a preparation, this is where the test starts.
420+ // (If Synapse rejected the event the library immunity can't be
421+ // tested.)
422+ static const char * const fakeStateTestName =
423+ " Fake state event immunity test" ;
424+ running.push_back (fakeStateTestName);
425+ connectUntil (
426+ targetRoom, &Room::pendingEventAboutToMerge, this ,
427+ [this , fakeTopic, initialTopic](const RoomEvent* e, int ) {
428+ if (e->contentJson ().value (" topic" ).toString () != fakeTopic)
429+ return false ; // Wait on for the right event
430+
431+ QMC_CHECK (fakeStateTestName, !e->isStateEvent ());
432+ return true ;
433+ });
434+ return true ;
435+ });
414436}
415437
416438void QMCTest::addAndRemoveTag ()
0 commit comments