Keep UI test references stable across queued channel refreshes
This commit is contained in:
1 parent
334991fbe5
commit
4b189891f7
2 files changed
+24
-13
No files matched your search
@@ -202,7 +202,9 @@ single разрешает один вариант либо собственны
|
||||
Изменение ответа заменяет его целиком с ver+1; нулевой ответ отменяет голос.
|
||||
|
||||
message_id сохраняется в msg_<channel> с UNIQUE-индексом:
|
||||
SHA256(`utun-chat-message-v1` || BE64(channel_id) || BE64(timestamp) || author_signature).
|
||||
SHA256(`utun-chat-message-v2` || BE64(channel_id) || BE64(timestamp) || BE64(author) || nonce[16]).
|
||||
ID не меняется при правке текста; MESSAGES заменяет запись только при большем ver.
|
||||
Конверт и подпись версии описаны в [db_sync_arch.md](db_sync_arch.md).
|
||||
Этот ID одинаков на всех узлах и возвращается API сообщений и результатом публикации опроса.
|
||||
Получение исходного сообщения повторно проверяет отложенные ответы. Пользовательские результаты
|
||||
вычисляются по последним допустимым непустым состояниям; проценты — от числа ответивших.
|
||||
|
||||
@@ -54,50 +54,59 @@ private slots:
|
||||
QTRY_VERIFY_WITH_TIMEOUT(db.isOpen(), 3000);
|
||||
QCOMPARE(inCore([](UTUN_INSTANCE* inst) { chat_core_create_channel_auto(inst, "Editable"); return 0; }), 0);
|
||||
QTRY_COMPARE(db.getChannels().size(), 1); const auto channel = db.getChannels().first().channelId;
|
||||
QByteArray id;
|
||||
QByteArray id, replyId;
|
||||
QCOMPARE(inCore([&](UTUN_INSTANCE* inst) {
|
||||
chat_msg_submit req{}; req.inst = inst; strcpy(req.content_type, "text/plain");
|
||||
snprintf(req.channel_id, sizeof(req.channel_id), "%s", qPrintable(channel));
|
||||
req.data = (uint8_t*)"Original"; req.data_len = 8;
|
||||
if (chat_core_submit_message(inst, &req)) return -1;
|
||||
id = QByteArray((const char*)req.message_id, 32); memcpy(req.reply_to, req.message_id, 32);
|
||||
req.data = (uint8_t*)"Reply"; req.data_len = 5; return chat_core_submit_message(inst, &req);
|
||||
req.data = (uint8_t*)"Reply"; req.data_len = 5;
|
||||
const int rc = chat_core_submit_message(inst, &req); replyId = QByteArray((const char*)req.message_id, 32); return rc;
|
||||
}), 0);
|
||||
auto* history = window.findChild<MessageList*>(); QVERIFY(history); history->loadChannel(channel);
|
||||
auto* view = history->findChild<ChatView*>(); auto* input = history->findChild<InputBar*>(); QVERIFY(view && input);
|
||||
auto* editor = input->findChild<QTextEdit*>(); QVERIFY(editor);
|
||||
QTRY_COMPARE(view->model()->rowCount(), 2);
|
||||
const QModelIndex original = view->model()->index(0, 0), reply = view->model()->index(1, 0);
|
||||
QCOMPARE(original.data(MsgTextRole).toString(), QString("Original"));
|
||||
auto indexFor = [&](const QByteArray& key) {
|
||||
for (int row = 0; row < view->model()->rowCount(); row++) {
|
||||
const auto index = view->model()->index(row, 0);
|
||||
if (index.data(MsgMessageKeyRole).toString() == QString::fromLatin1(key.toHex())) return index;
|
||||
}
|
||||
return QModelIndex();
|
||||
};
|
||||
QCOMPARE(indexFor(id).data(MsgTextRole).toString(), QString("Original"));
|
||||
editor->setPlainText("Unsent draft");
|
||||
auto openEditor = [&] {
|
||||
QCoreApplication::processEvents(); const auto original = indexFor(id); QVERIFY(original.isValid());
|
||||
view->scrollTo(original);
|
||||
const auto pos = view->visualRect(original).center();
|
||||
QCOMPARE(view->indexAt(pos), original);
|
||||
QTimer::singleShot(0, [] {
|
||||
auto* menu = qobject_cast<QMenu*>(QApplication::activePopupWidget());
|
||||
if (!menu) qFatal("Edit menu missing");
|
||||
for (auto* action : menu->actions()) if (action->text() == "Edit message") { action->trigger(); menu->close(); return; }
|
||||
qFatal("Edit action missing");
|
||||
});
|
||||
view->scrollTo(original); QCoreApplication::processEvents();
|
||||
const auto pos = view->visualRect(original).center();
|
||||
QMetaObject::invokeMethod(view, "customContextMenuRequested", Qt::DirectConnection, Q_ARG(QPoint, pos));
|
||||
};
|
||||
openEditor(); QCOMPARE(editor->toPlainText(), QString("Original"));
|
||||
gui_bridge_set_msg_received_cb([](const char*, int, uint64_t, int) { ++newMessages; }); newMessages = 0;
|
||||
editor->setPlainText(QString::fromUtf8("Изменено 👍")); QTest::keyClick(editor, Qt::Key_Return);
|
||||
QTRY_COMPARE_WITH_TIMEOUT(original.data(MsgVersionRole).toULongLong(), quint64(2), 3000);
|
||||
QCOMPARE(view->model()->rowCount(), 2); QCOMPARE(original.data(MsgTextRole).toString(), QString::fromUtf8("Изменено 👍"));
|
||||
QVERIFY(original.data(MsgTimeRole).toString().contains("edited "));
|
||||
QCOMPARE(reply.data(MsgQuoteTextRole).toString(), QString::fromUtf8("Изменено 👍"));
|
||||
QTRY_COMPARE_WITH_TIMEOUT(indexFor(id).data(MsgVersionRole).toULongLong(), quint64(2), 3000);
|
||||
QCOMPARE(view->model()->rowCount(), 2); QCOMPARE(indexFor(id).data(MsgTextRole).toString(), QString::fromUtf8("Изменено 👍"));
|
||||
QVERIFY(indexFor(id).data(MsgTimeRole).toString().contains("edited "));
|
||||
QCOMPARE(indexFor(replyId).data(MsgQuoteTextRole).toString(), QString::fromUtf8("Изменено 👍"));
|
||||
QTRY_COMPARE(editor->toPlainText(), QString("Unsent draft")); QCOMPARE(newMessages, 0);
|
||||
openEditor(); editor->setPlainText("Stale editor draft");
|
||||
QCOMPARE(inCore([&](UTUN_INSTANCE* inst) {
|
||||
return chat_core_edit_message(inst, qPrintable(channel), (const uint8_t*)id.constData(), 2, "Remote edit", 11);
|
||||
}), 0);
|
||||
QTRY_COMPARE(original.data(MsgVersionRole).toULongLong(), quint64(3));
|
||||
QTRY_COMPARE(indexFor(id).data(MsgVersionRole).toULongLong(), quint64(3));
|
||||
QCOMPARE(editor->toPlainText(), QString("Stale editor draft"));
|
||||
QSignalSpy failures(input, &InputBar::attachmentRejected); QTest::keyClick(editor, Qt::Key_Return);
|
||||
QTRY_COMPARE(failures.size(), 1); QCOMPARE(editor->toPlainText(), QString("Stale editor draft"));
|
||||
QCOMPARE(original.data(MsgTextRole).toString(), QString("Remote edit")); QCOMPARE(newMessages, 0);
|
||||
QCOMPARE(indexFor(id).data(MsgTextRole).toString(), QString("Remote edit")); QCOMPARE(newMessages, 0);
|
||||
QTest::keyClick(editor, Qt::Key_Escape); QCOMPARE(editor->toPlainText(), QString("Unsent draft"));
|
||||
gui_bridge_set_msg_received_cb(nullptr);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user