/* GUI получает готовую ссылку: выбор LAN-устройства не пересобирает её и ACK не означает JOIN. */ #include "../src/invitedialog.h" #include "../transport/gui_bridge.h" #include "../db/db_manager.h" #include "../../../src/chat/chat_local.h" #include "../../../src/chat/invite_build.h" #include "../../../lib/debug_config.h" #include "../../../lib/mem.h" #include #include #include #include #include #include static gui_local_event_fn devices_cb, delivery_cb; static gui_invite_link_ready_fn link_cb; static struct chat_local_send_request sent; static int sends; QString DbManager::getDisplayName(quint64 id) const { return QString::number(id); } struct UTUN_INSTANCE* gui_bridge_get_inst(void) { return reinterpret_cast(1); } int gui_bridge_is_uasync_ready(void) { return 1; } void gui_bridge_set_local_devices_cb(gui_local_event_fn cb) { devices_cb = cb; } void gui_bridge_set_local_delivery_cb(gui_local_event_fn cb) { delivery_cb = cb; } void gui_bridge_set_invite_link_ready_cb(gui_invite_link_ready_fn cb) { link_cb = cb; } void gui_bridge_set_invite_candidates_cb(gui_invite_candidates_fn) {} void gui_bridge_post_uasync_fn(void (*fn)(void*), void* arg) { if (fn == chat_local_peers_trampoline) return; if (fn == chat_local_send_trampoline) { sent = *static_cast(arg); sends++; } u_free(arg); } static QByteArray devices(std::initializer_list ids) { QByteArray result; QDataStream stream(&result, QIODevice::WriteOnly); stream << quint16(ids.size()); for (quint64 id : ids) { stream << id << quint8(4); stream.writeRawData("Nick", 4); } return result; } class LocalInviteUiTest : public QObject { Q_OBJECT private slots: void initTestCase() { debug_config_init(); } void deliveryAndDeviceChanges() { { ShareInviteDialog dialog("42", nullptr); auto* combo = dialog.findChild("localDevices"); auto* send = dialog.findChild("sendLocalInvite"); QVERIFY(combo && send && devices_cb && delivery_cb && link_cb); QVERIFY(!send->isEnabled()); auto list = devices({7, 8}); devices_cb((const uint8_t*)list.constData(), list.size()); QCOMPARE(combo->count(), 2); QVERIFY(!send->isEnabled()); link_cb("42", 2, 0, "utun://registered-link"); QVERIFY(send->isEnabled()); combo->setCurrentIndex(1); list = devices({8, 9, 7}); devices_cb((const uint8_t*)list.constData(), list.size()); QCOMPARE(combo->currentData().toULongLong(), quint64(8)); devices_cb((const uint8_t*)list.constData(), list.size() - 1); QCOMPARE(combo->count(), 3); QTest::mouseClick(send, Qt::LeftButton); QCOMPARE(sends, 1); QCOMPARE(sent.peer_id, uint64_t(8)); QCOMPARE(QByteArray(sent.link), QByteArray("utun://registered-link")); QVERIFY(!send->isEnabled()); uint8_t response[17] = {0}; qToBigEndian(sent.request_id + 1, response); response[16] = 1; delivery_cb(response, sizeof(response)); QVERIFY(!send->isEnabled()); qToBigEndian(sent.request_id, response); delivery_cb(response, sizeof(response)); QVERIFY(send->isEnabled()); QTest::mouseClick(send, Qt::LeftButton); QCOMPARE(sends, 2); qToBigEndian(sent.request_id, response); response[16] = LOCAL_DELIVERY_FORBIDDEN; delivery_cb(response, sizeof(response)); QVERIFY(send->isEnabled()); bool forbiddenMessage = false; for (auto* label : dialog.findChildren()) if (label->text() == "Receiving invitations is forbidden. Enable it in the recipient device's settings.") forbiddenMessage = true; QVERIFY(forbiddenMessage); link_cb("42", 2, 0, ""); QVERIFY(!send->isEnabled()); list = devices({}); devices_cb((const uint8_t*)list.constData(), list.size()); QCOMPARE(combo->count(), 0); QVERIFY(!send->isEnabled()); } QVERIFY(!devices_cb && !delivery_cb && !link_cb); } }; QTEST_MAIN(LocalInviteUiTest) #include "test_local_invite_ui.moc"