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

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 "addcollectiontask.h"
0011 #include <Akonadi/CollectionAnnotationsAttribute>
0012 #include <QDebug>
0013 #include <QTest>
0014 class TestAddCollectionTask : public ImapTestBase
0015 {
0016     Q_OBJECT
0017 
0018 private Q_SLOTS:
0019     void shouldCreateAndSubscribe_data()
0020     {
0021         QTest::addColumn<Akonadi::Collection>("parentCollection");
0022         QTest::addColumn<Akonadi::Collection>("collection");
0023         QTest::addColumn<QList<QByteArray>>("scenario");
0024         QTest::addColumn<QStringList>("callNames");
0025         QTest::addColumn<QString>("collectionName");
0026         QTest::addColumn<QString>("remoteId");
0027 
0028         Akonadi::Collection parentCollection;
0029         Akonadi::Collection collection;
0030         QList<QByteArray> scenario;
0031         QStringList callNames;
0032 
0033         parentCollection = createCollectionChain(QStringLiteral("/INBOX/Foo"));
0034         collection = Akonadi::Collection(4);
0035         collection.setName(QStringLiteral("Bar"));
0036         collection.setParentCollection(parentCollection);
0037 
0038         scenario.clear();
0039         scenario << defaultPoolConnectionScenario() << "C: A000003 CREATE \"INBOX/Foo/Bar\""
0040                  << "S: A000003 OK create done"
0041                  << "C: A000004 SUBSCRIBE \"INBOX/Foo/Bar\""
0042                  << "S: A000004 OK subscribe done";
0043 
0044         callNames.clear();
0045         callNames << QStringLiteral("collectionChangeCommitted") << QStringLiteral("synchronizeCollectionTree");
0046 
0047         QTest::newRow("trivial case") << parentCollection << collection << scenario << callNames << collection.name() << "/Bar";
0048 
0049         parentCollection = createCollectionChain(QStringLiteral("/INBOX/Foo"));
0050         collection = Akonadi::Collection(4);
0051         collection.setName(QStringLiteral("Bar/Baz"));
0052         collection.setParentCollection(parentCollection);
0053 
0054         scenario.clear();
0055         scenario << defaultPoolConnectionScenario() << "C: A000003 CREATE \"INBOX/Foo/BarBaz\""
0056                  << "S: A000003 OK create done"
0057                  << "C: A000004 SUBSCRIBE \"INBOX/Foo/BarBaz\""
0058                  << "S: A000004 OK subscribe done";
0059 
0060         callNames.clear();
0061         callNames << QStringLiteral("collectionChangeCommitted") << QStringLiteral("synchronizeCollectionTree");
0062 
0063         QTest::newRow("folder with invalid separator") << parentCollection << collection << scenario << callNames << "BarBaz"
0064                                                        << "/BarBaz";
0065 
0066         parentCollection = createCollectionChain(QStringLiteral(".INBOX"));
0067         collection = Akonadi::Collection(3);
0068         collection.setName(QStringLiteral("Foo"));
0069         collection.setParentCollection(parentCollection);
0070 
0071         scenario.clear();
0072         scenario << defaultPoolConnectionScenario() << "C: A000003 CREATE \"INBOX.Foo\""
0073                  << "S: A000003 OK create done"
0074                  << "C: A000004 SUBSCRIBE \"INBOX.Foo\""
0075                  << "S: A000004 OK subscribe done";
0076         callNames.clear();
0077         callNames << QStringLiteral("collectionChangeCommitted") << QStringLiteral("synchronizeCollectionTree");
0078 
0079         QTest::newRow("folder with non-standard separator") << parentCollection << collection << scenario << callNames << "Foo"
0080                                                             << ".Foo";
0081 
0082         parentCollection = createCollectionChain(QStringLiteral("/INBOX/Foo"));
0083         collection = Akonadi::Collection(4);
0084         collection.setName(QStringLiteral("Bar"));
0085         collection.setParentCollection(parentCollection);
0086         auto attr = collection.attribute<Akonadi::CollectionAnnotationsAttribute>(Akonadi::Collection::AddIfMissing);
0087         QMap<QByteArray, QByteArray> annotations;
0088         annotations.insert("/shared/vendor/foobar/foo", "value");
0089         attr->setAnnotations(annotations);
0090 
0091         scenario.clear();
0092         scenario << defaultPoolConnectionScenario() << "C: A000003 CREATE \"INBOX/Foo/Bar\""
0093                  << "S: A000003 OK create done"
0094                  << "C: A000004 SUBSCRIBE \"INBOX/Foo/Bar\""
0095                  << "S: A000004 OK subscribe done"
0096                  << R"(C: A000005 SETMETADATA "INBOX/Foo/Bar" ("/shared/vendor/foobar/foo" "value"))"
0097                  << "S: A000005 OK SETMETADATA complete";
0098 
0099         callNames.clear();
0100         callNames << QStringLiteral("collectionChangeCommitted");
0101 
0102         QTest::newRow("folder with annotations") << parentCollection << collection << scenario << callNames << collection.name() << "/Bar";
0103     }
0104 
0105     void shouldCreateAndSubscribe()
0106     {
0107         QFETCH(Akonadi::Collection, parentCollection);
0108         QFETCH(Akonadi::Collection, collection);
0109         QFETCH(QList<QByteArray>, scenario);
0110         QFETCH(QStringList, callNames);
0111         QFETCH(QString, collectionName);
0112         QFETCH(QString, remoteId);
0113 
0114         FakeServer server;
0115         server.setScenario(scenario);
0116         server.startAndWait();
0117 
0118         SessionPool pool(1);
0119 
0120         pool.setPasswordRequester(createDefaultRequester());
0121         QVERIFY(pool.connect(createDefaultAccount()));
0122         QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int, QString))));
0123 
0124         DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState);
0125         state->setParentCollection(parentCollection);
0126         state->setCollection(collection);
0127         if (collection.hasAttribute<Akonadi::CollectionAnnotationsAttribute>()) {
0128             state->setServerCapabilities(QStringList() << QStringLiteral("METADATA"));
0129         }
0130         auto task = new AddCollectionTask(state);
0131         task->start(&pool);
0132 
0133         QTRY_COMPARE(state->calls().count(), callNames.size());
0134         for (int i = 0; i < callNames.size(); i++) {
0135             QString command = QString::fromUtf8(state->calls().at(i).first);
0136             QVariant parameter = state->calls().at(i).second;
0137 
0138             if (command == QLatin1StringView("cancelTask") && callNames[i] != QLatin1StringView("cancelTask")) {
0139                 qDebug() << "Got a cancel:" << parameter.toString();
0140             }
0141 
0142             if (command == QLatin1StringView("collectionChangeCommitted")) {
0143                 QCOMPARE(parameter.value<Akonadi::Collection>().name(), collectionName);
0144                 QCOMPARE(parameter.value<Akonadi::Collection>().remoteId().right(collectionName.length()), collectionName);
0145                 QCOMPARE(parameter.value<Akonadi::Collection>().remoteId(), remoteId);
0146             }
0147 
0148             QCOMPARE(command, callNames[i]);
0149 
0150             if (command == QLatin1StringView("cancelTask")) {
0151                 QVERIFY(!parameter.toString().isEmpty());
0152             }
0153         }
0154 
0155         QVERIFY(server.isAllScenarioDone());
0156 
0157         server.quit();
0158     }
0159 };
0160 
0161 QTEST_GUILESS_MAIN(TestAddCollectionTask)
0162 
0163 #include "testaddcollectiontask.moc"