File indexing completed on 2024-11-24 04:44:00

0001 /*
0002    SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
0003    SPDX-FileContributor: Kevin Ottens <kevin@kdab.com>
0004 
0005    SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "imaptestbase.h"
0009 
0010 #include "changeitemtask.h"
0011 #include "uidnextattribute.h"
0012 
0013 #include <KMime/Message>
0014 
0015 #include <QTest>
0016 
0017 Q_DECLARE_METATYPE(QSet<QByteArray>)
0018 
0019 class TestChangeItemTask : public ImapTestBase
0020 {
0021     Q_OBJECT
0022 
0023 private Q_SLOTS:
0024     void shouldAppendMessage_data()
0025     {
0026         QTest::addColumn<Akonadi::Item>("item");
0027         QTest::addColumn<QSet<QByteArray>>("parts");
0028         QTest::addColumn<QList<QByteArray>>("scenario");
0029         QTest::addColumn<QStringList>("callNames");
0030 
0031         Akonadi::Collection collection;
0032         Akonadi::Item item;
0033         QSet<QByteArray> parts;
0034         QString messageContent;
0035         QList<QByteArray> scenario;
0036         QStringList callNames;
0037 
0038         collection = createCollectionChain(QStringLiteral("/INBOX/Foo"));
0039         collection.addAttribute(new UidNextAttribute(65));
0040         item = Akonadi::Item(2);
0041         item.setParentCollection(collection);
0042         item.setRemoteId(QStringLiteral("5"));
0043 
0044         KMime::Message::Ptr message(new KMime::Message);
0045 
0046         messageContent = QStringLiteral("From: ervin\nTo: someone\nSubject: foo\n\nSpeechless...");
0047 
0048         message->setContent(messageContent.toUtf8());
0049         message->parse();
0050         item.setPayload(message);
0051 
0052         parts.clear();
0053         parts << "PLD:RFC822";
0054 
0055         scenario.clear();
0056         scenario << defaultPoolConnectionScenario() << "C: A000003 APPEND \"INBOX/Foo\" {55}\r\n" + message->encodedContent(true)
0057                  << "S: A000003 OK append done [ APPENDUID 1239890035 65 ]"
0058                  << "C: A000004 SELECT \"INBOX/Foo\""
0059                  << "S: A000004 OK select done"
0060                  << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)"
0061                  << "S: A000005 OK store done";
0062 
0063         callNames.clear();
0064         callNames << QStringLiteral("applyCollectionChanges") << QStringLiteral("itemChangeCommitted");
0065 
0066         QTest::newRow("modifying mail content") << item << parts << scenario << callNames;
0067 
0068         collection = createCollectionChain(QStringLiteral("/INBOX/Foo"));
0069         collection.addAttribute(new UidNextAttribute(65));
0070         item = Akonadi::Item(2);
0071         item.setParentCollection(collection);
0072         item.setRemoteId(QStringLiteral("5"));
0073 
0074         message = KMime::Message::Ptr(new KMime::Message);
0075 
0076         messageContent = QStringLiteral("From: ervin\nTo: someone\nSubject: foo\nMessage-ID: <42.4242.foo@bar.org>\n\nSpeechless...");
0077 
0078         message->setContent(messageContent.toUtf8());
0079         message->parse();
0080         item.setPayload(message);
0081 
0082         parts.clear();
0083         parts << "PLD:RFC822";
0084 
0085         scenario.clear();
0086         scenario << defaultPoolConnectionScenario() << "C: A000003 APPEND \"INBOX/Foo\" {90}\r\n" + message->encodedContent(true) << "S: A000003 OK append done"
0087                  << "C: A000004 SELECT \"INBOX/Foo\""
0088                  << "S: A000004 OK select done"
0089                  << "C: A000005 UID SEARCH HEADER Message-ID \"<42.4242.foo@bar.org>\""
0090                  << "S: * SEARCH 65"
0091                  << "S: A000005 OK search done"
0092                  << "C: A000006 UID STORE 5 +FLAGS (\\Deleted)"
0093                  << "S: A000006 OK store done";
0094 
0095         callNames.clear();
0096         callNames << QStringLiteral("applyCollectionChanges") << QStringLiteral("itemChangeCommitted");
0097 
0098         QTest::newRow("modifying mail content, no APPENDUID, message has Message-ID") << item << parts << scenario << callNames;
0099 
0100         collection = createCollectionChain(QStringLiteral("/INBOX/Foo"));
0101         collection.addAttribute(new UidNextAttribute(65));
0102         item = Akonadi::Item(2);
0103         item.setParentCollection(collection);
0104         item.setRemoteId(QStringLiteral("5"));
0105 
0106         message = KMime::Message::Ptr(new KMime::Message);
0107 
0108         messageContent = QStringLiteral("From: ervin\nTo: someone\nSubject: foo\n\nSpeechless...");
0109 
0110         message->setContent(messageContent.toUtf8());
0111         message->parse();
0112         item.setPayload(message);
0113 
0114         parts.clear();
0115         parts << "PLD:RFC822";
0116 
0117         scenario.clear();
0118         scenario << defaultPoolConnectionScenario() << "C: A000003 APPEND \"INBOX/Foo\" {55}\r\n" + message->encodedContent(true) << "S: A000003 OK append done"
0119                  << "C: A000004 SELECT \"INBOX/Foo\""
0120                  << "S: A000004 OK select done"
0121                  << "C: A000005 UID SEARCH NEW UID 65:*"
0122                  << "S: * SEARCH 65"
0123                  << "S: A000005 OK search done"
0124                  << "C: A000006 UID STORE 5 +FLAGS (\\Deleted)"
0125                  << "S: A000006 OK store done";
0126 
0127         callNames.clear();
0128         callNames << QStringLiteral("applyCollectionChanges") << QStringLiteral("itemChangeCommitted");
0129 
0130         QTest::newRow("modifying mail content, no APPENDUID, message has no Message-ID") << item << parts << scenario << callNames;
0131 
0132         // collection unchanged for this test
0133         // item only gets a set of flags
0134         item.setFlags(QSet<QByteArray>() << "\\Foo");
0135 
0136         parts.clear();
0137         parts << "FLAGS";
0138 
0139         scenario.clear();
0140         scenario << defaultPoolConnectionScenario() << "C: A000003 SELECT \"INBOX/Foo\""
0141                  << "S: A000003 OK select done"
0142                  << "C: A000004 UID STORE 5 FLAGS (\\Foo)"
0143                  << "S: A000004 OK store done";
0144 
0145         callNames.clear();
0146         callNames << QStringLiteral("changeProcessed");
0147 
0148         QTest::newRow("modifying mail flags") << item << parts << scenario << callNames;
0149     }
0150 
0151     void shouldAppendMessage()
0152     {
0153         QFETCH(Akonadi::Item, item);
0154         QFETCH(QSet<QByteArray>, parts);
0155         QFETCH(QList<QByteArray>, scenario);
0156         QFETCH(QStringList, callNames);
0157 
0158         FakeServer server;
0159         server.setScenario(scenario);
0160         server.startAndWait();
0161 
0162         SessionPool pool(1);
0163 
0164         pool.setPasswordRequester(createDefaultRequester());
0165         QVERIFY(pool.connect(createDefaultAccount()));
0166         QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int, QString))));
0167 
0168         DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState);
0169         state->setParts(parts);
0170         state->setItem(item);
0171         auto task = new ChangeItemTask(state);
0172         task->start(&pool);
0173 
0174         QTRY_COMPARE(state->calls().count(), callNames.size());
0175         for (int i = 0; i < callNames.size(); i++) {
0176             QString command = QString::fromUtf8(state->calls().at(i).first);
0177             QVariant parameter = state->calls().at(i).second;
0178 
0179             if (command == QLatin1StringView("cancelTask") && callNames[i] != QLatin1StringView("cancelTask")) {
0180                 qDebug() << "Got a cancel:" << parameter.toString();
0181             }
0182 
0183             QCOMPARE(command, callNames[i]);
0184 
0185             if (command == QLatin1StringView("cancelTask")) {
0186                 QVERIFY(!parameter.toString().isEmpty());
0187             }
0188         }
0189 
0190         QVERIFY(server.isAllScenarioDone());
0191 
0192         server.quit();
0193     }
0194 };
0195 
0196 QTEST_GUILESS_MAIN(TestChangeItemTask)
0197 
0198 #include "testchangeitemtask.moc"