Warning, file /plasma/plasma-workspace/libnotificationmanager/autotests/notifications_test.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2017 David Edmundson <davidedmundson@kde.org> 0003 SPDX-FileCopyrightText: 2020 Kai Uwe Broulik <kde@broulik.de> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include <QDebug> 0009 #include <QObject> 0010 #include <QSignalSpy> 0011 #include <QTest> 0012 0013 #include "notification.h" 0014 #include "notificationsmodel.h" 0015 #include "server.h" 0016 0017 namespace NotificationManager 0018 { 0019 class NotificationTest : public QObject 0020 { 0021 Q_OBJECT 0022 public: 0023 NotificationTest() 0024 { 0025 } 0026 private Q_SLOTS: 0027 void parse_data(); 0028 void parse(); 0029 0030 void compressNotificationRemoval(); 0031 }; 0032 0033 void NotificationTest::parse_data() 0034 { 0035 QTest::addColumn<QString>("messageIn"); 0036 QTest::addColumn<QString>("expectedOut"); 0037 0038 // clang-format off 0039 QTest::newRow("basic no HTML") << "I am a notification" << "I am a notification"; 0040 QTest::newRow("whitespace") << " I am a notification " << "I am a notification"; 0041 0042 QTest::newRow("basic html") << "I am <b>the</b> notification" << "I am <b>the</b> notification"; 0043 QTest::newRow("nested html") << "I am <i><b>the</b></i> notification" << "I am <i><b>the</b></i> notification"; 0044 0045 QTest::newRow("no extra tags") << "I am <blink>the</blink> notification" << "I am the notification"; 0046 QTest::newRow("no extra attrs") << "I am <b style=\"font-weight:20\">the</b> notification" << "I am <b>the</b> notification"; 0047 0048 QTest::newRow("newlines") << "I am\nthe\nnotification" << "I am<br/>the<br/>notification"; 0049 QTest::newRow("multinewlines") << "I am\n\nthe\n\n\nnotification" << "I am<br/>the<br/>notification"; 0050 0051 QTest::newRow("amp") << "me&you" << "me&you"; 0052 QTest::newRow("double escape") << "foo & <bar>" << "foo & <bar>"; 0053 0054 QTest::newRow("quotes") << "'foo'" << "'foo'";//as label can't handle this normally valid entity 0055 0056 QTest::newRow("image normal") << "This is <img src=\"file:://foo/boo.png\" alt=\"cheese\"/> and more text" << "This is <img src=\"file:://foo/boo.png\" alt=\"cheese\"/> and more text"; 0057 0058 //this input is technically wrong, so the output is also wrong, but QTextHtmlParser does the "right" thing 0059 QTest::newRow("image normal no close") << "This is <img src=\"file:://foo/boo.png\" alt=\"cheese\"> and more text" << "This is <img src=\"file:://foo/boo.png\" alt=\"cheese\"> and more text</img>"; 0060 0061 QTest::newRow("image remote URL") << "This is <img src=\"http://foo.com/boo.png\" alt=\"cheese\" /> and more text" << "This is <img alt=\"cheese\"/> and more text"; 0062 0063 //more bad formatted options. To some extent actual output doesn't matter. Garbage in, garbage out. 0064 //the important thing is that it doesn't contain anything that could be parsed as the remote URL 0065 QTest::newRow("image remote URL no close") << "This is <img src=\"http://foo.com/boo.png>\" alt=\"cheese\"> and more text" << "This is <img alt=\"cheese\"> and more text</img>"; 0066 QTest::newRow("image remote URL double open") << "This is <<img src=\"http://foo.com/boo.png>\" and more text" << "This is "; 0067 QTest::newRow("image remote URL no entity close") << "This is <img src=\"http://foo.com/boo.png\" and more text" << "This is "; 0068 QTest::newRow("image remote URL space in element name") << "This is < img src=\"http://foo.com/boo.png\" alt=\"cheese\" /> and more text" << "This is "; 0069 0070 QTest::newRow("link") << "This is a link <a href=\"http://foo.com/boo\"/> and more text" << "This is a link <a href=\"http://foo.com/boo\"/> and more text"; 0071 // clang-format on 0072 } 0073 0074 void NotificationTest::parse() 0075 { 0076 QFETCH(QString, messageIn); 0077 QFETCH(QString, expectedOut); 0078 0079 NotificationManager::Notification notification; 0080 notification.setBody(messageIn); 0081 0082 expectedOut = "<?xml version=\"1.0\"?><html>" + expectedOut + "</html>\n"; 0083 0084 QCOMPARE(notification.body(), expectedOut); 0085 } 0086 0087 void NotificationTest::compressNotificationRemoval() 0088 { 0089 const int notificationCount = 10; 0090 const int gapId = 4; 0091 0092 auto model = NotificationsModel::createNotificationsModel(); 0093 0094 QSignalSpy rowsRemovedSpy(model.get(), &QAbstractItemModel::rowsRemoved); 0095 QVERIFY(rowsRemovedSpy.isValid()); 0096 0097 for (uint i = 1; i <= notificationCount; ++i) { 0098 Notification notification{i}; 0099 notification.setSummary(QStringLiteral("Notification %1").arg(i)); 0100 model->onNotificationAdded(notification); 0101 } 0102 0103 QCOMPARE(model->rowCount(), notificationCount); 0104 0105 for (uint i = 1; i <= notificationCount; ++i) { 0106 // Leave a gap inbetween 0107 if (i != gapId) { 0108 model->onNotificationRemoved(i, Server::CloseReason::Revoked); 0109 } 0110 } 0111 0112 // We should have two ranges that we ended up removing 0113 QTRY_COMPARE(rowsRemovedSpy.count(), 2); 0114 0115 // The fact that it emits row removal in reverse order is an implementation detail 0116 // We only really care that the number of rows emitted matches our expectation 0117 int removedCount = 0; 0118 for (const auto &removedEmission : rowsRemovedSpy) { 0119 const int from = removedEmission.at(1).toInt(); 0120 const int to = removedEmission.at(2).toInt(); 0121 removedCount += (to - from) + 1; 0122 } 0123 0124 QCOMPARE(removedCount, notificationCount - 1); 0125 QCOMPARE(model->rowCount(), 1); 0126 0127 rowsRemovedSpy.clear(); 0128 0129 // Removing a random non-existing notification should noop 0130 model->onNotificationRemoved(3, Server::CloseReason::Revoked); 0131 QTRY_COMPARE(rowsRemovedSpy.count(), 0); 0132 QCOMPARE(model->rowCount(), 1); 0133 rowsRemovedSpy.clear(); 0134 0135 // Now remove the last one 0136 model->onNotificationRemoved(gapId, Server::CloseReason::Revoked); 0137 QTRY_COMPARE(rowsRemovedSpy.count(), 1); 0138 QCOMPARE(rowsRemovedSpy.at(0).at(1), 0); // from 0139 QCOMPARE(rowsRemovedSpy.at(0).at(2), 0); // to 0140 QCOMPARE(model->rowCount(), 0); 0141 } 0142 0143 } // namespace NotificationManager 0144 0145 QTEST_GUILESS_MAIN(NotificationManager::NotificationTest) 0146 0147 #include "notifications_test.moc"