diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 08e2a47be..5ec04ee64 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -41,7 +41,7 @@ ecm_add_test( ecm_add_test( chatbarcachetest.cpp - LINK_LIBRARIES neochat Qt::Test + LINK_LIBRARIES neochat Qt::Test Qt::HttpServer neochat_server TEST_NAME chatbarcachetest ) diff --git a/autotests/chatbarcachetest.cpp b/autotests/chatbarcachetest.cpp index fee7270e9..5f635c827 100644 --- a/autotests/chatbarcachetest.cpp +++ b/autotests/chatbarcachetest.cpp @@ -11,9 +11,13 @@ #include #include +#include + +#include "accountmanager.h" #include "chatbarcache.h" #include "neochatroom.h" +#include "server.h" #include "testutils.h" using namespace Quotient; @@ -24,7 +28,9 @@ class ChatBarCacheTest : public QObject private: Connection *connection = nullptr; - TestUtils::TestRoom *room = nullptr; + NeoChatRoom *room = nullptr; + Server server; + QString eventId; private Q_SLOTS: void initTestCase(); @@ -40,8 +46,31 @@ private Q_SLOTS: void ChatBarCacheTest::initTestCase() { - connection = Connection::makeMockConnection(u"@bob:kde.org"_s); - room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, "test-min-sync.json"_L1); + Connection::setRoomType(); + server.start(); + KLocalizedString::setApplicationDomain(QByteArrayLiteral("neochat")); + auto accountManager = new AccountManager(true, this); + QSignalSpy spy(accountManager, &AccountManager::connectionAdded); + connection = dynamic_cast(accountManager->accounts()->front()); + + const auto roomId = server.createRoom(u"@user:localhost:1234"_s); + eventId = server.sendEvent(roomId, + u"m.room.message"_s, + QJsonObject{ + {u"body"_s, u"foo"_s}, + {u"msgtype"_s, u"m.text"_s}, + }); + + QSignalSpy syncSpy(connection, &Connection::syncDone); + // We need to wait for two syncs, as the next one won't have the changes yet + QVERIFY(syncSpy.wait()); + QVERIFY(syncSpy.wait()); + room = dynamic_cast(connection->room(roomId)); + QVERIFY(room); + + server.joinUser(room->id(), u"@foo:server.com"_s); + QVERIFY(syncSpy.wait()); + QVERIFY(syncSpy.wait()); } void ChatBarCacheTest::empty() @@ -60,8 +89,9 @@ void ChatBarCacheTest::empty() void ChatBarCacheTest::noRoom() { + QTest::ignoreMessage(QtWarningMsg, "ChatBarCache created with no parent, a NeoChatRoom must be set as the parent on creation."); QScopedPointer chatBarCache(new ChatBarCache()); - chatBarCache->setReplyId(u"$153456789:example.org"_s); + chatBarCache->setReplyId(eventId); // These should return empty even though a reply ID has been set because the // ChatBarCache has no parent. @@ -75,9 +105,10 @@ void ChatBarCacheTest::noRoom() void ChatBarCacheTest::badParent() { + QTest::ignoreMessage(QtWarningMsg, "ChatBarCache created with incorrect parent, a NeoChatRoom must be set as the parent on creation."); QScopedPointer badParent(new QObject()); QScopedPointer chatBarCache(new ChatBarCache(badParent.get())); - chatBarCache->setReplyId(u"$153456789:example.org"_s); + chatBarCache->setReplyId(eventId); // These should return empty even though a reply ID has been set because the // ChatBarCache has no parent. @@ -94,15 +125,15 @@ void ChatBarCacheTest::reply() QScopedPointer chatBarCache(new ChatBarCache(room)); chatBarCache->setText(u"some text"_s); chatBarCache->setAttachmentPath(u"some/path"_s); - chatBarCache->setReplyId(u"$153456789:example.org"_s); + chatBarCache->setReplyId(eventId); QCOMPARE(chatBarCache->text(), u"some text"_s); QCOMPARE(chatBarCache->isReplying(), true); - QCOMPARE(chatBarCache->replyId(), u"$153456789:example.org"_s); + QCOMPARE(chatBarCache->replyId(), eventId); QCOMPARE(chatBarCache->isEditing(), false); QCOMPARE(chatBarCache->editId(), QString()); - QCOMPARE(chatBarCache->relationAuthor(), room->member(u"@example:example.org"_s)); - QCOMPARE(chatBarCache->relationMessage(), u"This is an example\ntext message"_s); + QCOMPARE(chatBarCache->relationAuthor(), room->member(u"@foo:server.com"_s)); + QCOMPARE(chatBarCache->relationMessage(), u"foo"_s); QCOMPARE(chatBarCache->attachmentPath(), QString()); QCOMPARE(chatBarCache->relationAuthorIsPresent(), true); } @@ -112,22 +143,26 @@ void ChatBarCacheTest::replyMissingUser() QScopedPointer chatBarCache(new ChatBarCache(room)); chatBarCache->setText(u"some text"_s); chatBarCache->setAttachmentPath(u"some/path"_s); - chatBarCache->setReplyId(u"$153456789:example.org"_s); + chatBarCache->setReplyId(eventId); QCOMPARE(chatBarCache->text(), u"some text"_s); QCOMPARE(chatBarCache->isReplying(), true); - QCOMPARE(chatBarCache->replyId(), u"$153456789:example.org"_s); + QCOMPARE(chatBarCache->replyId(), eventId); QCOMPARE(chatBarCache->isEditing(), false); QCOMPARE(chatBarCache->editId(), QString()); - QCOMPARE(chatBarCache->relationAuthor(), room->member(u"@example:example.org"_s)); - QCOMPARE(chatBarCache->relationMessage(), u"This is an example\ntext message"_s); + QCOMPARE(chatBarCache->relationAuthor(), room->member(u"@foo:server.com"_s)); + QCOMPARE(chatBarCache->relationMessage(), u"foo"_s); QCOMPARE(chatBarCache->attachmentPath(), QString()); QCOMPARE(chatBarCache->relationAuthorIsPresent(), true); QSignalSpy relationAuthorIsPresentSpy(chatBarCache.get(), &ChatBarCache::relationAuthorIsPresentChanged); // sync again, which will simulate the reply user leaving the room - room->syncNewEvents(u"test-min-sync-extra-sync.json"_s); + + QSignalSpy syncSpy(connection, &Connection::syncDone); + server.sendStateEvent(room->id(), u"m.room.member"_s, u"@foo:server.com"_s, {{u"membership"_s, u"leave"_s}}); + QVERIFY(syncSpy.wait()); + QVERIFY(syncSpy.wait()); QTRY_COMPARE(relationAuthorIsPresentSpy.count(), 1); QCOMPARE(chatBarCache->relationAuthorIsPresent(), false); @@ -139,19 +174,19 @@ void ChatBarCacheTest::edit() chatBarCache->setText(u"some text"_s); chatBarCache->setAttachmentPath(u"some/path"_s); - connect(chatBarCache.get(), &ChatBarCache::relationIdChanged, this, [](const QString &oldEventId, const QString &newEventId) { + connect(chatBarCache.get(), &ChatBarCache::relationIdChanged, this, [this](const QString &oldEventId, const QString &newEventId) { QCOMPARE(oldEventId, QString()); - QCOMPARE(newEventId, QString(u"$153456789:example.org"_s)); + QCOMPARE(newEventId, eventId); }); - chatBarCache->setEditId(u"$153456789:example.org"_s); + chatBarCache->setEditId(eventId); QCOMPARE(chatBarCache->text(), u"some text"_s); QCOMPARE(chatBarCache->isReplying(), false); QCOMPARE(chatBarCache->replyId(), QString()); QCOMPARE(chatBarCache->isEditing(), true); - QCOMPARE(chatBarCache->editId(), u"$153456789:example.org"_s); - QCOMPARE(chatBarCache->relationAuthor(), room->member(u"@example:example.org"_s)); - QCOMPARE(chatBarCache->relationMessage(), u"This is an example\ntext message"_s); + QCOMPARE(chatBarCache->editId(), eventId); + QCOMPARE(chatBarCache->relationAuthor(), room->member(u"@foo:server.com"_s)); + QCOMPARE(chatBarCache->relationMessage(), u"foo"_s); QCOMPARE(chatBarCache->attachmentPath(), QString()); } @@ -159,7 +194,7 @@ void ChatBarCacheTest::attachment() { QScopedPointer chatBarCache(new ChatBarCache(room)); chatBarCache->setText(u"some text"_s); - chatBarCache->setEditId(u"$153456789:example.org"_s); + chatBarCache->setEditId(eventId); chatBarCache->setAttachmentPath(u"some/path"_s); QCOMPARE(chatBarCache->text(), u"some text"_s); diff --git a/autotests/data/test-min-sync-extra-sync.json b/autotests/data/test-min-sync-extra-sync.json deleted file mode 100644 index 52453b21b..000000000 --- a/autotests/data/test-min-sync-extra-sync.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "state": { - "events": [ - { - "content": { - "membership": "leave" - }, - "event_id": "$1432735824666PhrSA:example.org", - "origin_server_ts": 1432735824666, - "room_id": "!jEsUZKDJdhlrceRyVU:example.org", - "sender": "@example:example.org", - "state_key": "@example:example.org", - "type": "m.room.member", - "unsigned": { - "replaces_state": "$143273582443PhrSn:example.org" - } - } - ] - } -} diff --git a/autotests/server.cpp b/autotests/server.cpp index 4ac650c58..013fe03db 100644 --- a/autotests/server.cpp +++ b/autotests/server.cpp @@ -127,7 +127,7 @@ void Server::start() qFatal() << "Server failed to listen on a port."; return; } else { - qWarning() << "Server listening"; + qInfo() << "Server listening"; } } @@ -203,6 +203,25 @@ QString Server::sendEvent(const QString &roomId, const QString &eventType, const return eventId; } +QString Server::sendStateEvent(const QString &roomId, const QString &eventType, const QString &stateKey, const QJsonObject &content) +{ + Changes changes; + const auto eventId = generateEventId(); + const auto json = QJsonObject{{u"type"_s, eventType}, + {u"content"_s, content}, + {u"sender"_s, u"@foo:server.com"_s}, + {u"event_id"_s, eventId}, + {u"origin_server_ts"_s, QDateTime::currentMSecsSinceEpoch()}, + {u"room_id"_s, roomId}, + {u"state_key"_s, stateKey}}; + changes.events += Changes::Event{ + .fullJson = json, + }; + changes.stateEvents += Changes::Event{.fullJson = json}; + m_state += changes; + return eventId; +} + void Server::sync(const QHttpServerRequest &request, QHttpServerResponder &responder) { QJsonObject joinRooms; @@ -334,6 +353,18 @@ void Server::sync(const QHttpServerRequest &request, QHttpServerResponder &respo } } + for (const auto &change : m_state.mid(token)) { + for (const auto &state : change.stateEvents) { + const auto &roomId = state.fullJson[u"room_id"_s].toString(); + // TODO: The join could be for a room we haven't joined yet. Shouldn't be necessary for now, though. + auto stateEvents = joinRooms[roomId][u"state"_s][u"events"_s].toArray(); + stateEvents.append(state.fullJson); + auto room = joinRooms[roomId].toObject(); + room[u"state"_s] = QJsonObject{{u"events"_s, stateEvents}}; + joinRooms[roomId] = room; + } + } + for (const auto &change : m_state.mid(token)) { for (const auto &event : change.events) { // TODO the room might be in a different join state. @@ -366,6 +397,5 @@ void Server::sync(const QHttpServerRequest &request, QHttpServerResponder &respo syncData[u"rooms"_s] = rooms; } - qWarning() << syncData; responder.write(QJsonDocument(syncData), QHttpServerResponder::StatusCode::Ok); } diff --git a/autotests/server.h b/autotests/server.h index 10c65999e..003835da4 100644 --- a/autotests/server.h +++ b/autotests/server.h @@ -35,6 +35,7 @@ struct Changes { QJsonObject fullJson; }; QList events; + QList stateEvents; }; struct RoomData { @@ -67,6 +68,7 @@ public: */ QString createServerNoticesRoom(const QString &matrixId); QString sendEvent(const QString &roomId, const QString &eventType, const QJsonObject &content); + QString sendStateEvent(const QString &roomId, const QString &eventType, const QString &stateKey, const QJsonObject &content); private: QHttpServer m_server;