|
|
|
|
@ -4,6 +4,7 @@
|
|
|
|
|
#include "../src/accountdelegate.h" |
|
|
|
|
#include <QtTest> |
|
|
|
|
#include <QStandardItemModel> |
|
|
|
|
#include <QClipboard> |
|
|
|
|
extern "C" { |
|
|
|
|
#include "chat/invite_link.h" |
|
|
|
|
} |
|
|
|
|
@ -11,6 +12,60 @@ extern "C" {
|
|
|
|
|
class InviteLinksTest : public QObject { |
|
|
|
|
Q_OBJECT |
|
|
|
|
private slots: |
|
|
|
|
void compactInvitationUsesFullLinkForClickAndCopy() { |
|
|
|
|
struct InviteData invite = {}; |
|
|
|
|
invite.channelId = 42; invite.join_key = 123; invite.pubkey[0] = 1; invite.addrCount = 8; |
|
|
|
|
for (auto& address : invite.addrs) { address.family = 6; address.proto = INVITE_PROTO_TCP; address.port = 443; } |
|
|
|
|
char buffer[1024]; |
|
|
|
|
QVERIFY(invite_link_encode(&invite, nullptr, buffer, sizeof(buffer)) > 0); |
|
|
|
|
const QString link = QString::fromUtf8(buffer); |
|
|
|
|
const QString text = QStringLiteral("Приглашение в группу «Группа»\n") + link; |
|
|
|
|
for (int width : {240, 480}) { |
|
|
|
|
QStandardItemModel model; |
|
|
|
|
auto* message = new QStandardItem; |
|
|
|
|
message->setData(text, MsgTextRole); message->setData(link, MsgInviteLinkRole); |
|
|
|
|
message->setData(QStringLiteral("text/plain"), MsgContentTypeRole); message->setData(true, MsgIsOutgoingRole); |
|
|
|
|
model.appendRow(message); |
|
|
|
|
ChatView view; MessageDelegate delegate; |
|
|
|
|
view.setModel(&model); view.setItemDelegate(&delegate); view.resize(width, 300); |
|
|
|
|
view.setInviteHitTest([&](const QModelIndex& index, const QPoint& point) { |
|
|
|
|
QStyleOptionViewItem option; option.initFrom(&view); option.widget = &view; option.rect = view.visualRect(index); |
|
|
|
|
return delegate.inviteLinkAt(option, index, point); |
|
|
|
|
}); |
|
|
|
|
view.show(); QTest::qWait(30); |
|
|
|
|
const QModelIndex index = model.index(0, 0); |
|
|
|
|
QStyleOptionViewItem option; option.initFrom(&view); option.widget = &view; option.rect = view.visualRect(index); |
|
|
|
|
QPoint firstPoint, lastPoint; |
|
|
|
|
QSet<int> rows; |
|
|
|
|
for (int y = 0; y < option.rect.height(); ++y) { |
|
|
|
|
for (int x = 0; x < view.viewport()->width(); x += 2) { |
|
|
|
|
const QString hit = delegate.inviteLinkAt(option, index, QPoint(x, y)); |
|
|
|
|
if (hit.isEmpty()) continue; |
|
|
|
|
QCOMPARE(hit, link); |
|
|
|
|
rows.insert(y); |
|
|
|
|
if (firstPoint.isNull()) firstPoint = QPoint(x, y); |
|
|
|
|
lastPoint = QPoint(x, y); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
QVERIFY(!firstPoint.isNull()); |
|
|
|
|
QVERIFY(rows.size() <= QFontMetrics(option.font).height() + 1); |
|
|
|
|
QVERIFY(option.rect.height() < 160); |
|
|
|
|
QSignalSpy clicked(&view, &ChatView::inviteLinkActivated); |
|
|
|
|
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, lastPoint); |
|
|
|
|
QCOMPARE(clicked.count(), 1); QCOMPARE(clicked.last().first().toString(), link); |
|
|
|
|
QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, firstPoint); |
|
|
|
|
QMouseEvent drag(QEvent::MouseMove, lastPoint, view.viewport()->mapToGlobal(lastPoint), |
|
|
|
|
Qt::NoButton, Qt::LeftButton, Qt::NoModifier); |
|
|
|
|
QApplication::sendEvent(view.viewport(), &drag); |
|
|
|
|
QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, lastPoint); |
|
|
|
|
QTest::qWait(20); |
|
|
|
|
QCOMPARE(clicked.count(), 1); |
|
|
|
|
view.copySelection(); |
|
|
|
|
QCOMPARE(QApplication::clipboard()->text(), link); |
|
|
|
|
QCOMPARE(index.data(MsgTextRole).toString(), text); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void wrappedLinksPreserveTheirCompleteText() { |
|
|
|
|
struct InviteData invite = {}; |
|
|
|
|
invite.channelId = 42; invite.join_key = 123; invite.pubkey[0] = 1; invite.addrCount = 8; |
|
|
|
|
|