Cover channel reload state and pending request ownership
This commit is contained in:
1 parent
f81f6299b4
commit
50fff66412
2 files changed
+137
No files matched your search
@@ -474,6 +474,12 @@ target_link_libraries(test_channel_delegate PRIVATE ${QT_LIBS} ${QT_TEST_LIB} ut
|
||||
add_test(NAME test_channel_delegate COMMAND test_channel_delegate)
|
||||
set_tests_properties(test_channel_delegate PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 15)
|
||||
|
||||
add_executable(test_channel_list tests/test_channel_list.cpp src/channellist.cpp src/channeldelegate.cpp
|
||||
src/avatars/groupavatarmanager.cpp db/db_manager.cpp transport/gui_bridge_impl.cpp)
|
||||
target_link_libraries(test_channel_list PRIVATE ${QT_LIBS} ${QT_TEST_LIB} utun utun_voice pthread ${CMAKE_DL_LIBS})
|
||||
add_test(NAME test_channel_list COMMAND test_channel_list)
|
||||
set_tests_properties(test_channel_list PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
|
||||
|
||||
add_executable(test_single_instance tests/test_single_instance.cpp src/single_instance.cpp)
|
||||
target_link_libraries(test_single_instance PRIVATE ${QT_LIBS} ${QT_TEST_LIB} utun pthread ${CMAKE_DL_LIBS})
|
||||
if(WIN32)
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/* Настоящие Qt-меню, БД ядра и bridge: обновления списка и отмена его команд. */
|
||||
#include "../src/channellist.h"
|
||||
#include "../src/channeldelegate.h"
|
||||
#include "../db/db_manager.h"
|
||||
#include "../transport/gui_bridge.h"
|
||||
#include <QtTest>
|
||||
#include <QMenu>
|
||||
#include <QPointer>
|
||||
#include <QScopeGuard>
|
||||
extern "C" {
|
||||
#include "utun_instance.h"
|
||||
#include "chat/chat_core.h"
|
||||
#include "dm/dm_core.h"
|
||||
#include "mem.h"
|
||||
#include "debug_config.h"
|
||||
}
|
||||
|
||||
struct ListCore {
|
||||
UASYNC* ua = uasync_create();
|
||||
UTUN_INSTANCE* inst = nullptr;
|
||||
DbManager db;
|
||||
QString channel;
|
||||
~ListCore() {
|
||||
gui_bridge_set_inst(nullptr); gui_bridge_set_uasync(nullptr);
|
||||
if (ua) uasync_mark_stopped(ua);
|
||||
db.setDb(nullptr);
|
||||
if (inst) utun_instance_destroy(inst);
|
||||
if (ua) uasync_destroy(ua, 0);
|
||||
}
|
||||
bool start() {
|
||||
if (!ua) return false;
|
||||
const char* config = "[global]\n"
|
||||
"my_private_key=704f2e012c8fa8768130cb0f988a997dccb628372bc5ceccacc78dcbfec5916f\n"
|
||||
"my_public_key=b3193173def895bd0fcea6f86af077c7d77216f10395275f627ac18242ec0f01\n"
|
||||
"[chatserver]\ngroup_autoconnect=0\nmember_files_enabled=0\nstorage_autoload=0\n";
|
||||
inst = utun_instance_create_from_str(ua, config);
|
||||
if (!inst || utun_core_start(inst) || chat_service_start(inst)) return false;
|
||||
chat_core_create_channel_auto(inst, "Group");
|
||||
db.setDb(inst->topo_sqlite_db); db.setMyNodeId(inst->node_id);
|
||||
if (db.getChannels().size() != 1) return false;
|
||||
channel = db.getChannels()[0].channelId;
|
||||
const QByteArray peer = QByteArray::fromHex("ce8871f07fa056c636d297115f231b08c29cdf94e0d440fce83a07c34416d36a");
|
||||
return dm_start(inst, 7, (const uint8_t*)peer.constData(), (const uint8_t*)peer.constData(), "PM", nullptr) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
class ChannelListTest : public QObject {
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void initTestCase() { debug_config_init(); debug_set_level(DEBUG_LEVEL_WARN); }
|
||||
|
||||
void reloadKeepsConnectionState() {
|
||||
ListCore core; QVERIFY(core.start());
|
||||
ChannelList list(&core.db); list.loadChannels();
|
||||
auto* view = list.findChild<QListView*>(); QVERIFY(view);
|
||||
list.setChannelPeersOnline(core.channel, 3);
|
||||
list.setAutoConnectActive(true);
|
||||
list.loadChannels();
|
||||
QCOMPARE(view->currentIndex().data(ChannelPeersOnlineRole).toInt(), 3);
|
||||
QVERIFY(view->currentIndex().data(ChannelAutoConnectActiveRole).toBool());
|
||||
QSignalSpy selected(&list, &ChannelList::channelSelected);
|
||||
list.selectChannel(QString());
|
||||
QCOMPARE(view->currentIndex().data(ChannelChannelIdRole).toString(), core.channel);
|
||||
QVERIFY(selected.isEmpty());
|
||||
}
|
||||
|
||||
void unreadNotificationIsUnique() {
|
||||
ListCore core; QVERIFY(core.start());
|
||||
ChannelList list(&core.db); list.loadChannels();
|
||||
auto* view = list.findChild<QListView*>(); QVERIFY(view);
|
||||
QSignalSpy changes(view->model(), &QAbstractItemModel::dataChanged);
|
||||
list.setChannelUnreadCount(core.channel, 7);
|
||||
QCOMPARE(list.getChannelUnreadCount(core.channel), 7);
|
||||
QCOMPARE(changes.count(), 1);
|
||||
list.setChannelUnreadCount(core.channel, 7);
|
||||
QCOMPARE(changes.count(), 1);
|
||||
}
|
||||
|
||||
void presenceRequestsAreCancelledWithoutLeaks() {
|
||||
ListCore core; QVERIFY(core.start());
|
||||
ChannelList list(&core.db);
|
||||
uasync_mark_running(core.ua);
|
||||
gui_bridge_set_uasync(core.ua); gui_bridge_set_inst(core.inst);
|
||||
const int allocations = u_get_alloc_count();
|
||||
list.refreshDmPresence(); list.refreshDmPresence();
|
||||
QTest::qWait(100);
|
||||
QVERIFY(core.ua->pending_head != nullptr);
|
||||
gui_bridge_set_inst(nullptr);
|
||||
QVERIFY(core.ua->pending_head == nullptr);
|
||||
QCOMPARE(u_get_alloc_count(), allocations);
|
||||
}
|
||||
|
||||
void menuRejectsChangedDmGeneration() {
|
||||
ListCore core; QVERIFY(core.start());
|
||||
ChannelList list(&core.db); list.loadChannels(); list.resize(300, 400); list.show();
|
||||
const auto dm = core.db.getDmConversations()[0];
|
||||
list.selectChannel("dm:" + dm.convId);
|
||||
auto* view = list.findChild<QListView*>(); QVERIFY(view);
|
||||
QSignalSpy removed(&list, &ChannelList::dmDeleteRequested);
|
||||
QTimer::singleShot(0, &list, [&] {
|
||||
auto* menu = qobject_cast<QMenu*>(QApplication::activePopupWidget()); QVERIFY(menu);
|
||||
auto* action = menu->findChild<QAction*>("deleteDmAction"); QVERIFY(action && action->isEnabled());
|
||||
view->model()->setData(view->currentIndex(), QVariant::fromValue(dm.generation + 1), ChannelDmGenerationRole);
|
||||
QTest::keyClick(menu, Qt::Key_Down); QTest::keyClick(menu, Qt::Key_Return);
|
||||
});
|
||||
view->customContextMenuRequested(view->visualRect(view->currentIndex()).center());
|
||||
QVERIFY(removed.isEmpty());
|
||||
}
|
||||
|
||||
void menuSurvivesOwnerDeletion() {
|
||||
ListCore core; QVERIFY(core.start());
|
||||
QPointer<ChannelList> list = new ChannelList(&core.db);
|
||||
list->loadChannels(); list->resize(300, 400); list->show();
|
||||
auto* view = list->findChild<QListView*>(); QVERIFY(view);
|
||||
const QPoint point = view->visualRect(view->currentIndex()).center();
|
||||
QTimer::singleShot(0, [&] { delete list.data(); });
|
||||
view->customContextMenuRequested(point);
|
||||
QVERIFY(!list);
|
||||
}
|
||||
|
||||
void borrowedDbCanDisappear() {
|
||||
QPointer<DbManager> db = new DbManager;
|
||||
ChannelList list(db); delete db.data();
|
||||
list.loadChannels(); list.refreshDmPresence();
|
||||
QTest::qWait(100);
|
||||
QCOMPARE(list.findChild<QListView*>()->model()->rowCount(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(ChannelListTest)
|
||||
#include "test_channel_list.moc"
|
||||
Reference in new issue
Block a user