File indexing completed on 2025-01-05 04:58:36

0001 
0002 #include <QTest>
0003 
0004 
0005 #include "common/resourcecontrol.h"
0006 #include "common/secretstore.h"
0007 #include "common/store.h"
0008 #include "common/test.h"
0009 #include <KDAV2/DavItem>
0010 #include <KDAV2/DavUrl>
0011 #include <KDAV2/DavItemCreateJob>
0012 #include <KDAV2/DavCollectionsFetchJob>
0013 #include <KDAV2/DavCollectionCreateJob>
0014 #include <KDAV2/DavCollection>
0015 #include <KContacts/Addressee>
0016 #include <KContacts/VCardConverter>
0017 
0018 
0019 using Sink::ApplicationDomain::Addressbook;
0020 using Sink::ApplicationDomain::Contact;
0021 using Sink::ApplicationDomain::SinkResource;
0022 
0023 class CardDavTest : public QObject
0024 {
0025     Q_OBJECT
0026 
0027     SinkResource createResource()
0028     {
0029         auto resource = Sink::ApplicationDomain::CardDavResource::create("account1");
0030         resource.setProperty("server", "http://localhost");
0031         resource.setProperty("username", "doe");
0032         Sink::SecretStore::instance().insert(resource.identifier(), "doe");
0033         return resource;
0034     }
0035 
0036 
0037     QByteArray mResourceInstanceIdentifier;
0038 
0039     void createContact(const QString &firstname, const QString &lastname, const QString &collectionName)
0040     {
0041         QUrl mainUrl(QStringLiteral("http://localhost/dav/addressbooks/user/doe"));
0042         mainUrl.setUserName(QStringLiteral("doe"));
0043         mainUrl.setPassword(QStringLiteral("doe"));
0044 
0045         KDAV2::DavUrl davUrl(mainUrl, KDAV2::CardDav);
0046 
0047         auto *job = new KDAV2::DavCollectionsFetchJob(davUrl);
0048         job->exec();
0049 
0050         const auto collectionUrl = [&] {
0051             for (const auto &col : job->collections()) {
0052                 if (col.displayName() == collectionName) {
0053                     return col.url().url();
0054                 }
0055             }
0056             return QUrl{};
0057         }();
0058 
0059 
0060         QUrl url{collectionUrl.toString() + firstname + lastname + ".vcf"};
0061         url.setUserInfo(mainUrl.userInfo());
0062         KDAV2::DavUrl testItemUrl(url, KDAV2::CardDav);
0063         QByteArray data = QString("BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Kolab//iRony DAV Server 0.3.1//Sabre//Sabre VObject 2.1.7//EN\r\nUID:12345678-1234-1234-%1-%2\r\nFN:%1 %2\r\nN:%2;%1;;;\r\nEMAIL;TYPE=INTERNET;TYPE=HOME:%1.%2@example.com\r\nREV;VALUE=DATE-TIME:20161221T145611Z\r\nEND:VCARD\r\n").arg(firstname).arg(lastname).toUtf8();
0064         KDAV2::DavItem item(testItemUrl, QStringLiteral("text/vcard"), data, QString());
0065         auto createJob = new KDAV2::DavItemCreateJob(item);
0066         createJob->exec();
0067         if (createJob->error()) {
0068             qWarning() << createJob->errorString();
0069         }
0070     }
0071 
0072     void createCollection(const QString &name)
0073     {
0074         QUrl mainUrl(QStringLiteral("http://localhost/dav/addressbooks/user/doe/") + name);
0075         mainUrl.setUserName(QStringLiteral("doe"));
0076         mainUrl.setPassword(QStringLiteral("doe"));
0077 
0078         KDAV2::DavUrl davUrl(mainUrl, KDAV2::CardDav);
0079         KDAV2::DavCollection collection{davUrl, name, KDAV2::DavCollection::Contacts};
0080 
0081         auto createJob = new KDAV2::DavCollectionCreateJob(collection);
0082         createJob->exec();
0083         if (createJob->error()) {
0084             qWarning() << createJob->errorString();
0085         }
0086     }
0087 
0088     void resetTestEnvironment()
0089     {
0090         system("resetmailbox.sh");
0091     }
0092 
0093 private slots:
0094 
0095     void initTestCase()
0096     {
0097         Sink::Test::initTest();
0098         resetTestEnvironment();
0099         auto resource = createResource();
0100         QVERIFY(!resource.identifier().isEmpty());
0101         VERIFYEXEC(Sink::Store::create(resource));
0102         mResourceInstanceIdentifier = resource.identifier();
0103     }
0104 
0105     void cleanup()
0106     {
0107         VERIFYEXEC(Sink::Store::removeDataFromDisk(mResourceInstanceIdentifier));
0108     }
0109 
0110     void init()
0111     {
0112         VERIFYEXEC(Sink::ResourceControl::start(mResourceInstanceIdentifier));
0113     }
0114 
0115     void testSyncAddressbooks()
0116     {
0117         createCollection("addressbook2");
0118 
0119         Sink::SyncScope scope;
0120         scope.setType<Addressbook>();
0121         scope.resourceFilter(mResourceInstanceIdentifier);
0122 
0123         VERIFYEXEC(Sink::Store::synchronize(scope));
0124         VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(mResourceInstanceIdentifier));
0125         const auto addressbooks = Sink::Store::read<Addressbook>(Sink::Query().resourceFilter(mResourceInstanceIdentifier));
0126         QCOMPARE(addressbooks.size(), 2);
0127     }
0128 
0129     void testSyncContacts()
0130     {
0131         createContact("john", "doe", "personal");
0132         createContact("jane", "doe", "personal");
0133         createContact("fred", "durst", "addressbook2");
0134         Sink::SyncScope scope;
0135         scope.resourceFilter(mResourceInstanceIdentifier);
0136 
0137         VERIFYEXEC(Sink::Store::synchronize(scope));
0138         VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(mResourceInstanceIdentifier));
0139         const auto contacts = Sink::Store::read<Sink::ApplicationDomain::Contact>(Sink::Query().resourceFilter(mResourceInstanceIdentifier));
0140         QCOMPARE(contacts.size(), 3);
0141 
0142         //Ensure a resync works
0143         {
0144             VERIFYEXEC(Sink::Store::synchronize(scope));
0145             VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(mResourceInstanceIdentifier));
0146             const auto contacts = Sink::Store::read<Sink::ApplicationDomain::Contact>(Sink::Query().resourceFilter(mResourceInstanceIdentifier));
0147             QCOMPARE(contacts.size(), 3);
0148         }
0149 
0150         //Ensure a resync after another creation works
0151         createContact("alf", "alf", "addressbook2");
0152         {
0153             VERIFYEXEC(Sink::Store::synchronize(scope));
0154             VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(mResourceInstanceIdentifier));
0155             const auto contacts = Sink::Store::read<Sink::ApplicationDomain::Contact>(Sink::Query().resourceFilter(mResourceInstanceIdentifier));
0156             QCOMPARE(contacts.size(), 4);
0157         }
0158     }
0159 
0160     void testAddModifyRemoveContact()
0161     {
0162         auto createVCard = [] (const QString &firstname, const QString &uid) {
0163             KContacts::Addressee addressee;
0164             addressee.setGivenName(firstname);
0165             addressee.setFamilyName("Doe");
0166             addressee.setFormattedName("John Doe");
0167             addressee.setUid(uid);
0168             return KContacts::VCardConverter{}.createVCard(addressee, KContacts::VCardConverter::v3_0);
0169         };
0170 
0171 
0172         Sink::SyncScope scope;
0173         scope.setType<Addressbook>();
0174         scope.resourceFilter(mResourceInstanceIdentifier);
0175 
0176         VERIFYEXEC(Sink::Store::synchronize(scope));
0177         VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(mResourceInstanceIdentifier));
0178 
0179         auto addressbooks = Sink::Store::read<Addressbook>(Sink::Query().resourceFilter(mResourceInstanceIdentifier));
0180         QVERIFY(!addressbooks.isEmpty());
0181 
0182 
0183         auto addedUid = QUuid::createUuid().toString();
0184         auto contact = Sink::ApplicationDomain::ApplicationDomainType::createEntity<Sink::ApplicationDomain::Contact>(mResourceInstanceIdentifier);
0185         contact.setVcard(createVCard("John", addedUid));
0186         contact.setAddressbook(addressbooks.first());
0187 
0188         {
0189             VERIFYEXEC(Sink::Store::create(contact));
0190             VERIFYEXEC(Sink::ResourceControl::flushReplayQueue(mResourceInstanceIdentifier));
0191 
0192             auto contacts = Sink::Store::read<Contact>(Sink::Query().filter("uid", Sink::Query::Comparator(addedUid)));
0193             QCOMPARE(contacts.size(), 1);
0194             QCOMPARE(contacts.first().getFirstname(), QLatin1String{"John"});
0195         }
0196 
0197 
0198         {
0199             contact.setVcard(createVCard("Jane", addedUid));
0200             VERIFYEXEC(Sink::Store::modify(contact));
0201             VERIFYEXEC(Sink::ResourceControl::flushReplayQueue(mResourceInstanceIdentifier));
0202             VERIFYEXEC(Sink::Store::synchronize(Sink::Query().resourceFilter(mResourceInstanceIdentifier)));
0203             VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(mResourceInstanceIdentifier));
0204             auto contacts = Sink::Store::read<Contact>(Sink::Query().filter("uid", Sink::Query::Comparator(addedUid)));
0205             QCOMPARE(contacts.size(), 1);
0206             QCOMPARE(contacts.first().getFirstname(), QLatin1String{"Jane"});
0207         }
0208 
0209         {
0210             VERIFYEXEC(Sink::Store::remove(contact));
0211             VERIFYEXEC(Sink::ResourceControl::flushReplayQueue(mResourceInstanceIdentifier));
0212             VERIFYEXEC(Sink::Store::synchronize(Sink::Query().resourceFilter(mResourceInstanceIdentifier)));
0213             VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(mResourceInstanceIdentifier));
0214             auto contacts = Sink::Store::read<Contact>(Sink::Query().filter("uid", Sink::Query::Comparator(addedUid)));
0215             QCOMPARE(contacts.size(), 0);
0216         }
0217     }
0218 };
0219 
0220 QTEST_MAIN(CardDavTest)
0221 
0222 #include "carddavtest.moc"