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

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 "removecollectionrecursivetask.h"
0011 #include <QTest>
0012 class TestRemoveCollectionRecursiveTask : public ImapTestBase
0013 {
0014     Q_OBJECT
0015 
0016     void shouldDeleteMailBoxRecursive_data()
0017     {
0018         QTest::addColumn<Akonadi::Collection>("collection");
0019         QTest::addColumn<QList<QByteArray>>("scenario");
0020         QTest::addColumn<QStringList>("callNames");
0021 
0022         Akonadi::Collection collection;
0023         QList<QByteArray> scenario;
0024         QStringList callNames;
0025 
0026         collection = createCollectionChain(QStringLiteral("/INBOX/test1"));
0027 
0028         scenario.clear();
0029         scenario << defaultPoolConnectionScenario() << "C: A000003 LSUB \"\" *"
0030                  << "S: * LSUB ( \\HasChildren ) / INBOX"
0031                  << "S: * LSUB ( \\HasChildren ) / INBOX/test1"
0032                  << "S: * LSUB ( ) / INBOX/test1/test2"
0033                  << "S: A000003 OK Completed ( 0.000 secs 26 calls )"
0034                  << "C: A000004 SELECT \"INBOX/test1/test2\""
0035                  << R"(S: * FLAGS ( \Answered \Flagged \Draft \Deleted \Seen ))"
0036                  << R"(S: * OK [ PERMANENTFLAGS ( \Answered \Flagged \Draft \Deleted \Seen \* )  ])"
0037                  << "S: * 1 EXISTS"
0038                  << "S: * 0 RECENT"
0039                  << "S: * OK [ UNSEEN 1  ]"
0040                  << "S: * OK [ UIDVALIDITY 1292857898  ]"
0041                  << "S: * OK [ UIDNEXT 2  ]"
0042                  << "S: A000004 OK Completed [ READ-WRITE  ]"
0043                  << "C: A000005 STORE 1:* +FLAGS (\\DELETED)"
0044                  << "S: * 1 FETCH ( FLAGS (\\Deleted) ) "
0045                  << "S: A000005 OK Completed"
0046                  << "C: A000006 EXPUNGE"
0047                  << "S: * 1 EXPUNGE"
0048                  << "S: * 0 EXISTS"
0049                  << "S: * 0 RECENT"
0050                  << "S: A000006 OK Completed"
0051                  << "C: A000007 CLOSE"
0052                  << "S: A000007 OK Completed"
0053                  << "C: A000008 DELETE \"INBOX/test1/test2\""
0054                  << "S: * 0 EXISTS"
0055                  << "S: * 0 RECENT"
0056                  << "S: A000008 OK Completed"
0057                  << "C: A000009 SELECT \"INBOX/test1\""
0058                  << R"(S: * FLAGS ( \Answered \Flagged \Draft \Deleted \Seen ))"
0059                  << R"(S: * OK [ PERMANENTFLAGS ( \Answered \Flagged \Draft \Deleted \Seen \* )  ])"
0060                  << "S: * 1 EXISTS"
0061                  << "S: * 1 RECENT"
0062                  << "S: * OK [ UIDVALIDITY 1292857888  ]"
0063                  << "S: * OK [ UIDNEXT 2  ]"
0064                  << "S: A000009 OK Completed [ READ-WRITE  ]"
0065                  << "C: A000010 STORE 1:* +FLAGS (\\DELETED)"
0066                  << R"(S: * 1 FETCH ( FLAGS (\Recent \Deleted \Seen) ))"
0067                  << "S: A000010 OK Completed"
0068                  << "C: A000011 EXPUNGE"
0069                  << "S: * 1 EXPUNGE"
0070                  << "S: * 0 EXISTS"
0071                  << "S: * 0 RECENT"
0072                  << "S: A000011 OK Completed"
0073                  << "C: A000012 CLOSE"
0074                  << "S: A000012 OK Completed"
0075                  << "C: A000013 DELETE \"INBOX/test1\""
0076                  << "S: * 0 EXISTS"
0077                  << "S: * 0 RECENT"
0078                  << "S: A000013 OK Completed";
0079         callNames.clear();
0080         callNames << QStringLiteral("changeProcessed");
0081 
0082         QTest::newRow("normal case") << collection << scenario << callNames;
0083 
0084         scenario.clear();
0085         scenario << defaultPoolConnectionScenario() << "C: A000003 LSUB \"\" *"
0086                  << "S: * LSUB ( \\HasChildren ) / INBOX"
0087                  << "S: * LSUB ( \\HasChildren ) / INBOX/test1"
0088                  << "S: * LSUB ( ) / INBOX/test1/test2"
0089                  << "S: A000003 OK Completed ( 0.000 secs 26 calls )";
0090         collection.setRemoteId(QStringLiteral("/test1"));
0091         collection.setParentCollection(Akonadi::Collection::root());
0092         callNames.clear();
0093         callNames << QStringLiteral("changeProcessed") << QStringLiteral("emitWarning") << QStringLiteral("synchronizeCollectionTree");
0094         QTest::newRow("invalid collection") << collection << scenario << callNames;
0095 
0096         collection = createCollectionChain(QStringLiteral(".INBOX.test1"));
0097         scenario.clear();
0098         scenario << defaultPoolConnectionScenario() << "C: A000003 LSUB \"\" *"
0099                  << "S: * LSUB ( \\HasChildren ) . INBOX"
0100                  << "S: * LSUB ( \\HasChildren ) . INBOX.test1"
0101                  << "S: * LSUB ( ) . INBOX.test1.test2"
0102                  << "S: A000003 OK Completed ( 0.000 secs 26 calls )"
0103                  << "C: A000004 SELECT \"INBOX.test1.test2\""
0104                  << R"(S: * FLAGS ( \Answered \Flagged \Draft \Deleted \Seen ))"
0105                  << R"(S: * OK [ PERMANENTFLAGS ( \Answered \Flagged \Draft \Deleted \Seen \* )  ])"
0106                  << "S: * 1 EXISTS"
0107                  << "S: * 0 RECENT"
0108                  << "S: * OK [ UNSEEN 1  ]"
0109                  << "S: * OK [ UIDVALIDITY 1292857898  ]"
0110                  << "S: * OK [ UIDNEXT 2  ]"
0111                  << "S: A000004 OK Completed [ READ-WRITE  ]"
0112                  << "C: A000005 STORE 1:* +FLAGS (\\DELETED)"
0113                  << "S: * 1 FETCH ( FLAGS (\\Deleted) ) "
0114                  << "S: A000005 OK Completed"
0115                  << "C: A000006 EXPUNGE"
0116                  << "S: * 1 EXPUNGE"
0117                  << "S: * 0 EXISTS"
0118                  << "S: * 0 RECENT"
0119                  << "S: A000006 OK Completed"
0120                  << "C: A000007 CLOSE"
0121                  << "S: A000007 OK Completed"
0122                  << "C: A000008 DELETE \"INBOX.test1.test2\""
0123                  << "S: * 0 EXISTS"
0124                  << "S: * 0 RECENT"
0125                  << "S: A000008 OK Completed"
0126                  << "C: A000009 SELECT \"INBOX.test1\""
0127                  << R"(S: * FLAGS ( \Answered \Flagged \Draft \Deleted \Seen ))"
0128                  << R"(S: * OK [ PERMANENTFLAGS ( \Answered \Flagged \Draft \Deleted \Seen \* )  ])"
0129                  << "S: * 1 EXISTS"
0130                  << "S: * 1 RECENT"
0131                  << "S: * OK [ UIDVALIDITY 1292857888  ]"
0132                  << "S: * OK [ UIDNEXT 2  ]"
0133                  << "S: A000009 OK Completed [ READ-WRITE  ]"
0134                  << "C: A000010 STORE 1:* +FLAGS (\\DELETED)"
0135                  << R"(S: * 1 FETCH ( FLAGS (\Recent \Deleted \Seen) ))"
0136                  << "S: A000010 OK Completed"
0137                  << "C: A000011 EXPUNGE"
0138                  << "S: * 1 EXPUNGE"
0139                  << "S: * 0 EXISTS"
0140                  << "S: * 0 RECENT"
0141                  << "S: A000011 OK Completed"
0142                  << "C: A000012 CLOSE"
0143                  << "S: A000012 OK Completed"
0144                  << "C: A000013 DELETE \"INBOX.test1\""
0145                  << "S: * 0 EXISTS"
0146                  << "S: * 0 RECENT"
0147                  << "S: A000013 OK Completed";
0148         callNames.clear();
0149         callNames << QStringLiteral("changeProcessed");
0150         QTest::newRow("non-standard separator") << collection << scenario << callNames;
0151 
0152         collection = createCollectionChain(QStringLiteral(".INBOX.test1"));
0153         scenario.clear();
0154         scenario << defaultPoolConnectionScenario() << "C: A000003 LSUB \"\" *"
0155                  << "S: * LSUB ( \\HasChildren ) . INBOX"
0156                  << "S: * LSUB ( \\HasChildren ) . INBOX.test1"
0157                  << "S: * LSUB ( ) . INBOX.test1.test2"
0158                  << "S: A000003 OK Completed ( 0.000 secs 26 calls )"
0159                  << "C: A000004 SELECT \"INBOX.test1.test2\""
0160                  << R"(S: * FLAGS ( \Answered \Flagged \Draft \Deleted \Seen ))"
0161                  << R"(S: * OK [ PERMANENTFLAGS ( \Answered \Flagged \Draft \Deleted \Seen \* )  ])"
0162                  << "S: * 1 EXISTS"
0163                  << "S: * 0 RECENT"
0164                  << "S: * OK [ UNSEEN 1  ]"
0165                  << "S: * OK [ UIDVALIDITY 1292857898  ]"
0166                  << "S: * OK [ UIDNEXT 2  ]"
0167                  << "S: A000004 OK Completed [ READ-WRITE  ]"
0168                  << "C: A000005 STORE 1:* +FLAGS (\\DELETED)"
0169                  << "S: * 1 FETCH ( FLAGS (\\Deleted) ) "
0170                  << "S: A000005 OK Completed"
0171                  << "C: A000006 EXPUNGE"
0172                  << "S: * 1 EXPUNGE"
0173                  << "S: * 0 EXISTS"
0174                  << "S: * 0 RECENT"
0175                  << "S: A000006 OK Completed"
0176                  << "C: A000007 CLOSE"
0177                  << "S: A000007 NO Close failed";
0178         callNames.clear();
0179         callNames << QStringLiteral("changeProcessed") << QStringLiteral("emitWarning") << QStringLiteral("synchronizeCollectionTree");
0180         QTest::newRow("close failed") << collection << scenario << callNames;
0181     }
0182 
0183     void shouldDeleteMailBoxRecursive()
0184     {
0185         QFETCH(Akonadi::Collection, collection);
0186         QFETCH(QList<QByteArray>, scenario);
0187         QFETCH(QStringList, callNames);
0188 
0189         FakeServer server;
0190         server.setScenario(scenario);
0191         server.startAndWait();
0192 
0193         SessionPool pool(1);
0194 
0195         pool.setPasswordRequester(createDefaultRequester());
0196         QVERIFY(pool.connect(createDefaultAccount()));
0197         QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int, QString))));
0198 
0199         DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState);
0200         state->setCollection(collection);
0201         auto task = new RemoveCollectionRecursiveTask(state);
0202         task->start(&pool);
0203         QEventLoop loop;
0204         connect(task, &RemoveCollectionRecursiveTask::destroyed, &loop, &QEventLoop::quit);
0205         loop.exec();
0206 
0207         QCOMPARE(state->calls().count(), callNames.size());
0208         for (int i = 0; i < callNames.size(); i++) {
0209             QString command = QString::fromUtf8(state->calls().at(i).first);
0210             QVariant parameter = state->calls().at(i).second;
0211 
0212             if (command == QLatin1StringView("cancelTask") && callNames[i] != QLatin1StringView("cancelTask")) {
0213                 qDebug() << "Got a cancel:" << parameter.toString();
0214             }
0215 
0216             QCOMPARE(command, callNames[i]);
0217 
0218             if (command == QLatin1StringView("cancelTask")) {
0219                 QVERIFY(!parameter.toString().isEmpty());
0220             }
0221         }
0222 
0223         QVERIFY(server.isAllScenarioDone());
0224 
0225         server.quit();
0226     }
0227 };
0228 
0229 QTEST_GUILESS_MAIN(TestRemoveCollectionRecursiveTask)
0230 
0231 #include "testremovecollectionrecursivetask.moc"