File indexing completed on 2025-03-09 04:47:29

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 "movecollectiontask.h"
0011 #include <QTest>
0012 class TestMoveCollectionTask : public ImapTestBase
0013 {
0014     Q_OBJECT
0015 
0016 private Q_SLOTS:
0017     void shouldRenameMailBox_data()
0018     {
0019         QTest::addColumn<Akonadi::Collection>("collection");
0020         QTest::addColumn<Akonadi::Collection>("source");
0021         QTest::addColumn<Akonadi::Collection>("target");
0022         QTest::addColumn<QList<QByteArray>>("scenario");
0023         QTest::addColumn<QStringList>("callNames");
0024 
0025         Akonadi::Collection root;
0026         Akonadi::Collection inbox;
0027         Akonadi::Collection collection;
0028         Akonadi::Collection source;
0029         Akonadi::Collection target;
0030         QList<QByteArray> scenario;
0031         QStringList callNames;
0032 
0033         root = createCollectionChain(QString());
0034         inbox = createCollectionChain(QStringLiteral("/INBOX"));
0035 
0036         source = Akonadi::Collection(3);
0037         source.setRemoteId(QStringLiteral("/Foo"));
0038         source.setParentCollection(inbox);
0039 
0040         collection = Akonadi::Collection(10);
0041         collection.setRemoteId(QStringLiteral("/Baz"));
0042         collection.setParentCollection(source);
0043 
0044         target = Akonadi::Collection(4);
0045         target.setRemoteId(QStringLiteral("/Bar"));
0046         target.setParentCollection(inbox);
0047 
0048         scenario.clear();
0049         scenario << defaultPoolConnectionScenario() << R"(C: A000003 RENAME "INBOX/Foo/Baz" "INBOX/Bar/Baz")"
0050                  << "S: A000003 OK rename done"
0051                  << "C: A000004 SUBSCRIBE \"INBOX/Bar/Baz\""
0052                  << "S: A000004 OK subscribe done";
0053 
0054         callNames.clear();
0055         callNames << QStringLiteral("collectionChangeCommitted");
0056 
0057         QTest::newRow("moving mailbox") << collection << source << target << scenario << callNames;
0058 
0059         {
0060             const Akonadi::Collection toplevel = createCollectionChain(QStringLiteral("/Bar"));
0061 
0062             scenario.clear();
0063             scenario << defaultPoolConnectionScenario() << R"(C: A000003 RENAME "Bar" "INBOX/Bar")"
0064                      << "S: A000003 OK rename done"
0065                      << "C: A000004 SUBSCRIBE \"INBOX/Bar\""
0066                      << "S: A000004 OK subscribe done";
0067 
0068             callNames.clear();
0069             callNames << QStringLiteral("collectionChangeCommitted");
0070 
0071             QTest::newRow("move mailbox from toplevel") << toplevel << root << inbox << scenario << callNames;
0072         }
0073 
0074         {
0075             const Akonadi::Collection toplevel = createCollectionChain(QStringLiteral("/INBOX/Bar"));
0076 
0077             scenario.clear();
0078             scenario << defaultPoolConnectionScenario() << R"(C: A000003 RENAME "INBOX/Bar" "Bar")"
0079                      << "S: A000003 OK rename done"
0080                      << "C: A000004 SUBSCRIBE \"Bar\""
0081                      << "S: A000004 OK subscribe done";
0082 
0083             callNames.clear();
0084             callNames << QStringLiteral("collectionChangeCommitted");
0085 
0086             QTest::newRow("move mailbox to toplevel") << toplevel << inbox << root << scenario << callNames;
0087         }
0088 
0089         // Same collections
0090         // The scenario changes though
0091 
0092         scenario.clear();
0093         scenario << defaultPoolConnectionScenario() << R"(C: A000003 RENAME "INBOX/Foo/Baz" "INBOX/Bar/Baz")"
0094                  << "S: A000003 OK rename done"
0095                  << "C: A000004 SUBSCRIBE \"INBOX/Bar/Baz\""
0096                  << "S: A000004 NO subscribe failed";
0097 
0098         callNames.clear();
0099         callNames << QStringLiteral("emitWarning") << QStringLiteral("collectionChangeCommitted");
0100 
0101         QTest::newRow("moving mailbox, subscribe fails") << collection << source << target << scenario << callNames;
0102 
0103         inbox = createCollectionChain(QStringLiteral(".INBOX"));
0104 
0105         source = Akonadi::Collection(3);
0106         source.setRemoteId(QStringLiteral(".Foo"));
0107         source.setParentCollection(inbox);
0108 
0109         collection = Akonadi::Collection(10);
0110         collection.setRemoteId(QStringLiteral(".Baz"));
0111         collection.setParentCollection(source);
0112 
0113         target = Akonadi::Collection(4);
0114         target.setRemoteId(QStringLiteral(".Bar"));
0115         target.setParentCollection(inbox);
0116 
0117         scenario.clear();
0118         scenario << defaultPoolConnectionScenario() << R"(C: A000003 RENAME "INBOX.Foo.Baz" "INBOX.Bar.Baz")"
0119                  << "S: A000003 OK rename done"
0120                  << "C: A000004 SUBSCRIBE \"INBOX.Bar.Baz\""
0121                  << "S: A000004 OK subscribe done";
0122 
0123         callNames.clear();
0124         callNames << QStringLiteral("collectionChangeCommitted");
0125 
0126         QTest::newRow("moving mailbox with non-standard separators") << collection << source << target << scenario << callNames;
0127     }
0128 
0129     void shouldRenameMailBox()
0130     {
0131         QFETCH(Akonadi::Collection, collection);
0132         QFETCH(Akonadi::Collection, source);
0133         QFETCH(Akonadi::Collection, target);
0134         QFETCH(QList<QByteArray>, scenario);
0135         QFETCH(QStringList, callNames);
0136 
0137         FakeServer server;
0138         server.setScenario(scenario);
0139         server.startAndWait();
0140 
0141         SessionPool pool(1);
0142 
0143         pool.setPasswordRequester(createDefaultRequester());
0144         QVERIFY(pool.connect(createDefaultAccount()));
0145         QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int, QString))));
0146 
0147         DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState);
0148         state->setCollection(collection);
0149         state->setSourceCollection(source);
0150         state->setTargetCollection(target);
0151         auto task = new MoveCollectionTask(state);
0152         task->start(&pool);
0153 
0154         QTRY_COMPARE(state->calls().count(), callNames.size());
0155         for (int i = 0; i < callNames.size(); i++) {
0156             QString command = QString::fromUtf8(state->calls().at(i).first);
0157             QVariant parameter = state->calls().at(i).second;
0158 
0159             if (command == QLatin1StringView("cancelTask") && callNames[i] != QLatin1StringView("cancelTask")) {
0160                 qDebug() << "Got a cancel:" << parameter.toString();
0161             }
0162 
0163             QCOMPARE(command, callNames[i]);
0164 
0165             if (command == QLatin1StringView("cancelTask")) {
0166                 QVERIFY(!parameter.toString().isEmpty());
0167             }
0168         }
0169 
0170         QVERIFY(server.isAllScenarioDone());
0171 
0172         server.quit();
0173     }
0174 };
0175 
0176 QTEST_GUILESS_MAIN(TestMoveCollectionTask)
0177 
0178 #include "testmovecollectiontask.moc"