File indexing completed on 2024-11-10 04:40:15

0001 /*
0002     SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "protocolhelper.cpp"
0008 #include "attributestorage.cpp"
0009 #include "qtest_akonadi.h"
0010 
0011 using namespace Akonadi;
0012 
0013 Q_DECLARE_METATYPE(Scope)
0014 Q_DECLARE_METATYPE(QList<Protocol::Ancestor>)
0015 Q_DECLARE_METATYPE(Protocol::ItemFetchScope)
0016 
0017 class ProtocolHelperTest : public QObject
0018 {
0019     Q_OBJECT
0020 private Q_SLOTS:
0021     void testItemSetToByteArray_data()
0022     {
0023         QTest::addColumn<Item::List>("items");
0024         QTest::addColumn<Scope>("result");
0025         QTest::addColumn<bool>("shouldThrow");
0026 
0027         Item u1;
0028         u1.setId(1);
0029         Item u2;
0030         u2.setId(2);
0031         Item u3;
0032         u3.setId(3);
0033         Item r1;
0034         r1.setRemoteId(QStringLiteral("A"));
0035         Item r2;
0036         r2.setRemoteId(QStringLiteral("B"));
0037         Item h1;
0038         h1.setRemoteId(QStringLiteral("H1"));
0039         h1.setParentCollection(Collection::root());
0040         Item h2;
0041         h2.setRemoteId(QStringLiteral("H2a"));
0042         h2.parentCollection().setRemoteId(QStringLiteral("H2b"));
0043         h2.parentCollection().setParentCollection(Collection::root());
0044         Item h3;
0045         h3.setRemoteId(QStringLiteral("H3a"));
0046         h3.parentCollection().setRemoteId(QStringLiteral("H3b"));
0047 
0048         QTest::newRow("empty") << Item::List() << Scope() << true;
0049         QTest::newRow("single uid") << (Item::List() << u1) << Scope(1) << false;
0050         QTest::newRow("multi uid") << (Item::List() << u1 << u3) << Scope(QList<qint64>{1, 3}) << false;
0051         QTest::newRow("block uid") << (Item::List() << u1 << u2 << u3) << Scope(ImapInterval(1, 3)) << false;
0052         QTest::newRow("single rid") << (Item::List() << r1) << Scope(Scope::Rid, {QStringLiteral("A")}) << false;
0053         QTest::newRow("multi rid") << (Item::List() << r1 << r2) << Scope(Scope::Rid, {QStringLiteral("A"), QStringLiteral("B")}) << false;
0054         QTest::newRow("invalid") << (Item::List() << Item()) << Scope() << true;
0055         QTest::newRow("mixed") << (Item::List() << u1 << r1) << Scope() << true;
0056         QTest::newRow("single hrid") << (Item::List() << h1) << Scope({Scope::HRID(-1, QStringLiteral("H1")), Scope::HRID(0)}) << false;
0057         QTest::newRow("single hrid 2") << (Item::List() << h2)
0058                                        << Scope({Scope::HRID(-1, QStringLiteral("H2a")), Scope::HRID(-2, QStringLiteral("H2b")), Scope::HRID(0)}) << false;
0059         QTest::newRow("mixed hrid/rid") << (Item::List() << h1 << r1) << Scope(Scope::Rid, {QStringLiteral("H1"), QStringLiteral("A")}) << false;
0060         QTest::newRow("unterminated hrid") << (Item::List() << h3) << Scope(Scope::Rid, {QStringLiteral("H3a")}) << false;
0061     }
0062 
0063     void testItemSetToByteArray()
0064     {
0065         QFETCH(Item::List, items);
0066         QFETCH(Scope, result);
0067         QFETCH(bool, shouldThrow);
0068 
0069         bool didThrow = false;
0070         try {
0071             const Scope scope = ProtocolHelper::entitySetToScope(items);
0072             QCOMPARE(scope, result);
0073         } catch (const std::exception &e) {
0074             qDebug() << e.what();
0075             didThrow = true;
0076         }
0077         QCOMPARE(didThrow, shouldThrow);
0078     }
0079 
0080     void testAncestorParsing_data()
0081     {
0082         QTest::addColumn<QList<Protocol::Ancestor>>("input");
0083         QTest::addColumn<Collection>("parent");
0084 
0085         QTest::newRow("top-level") << QList<Protocol::Ancestor>{Protocol::Ancestor(0)} << Collection::root();
0086 
0087         Protocol::Ancestor a1(42);
0088         a1.setRemoteId(QStringLiteral("net"));
0089 
0090         Collection c1;
0091         c1.setRemoteId(QStringLiteral("net"));
0092         c1.setId(42);
0093         c1.setParentCollection(Collection::root());
0094         QTest::newRow("till's obscure folder") << QList<Protocol::Ancestor>{a1, Protocol::Ancestor(0)} << c1;
0095     }
0096 
0097     void testAncestorParsing()
0098     {
0099         QFETCH(QList<Protocol::Ancestor>, input);
0100         QFETCH(Collection, parent);
0101 
0102         Item i;
0103         ProtocolHelper::parseAncestors(input, &i);
0104         QCOMPARE(i.parentCollection().id(), parent.id());
0105         QCOMPARE(i.parentCollection().remoteId(), parent.remoteId());
0106     }
0107 
0108     void testCollectionParsing_data()
0109     {
0110         QTest::addColumn<Protocol::FetchCollectionsResponse>("input");
0111         QTest::addColumn<Collection>("collection");
0112 
0113         Collection c1;
0114         c1.setId(2);
0115         c1.setRemoteId(QStringLiteral("r2"));
0116         c1.parentCollection().setId(1);
0117         c1.setName(QStringLiteral("n2"));
0118 
0119         {
0120             Protocol::FetchCollectionsResponse resp(2);
0121             resp.setParentId(1);
0122             resp.setRemoteId(QStringLiteral("r2"));
0123             resp.setName(QStringLiteral("n2"));
0124             QTest::newRow("no ancestors") << resp << c1;
0125         }
0126 
0127         {
0128             Protocol::FetchCollectionsResponse resp(3);
0129             resp.setParentId(2);
0130             resp.setRemoteId(QStringLiteral("r3"));
0131             resp.setAncestors({Protocol::Ancestor(2, QStringLiteral("r2")), Protocol::Ancestor(1, QStringLiteral("r1")), Protocol::Ancestor(0)});
0132 
0133             Collection c2;
0134             c2.setId(3);
0135             c2.setRemoteId(QStringLiteral("r3"));
0136             c2.parentCollection().setId(2);
0137             c2.parentCollection().setRemoteId(QStringLiteral("r2"));
0138             c2.parentCollection().parentCollection().setId(1);
0139             c2.parentCollection().parentCollection().setRemoteId(QStringLiteral("r1"));
0140             c2.parentCollection().parentCollection().setParentCollection(Collection::root());
0141             QTest::newRow("ancestors") << resp << c2;
0142         }
0143     }
0144 
0145     void testCollectionParsing()
0146     {
0147         QFETCH(Protocol::FetchCollectionsResponse, input);
0148         QFETCH(Collection, collection);
0149 
0150         Collection parsedCollection = ProtocolHelper::parseCollection(input);
0151 
0152         QCOMPARE(parsedCollection.name(), collection.name());
0153 
0154         while (collection.isValid() || parsedCollection.isValid()) {
0155             QCOMPARE(parsedCollection.id(), collection.id());
0156             QCOMPARE(parsedCollection.remoteId(), collection.remoteId());
0157             const Collection p1(parsedCollection.parentCollection());
0158             const Collection p2(collection.parentCollection());
0159             parsedCollection = p1;
0160             collection = p2;
0161             qDebug() << p1.isValid() << p2.isValid();
0162         }
0163     }
0164 
0165     void testParentCollectionAfterCollectionParsing()
0166     {
0167         Protocol::FetchCollectionsResponse resp(111);
0168         resp.setParentId(222);
0169         resp.setRemoteId(QStringLiteral("A"));
0170         resp.setAncestors({Protocol::Ancestor(222), Protocol::Ancestor(333), Protocol::Ancestor(0)});
0171 
0172         Collection parsedCollection = ProtocolHelper::parseCollection(resp);
0173 
0174         QList<qint64> ids;
0175         ids << 111 << 222 << 333 << 0;
0176         int i = 0;
0177 
0178         Collection col = parsedCollection;
0179         while (col.isValid()) {
0180             QCOMPARE(col.id(), ids[i++]);
0181             col = col.parentCollection();
0182         }
0183         QCOMPARE(i, 4);
0184     }
0185 
0186     void testHRidToScope_data()
0187     {
0188         QTest::addColumn<Collection>("collection");
0189         QTest::addColumn<Scope>("result");
0190 
0191         QTest::newRow("empty") << Collection() << Scope();
0192 
0193         {
0194             Scope scope;
0195             scope.setHRidChain({Scope::HRID(0)});
0196             QTest::newRow("root") << Collection::root() << scope;
0197         }
0198 
0199         Collection c;
0200         c.setId(1);
0201         c.setParentCollection(Collection::root());
0202         c.setRemoteId(QStringLiteral("r1"));
0203         {
0204             Scope scope;
0205             scope.setHRidChain({Scope::HRID(1, QStringLiteral("r1")), Scope::HRID(0)});
0206             QTest::newRow("one level") << c << scope;
0207         }
0208 
0209         {
0210             Collection c2;
0211             c2.setId(2);
0212             c2.setParentCollection(c);
0213             c2.setRemoteId(QStringLiteral("r2"));
0214 
0215             Scope scope;
0216             scope.setHRidChain({Scope::HRID(2, QStringLiteral("r2")), Scope::HRID(1, QStringLiteral("r1")), Scope::HRID(0)});
0217             QTest::newRow("two level ok") << c2 << scope;
0218         }
0219     }
0220 
0221     void testHRidToScope()
0222     {
0223         QFETCH(Collection, collection);
0224         QFETCH(Scope, result);
0225         QCOMPARE(ProtocolHelper::hierarchicalRidToScope(collection), result);
0226     }
0227 
0228     void testItemFetchScopeToProtocol_data()
0229     {
0230         QTest::addColumn<ItemFetchScope>("scope");
0231         QTest::addColumn<Protocol::ItemFetchScope>("result");
0232 
0233         {
0234             Protocol::ItemFetchScope fs;
0235             fs.setFetch(Protocol::ItemFetchScope::Flags | Protocol::ItemFetchScope::Size | Protocol::ItemFetchScope::RemoteID
0236                         | Protocol::ItemFetchScope::RemoteRevision | Protocol::ItemFetchScope::MTime);
0237             QTest::newRow("empty") << ItemFetchScope() << fs;
0238         }
0239 
0240         {
0241             ItemFetchScope scope;
0242             scope.fetchAllAttributes();
0243             scope.fetchFullPayload();
0244             scope.setAncestorRetrieval(Akonadi::ItemFetchScope::All);
0245             scope.setIgnoreRetrievalErrors(true);
0246 
0247             Protocol::ItemFetchScope fs;
0248             fs.setFetch(Protocol::ItemFetchScope::FullPayload | Protocol::ItemFetchScope::AllAttributes | Protocol::ItemFetchScope::Flags
0249                         | Protocol::ItemFetchScope::Size | Protocol::ItemFetchScope::RemoteID | Protocol::ItemFetchScope::RemoteRevision
0250                         | Protocol::ItemFetchScope::MTime | Protocol::ItemFetchScope::IgnoreErrors);
0251             fs.setAncestorDepth(Protocol::ItemFetchScope::AllAncestors);
0252             QTest::newRow("full") << scope << fs;
0253         }
0254 
0255         {
0256             ItemFetchScope scope;
0257             scope.setFetchModificationTime(false);
0258             scope.setFetchRemoteIdentification(false);
0259 
0260             Protocol::ItemFetchScope fs;
0261             fs.setFetch(Protocol::ItemFetchScope::Flags | Protocol::ItemFetchScope::Size);
0262             QTest::newRow("minimal") << scope << fs;
0263         }
0264     }
0265 
0266     void testItemFetchScopeToProtocol()
0267     {
0268         QFETCH(ItemFetchScope, scope);
0269         QFETCH(Protocol::ItemFetchScope, result);
0270         QCOMPARE(ProtocolHelper::itemFetchScopeToProtocol(scope), result);
0271     }
0272 
0273     void testTagParsing_data()
0274     {
0275         QTest::addColumn<Protocol::FetchTagsResponse>("input");
0276         QTest::addColumn<Tag>("expected");
0277 
0278         QTest::newRow("invalid") << Protocol::FetchTagsResponse(-1) << Tag();
0279 
0280         Protocol::FetchTagsResponse response(15);
0281         response.setGid("TAG13GID");
0282         response.setRemoteId("TAG13RID");
0283         response.setParentId(-1);
0284         response.setType("PLAIN");
0285         response.setAttributes({{"TAGAttribute", "MyAttribute"}});
0286 
0287         Tag tag(15);
0288         tag.setGid("TAG13GID");
0289         tag.setRemoteId("TAG13RID");
0290         tag.setType("PLAIN");
0291         auto attr = AttributeFactory::createAttribute("TAGAttribute");
0292         attr->deserialize("MyAttribute");
0293         tag.addAttribute(attr);
0294         QTest::newRow("valid with invalid parent") << response << tag;
0295 
0296         response.setParentId(15);
0297         tag.setParent(Tag(15));
0298         QTest::newRow("valid with valid parent") << response << tag;
0299     }
0300 
0301     void testTagParsing()
0302     {
0303         QFETCH(Protocol::FetchTagsResponse, input);
0304         QFETCH(Tag, expected);
0305 
0306         const Tag tag = ProtocolHelper::parseTagFetchResult(input);
0307         QCOMPARE(tag.id(), expected.id());
0308         QCOMPARE(tag.gid(), expected.gid());
0309         QCOMPARE(tag.remoteId(), expected.remoteId());
0310         QCOMPARE(tag.type(), expected.type());
0311         QCOMPARE(tag.parent(), expected.parent());
0312         QCOMPARE(tag.attributes().size(), expected.attributes().size());
0313         for (int i = 0; i < tag.attributes().size(); ++i) {
0314             Attribute *attr = tag.attributes().at(i);
0315             Attribute *expectedAttr = expected.attributes().at(i);
0316             QCOMPARE(attr->type(), expectedAttr->type());
0317             QCOMPARE(attr->serialized(), expectedAttr->serialized());
0318         }
0319     }
0320 };
0321 
0322 QTEST_MAIN(ProtocolHelperTest)
0323 
0324 #include "protocolhelpertest.moc"