File indexing completed on 2024-05-26 05:28:47

0001 /* Copyright (C) 2014 Stephan Platz <trojita@paalsteek.de>
0002    Copyright (C) 2014 Jan Kundrát <jkt@kde.org>
0003 
0004    This file is part of the Trojita Qt IMAP e-mail client,
0005    http://trojita.flaska.net/
0006 
0007    This program is free software; you can redistribute it and/or
0008    modify it under the terms of the GNU General Public License as
0009    published by the Free Software Foundation; either version 2 of
0010    the License or (at your option) version 3 or any later version
0011    accepted by the membership of KDE e.V. (or its successor approved
0012    by the membership of KDE e.V.), which shall act as a proxy
0013    defined in Section 14 of version 3 of the license.
0014 
0015    This program is distributed in the hope that it will be useful,
0016    but WITHOUT ANY WARRANTY; without even the implied warranty of
0017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0018    GNU General Public License for more details.
0019 
0020    You should have received a copy of the GNU General Public License
0021    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0022 */
0023 
0024 #include <QTest>
0025 #include <QNetworkRequest>
0026 #include <QNetworkReply>
0027 
0028 #include "data.h"
0029 #include "test_Imap_MsgPartNetAccessManager.h"
0030 #include "Imap/Model/ItemRoles.h"
0031 #include "Imap/Network/MsgPartNetAccessManager.h"
0032 #include "Imap/Network/ForbiddenReply.h"
0033 #include "Imap/Network/MsgPartNetworkReply.h"
0034 #include "Streams/FakeSocket.h"
0035 
0036 void ImapMsgPartNetAccessManagerTest::init()
0037 {
0038     LibMailboxSync::init();
0039 
0040     // By default, there's a 50ms delay between the time we request a part download and the time it actually happens.
0041     // That's too long for a unit test.
0042     model->setProperty("trojita-imap-delayed-fetch-part", 0);
0043 
0044     networkPolicy = new Imap::Mailbox::DummyNetworkWatcher(0, model);
0045     netAccessManager = new Imap::Network::MsgPartNetAccessManager(0);
0046 
0047     initialMessages(2);
0048     QModelIndex m1 = msgListA.model()->index(0, 0, msgListA);
0049     QVERIFY(m1.isValid());
0050     QCOMPARE(model->rowCount(m1), 0);
0051     cClient(t.mk("UID FETCH 1:2 (" FETCH_METADATA_ITEMS ")\r\n"));
0052     //cServer()
0053 
0054     QCOMPARE(model->rowCount(msgListA), 2);
0055     msg1 = msgListA.model()->index(0, 0, msgListA);
0056     QVERIFY(msg1.isValid());
0057     msg2 = msgListA.model()->index(1, 0, msgListA);
0058     QVERIFY(msg2.isValid());
0059 
0060     cEmpty();
0061 }
0062 
0063 void ImapMsgPartNetAccessManagerTest::cleanup()
0064 {
0065     delete netAccessManager;
0066     netAccessManager = 0;
0067     delete networkPolicy;
0068     networkPolicy = 0;
0069     LibMailboxSync::cleanup();
0070 }
0071 
0072 void ImapMsgPartNetAccessManagerTest::testMessageParts()
0073 {
0074     QFETCH(QByteArray, bodystructure);
0075     QFETCH(QByteArray, partId);
0076     QFETCH(QString, url);
0077     QFETCH(bool, validity);
0078     QFETCH(QByteArray, text);
0079 
0080     cServer("* 1 FETCH (UID 1 BODYSTRUCTURE (" + bodystructure + "))\r\n" +
0081             "* 2 FETCH (UID 2 BODYSTRUCTURE (" + bodystructure + "))\r\n"
0082             + t.last("OK fetched\r\n"));
0083     QVERIFY(model->rowCount(msg1) > 0);
0084 
0085     netAccessManager->setModelMessage(msg1);
0086     QNetworkRequest req;
0087     req.setUrl(QUrl(url));
0088     QNetworkReply *res = netAccessManager->get(req);
0089     if (validity) {
0090         QVERIFY(qobject_cast<Imap::Network::MsgPartNetworkReply*>(res));
0091         cClient(t.mk("UID FETCH 1 (BODY.PEEK[") + partId + "])\r\n");
0092         cServer("* 1 FETCH (UID 1 BODY[" + partId + "] " + asLiteral(text) + ")\r\n" + t.last("OK fetched\r\n"));
0093         cEmpty();
0094         QCOMPARE(text, res->readAll());
0095     } else {
0096         QVERIFY(qobject_cast<Imap::Network::ForbiddenReply*>(res));
0097     }
0098     QCOMPARE(res->isFinished(), true);
0099     cEmpty();
0100     QVERIFY(errorSpy->isEmpty());
0101 }
0102 
0103 void ImapMsgPartNetAccessManagerTest::testMessageParts_data()
0104 {
0105     QTest::addColumn<QByteArray>("bodystructure");
0106     QTest::addColumn<QByteArray>("partId");
0107     QTest::addColumn<QString>("url");
0108     QTest::addColumn<bool>("validity");
0109     QTest::addColumn<QByteArray>("text");
0110 
0111     QTest::newRow("plaintext/root")
0112             << bsPlaintext
0113             << QByteArray("1")
0114             << "trojita-imap://msg/0"
0115             << true
0116             << QByteArray("blesmrt");
0117 
0118     QTest::newRow("plaintext/invalid-index")
0119             << bsPlaintext
0120             << QByteArray()
0121             << "trojita-imap://msg/1"
0122             << false
0123             << QByteArray();
0124 
0125     QTest::newRow("plaintext/invalid-child")
0126             << bsPlaintext
0127             << QByteArray()
0128             << "trojita-imap://msg/0/0"
0129             << false
0130             << QByteArray();
0131 
0132     QTest::newRow("torture/message-mime")
0133             << bsTortureTest
0134             << QByteArray()
0135             << "trojita-imap://msg/MIME"
0136             << false
0137             << QByteArray();
0138 
0139     QTest::newRow("torture/message-text")
0140             << bsTortureTest
0141             << QByteArray("TEXT")
0142             << "trojita-imap://msg/TEXT"
0143             << true
0144             << QByteArray("meh");
0145 
0146     QTest::newRow("torture/message-header")
0147             << bsTortureTest
0148             << QByteArray("HEADER")
0149             << "trojita-imap://msg/HEADER"
0150             << true
0151             << QByteArray("meh");
0152 
0153     QTest::newRow("torture/plaintext")
0154             << bsTortureTest
0155             << QByteArray("1")
0156             << "trojita-imap://msg/0/0"
0157             << true
0158             << QByteArray("plaintext");
0159 
0160     QTest::newRow("torture/plaintext-mime")
0161             << bsTortureTest
0162             << QByteArray("1.MIME")
0163             << "trojita-imap://msg/0/0/MIME"
0164             << true
0165             << QByteArray("Content-Type: blabla");
0166 
0167     QTest::newRow("torture/plaintext-text")
0168             << bsTortureTest
0169             << QByteArray()
0170             << "trojita-imap://msg/0/0/TEXT"
0171             << false
0172             << QByteArray();
0173 
0174     QTest::newRow("torture/plaintext-header")
0175             << bsTortureTest
0176             << QByteArray()
0177             << "trojita-imap://msg/0/0/HEADER"
0178             << false
0179             << QByteArray();
0180 
0181     QTest::newRow("torture/richtext")
0182             << bsTortureTest
0183             << QByteArray("2.2.1")
0184             << "trojita-imap://msg/0/1/0/1/0"
0185             << true
0186             << QByteArray("text richtext");
0187 
0188     QTest::newRow("multipartRelated/cid")
0189             << bsMultipartRelated
0190             << QByteArray("3")
0191             << "cid:<image002.jpg@01CEFBE5.40406E50>"
0192             << true
0193             << QByteArray("image/jpeg");
0194 
0195     QTest::newRow("torture/trivial-out-of-bounds")
0196             << bsTortureTest
0197             << QByteArray()
0198             << "trojita-imap://msg/666/666"
0199             << false
0200             << QByteArray();
0201 }
0202 
0203 #define COMMON_METADATA_CHAT_PLAIN_AND_SIGNED \
0204     cServer("* 1 FETCH (UID 1 BODYSTRUCTURE (" + bsPlaintext + "))\r\n" + \
0205             "* 2 FETCH (UID 2 BODYSTRUCTURE (" + bsMultipartSignedTextPlain + "))\r\n" \
0206             + t.last("OK fetched\r\n")); \
0207     QCOMPARE(model->rowCount(msg1), 1); \
0208     QCOMPARE(model->rowCount(msg2), 1); \
0209 QCOMPARE(model->rowCount(msg2.model()->index(0, 0, msg2)), 2); \
0210 
0211 /** short A fetching operation gets interrupted by switching to the offline mode */
0212 void ImapMsgPartNetAccessManagerTest::testFetchResultOfflineSingle()
0213 {
0214     COMMON_METADATA_CHAT_PLAIN_AND_SIGNED
0215 
0216     netAccessManager->setModelMessage(msg1);
0217     QNetworkRequest req;
0218     req.setUrl(QUrl(QStringLiteral("trojita-imap://msg/0")));
0219     QNetworkReply *res = netAccessManager->get(req);
0220     QVERIFY(qobject_cast<Imap::Network::MsgPartNetworkReply*>(res));
0221     cClient(t.mk("UID FETCH 1 (BODY.PEEK[1])\r\n"));
0222 
0223     QModelIndex index = msgListA.model()->index(0, 0, msgListA);
0224     QPersistentModelIndex msg1p1 = index.model()->index(0, 0, index);
0225     QVERIFY(msg1p1.isValid());
0226     QCOMPARE(msg1p1.data(Imap::Mailbox::RoleMessageUid), QVariant(1u));
0227     QCOMPARE(msg1p1.data(Imap::Mailbox::RoleIsFetched), QVariant(false));
0228     QCOMPARE(msg1p1.data(Imap::Mailbox::RoleIsUnavailable), QVariant(false));
0229 
0230     networkPolicy->setNetworkOffline();
0231     cClient(t.mk("LOGOUT\r\n"));
0232     cServer(t.last("OK logged out\r\n") + "* BYE eh\r\n");
0233     QCOMPARE(msg1p1.data(Imap::Mailbox::RoleIsFetched), QVariant(false));
0234     QCOMPARE(msg1p1.data(Imap::Mailbox::RoleIsUnavailable), QVariant(true));
0235 
0236     QCOMPARE(res->isFinished(), true);
0237     QCOMPARE(res->error(), QNetworkReply::ContentNotFoundError);
0238 }
0239 
0240 
0241 QTEST_GUILESS_MAIN( ImapMsgPartNetAccessManagerTest )