diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-05-24 23:48:28 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-05-24 23:48:28 +0200 |
commit | b4be5caff7691b5a4325938dc10abc02432af26e (patch) | |
tree | cd41cde8bea050f9793ce5fc4e451945aec6082c | |
parent | 78a59b874ba088caec06c10761ebacaba3f120b5 (diff) | |
download | sink-b4be5caff7691b5a4325938dc10abc02432af26e.tar.gz sink-b4be5caff7691b5a4325938dc10abc02432af26e.zip |
A much more comprehensive mail test
-rw-r--r-- | common/genericresource.cpp | 2 | ||||
-rw-r--r-- | common/genericresource.h | 2 | ||||
-rw-r--r-- | examples/maildirresource/maildirresource.cpp | 105 | ||||
-rw-r--r-- | tests/mailtest.cpp | 110 | ||||
-rw-r--r-- | tests/mailtest.h | 3 |
5 files changed, 176 insertions, 46 deletions
diff --git a/common/genericresource.cpp b/common/genericresource.cpp index 74e829c..637e371 100644 --- a/common/genericresource.cpp +++ b/common/genericresource.cpp | |||
@@ -643,7 +643,7 @@ void GenericResource::scanForRemovals(Sink::Storage::Transaction &transaction, S | |||
643 | }); | 643 | }); |
644 | } | 644 | } |
645 | 645 | ||
646 | static QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> getLatest(const Sink::Storage::NamedDatabase &db, const QByteArray &uid, DomainTypeAdaptorFactoryInterface &adaptorFactory) | 646 | QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> GenericResource::getLatest(const Sink::Storage::NamedDatabase &db, const QByteArray &uid, DomainTypeAdaptorFactoryInterface &adaptorFactory) |
647 | { | 647 | { |
648 | QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> current; | 648 | QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> current; |
649 | db.findLatest(uid, | 649 | db.findLatest(uid, |
diff --git a/common/genericresource.h b/common/genericresource.h index 9665d6b..9582f06 100644 --- a/common/genericresource.h +++ b/common/genericresource.h | |||
@@ -114,6 +114,8 @@ protected: | |||
114 | void createOrModify(Sink::Storage::Transaction &transaction, Sink::Storage::Transaction &synchronizationTransaction, DomainTypeAdaptorFactoryInterface &adaptorFactory, | 114 | void createOrModify(Sink::Storage::Transaction &transaction, Sink::Storage::Transaction &synchronizationTransaction, DomainTypeAdaptorFactoryInterface &adaptorFactory, |
115 | const QByteArray &bufferType, const QByteArray &remoteId, const Sink::ApplicationDomain::ApplicationDomainType &entity); | 115 | const QByteArray &bufferType, const QByteArray &remoteId, const Sink::ApplicationDomain::ApplicationDomainType &entity); |
116 | 116 | ||
117 | static QSharedPointer<Sink::ApplicationDomain::BufferAdaptor> getLatest(const Sink::Storage::NamedDatabase &db, const QByteArray &uid, DomainTypeAdaptorFactoryInterface &adaptorFactory); | ||
118 | |||
117 | MessageQueue mUserQueue; | 119 | MessageQueue mUserQueue; |
118 | MessageQueue mSynchronizerQueue; | 120 | MessageQueue mSynchronizerQueue; |
119 | QByteArray mResourceInstanceIdentifier; | 121 | QByteArray mResourceInstanceIdentifier; |
diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp index 42da667..6dc9990 100644 --- a/examples/maildirresource/maildirresource.cpp +++ b/examples/maildirresource/maildirresource.cpp | |||
@@ -49,6 +49,22 @@ | |||
49 | #undef DEBUG_AREA | 49 | #undef DEBUG_AREA |
50 | #define DEBUG_AREA "resource.maildir" | 50 | #define DEBUG_AREA "resource.maildir" |
51 | 51 | ||
52 | static QString getFilePathFromMimeMessagePath(const QString &mimeMessagePath) | ||
53 | { | ||
54 | auto parts = mimeMessagePath.split('/'); | ||
55 | const auto key = parts.takeLast(); | ||
56 | const auto path = parts.join("/") + "/cur/"; | ||
57 | |||
58 | QDir dir(path); | ||
59 | const QFileInfoList list = dir.entryInfoList(QStringList() << (key+"*"), QDir::Files); | ||
60 | if (list.size() != 1) { | ||
61 | Warning() << "Failed to find message " << mimeMessagePath; | ||
62 | Warning() << "Failed to find message " << path; | ||
63 | return QString(); | ||
64 | } | ||
65 | return list.first().filePath(); | ||
66 | } | ||
67 | |||
52 | class FolderUpdater : public Sink::Preprocessor | 68 | class FolderUpdater : public Sink::Preprocessor |
53 | { | 69 | { |
54 | public: | 70 | public: |
@@ -76,7 +92,7 @@ public: | |||
76 | }); | 92 | }); |
77 | return folderPath; | 93 | return folderPath; |
78 | } | 94 | } |
79 | 95 | ||
80 | QString moveMessage(const QString &oldPath, const QByteArray &folder, Sink::Storage::Transaction &transaction) | 96 | QString moveMessage(const QString &oldPath, const QByteArray &folder, Sink::Storage::Transaction &transaction) |
81 | { | 97 | { |
82 | if (oldPath.startsWith(Sink::temporaryFileLocation())) { | 98 | if (oldPath.startsWith(Sink::temporaryFileLocation())) { |
@@ -90,22 +106,13 @@ public: | |||
90 | } | 106 | } |
91 | return oldPath; | 107 | return oldPath; |
92 | } | 108 | } |
109 | |||
93 | void updatedIndexedProperties(Sink::ApplicationDomain::BufferAdaptor &newEntity) | 110 | void updatedIndexedProperties(Sink::ApplicationDomain::BufferAdaptor &newEntity) |
94 | { | 111 | { |
95 | const auto mimeMessagePath = newEntity.getProperty("mimeMessage").toString(); | 112 | const auto filePath = getFilePathFromMimeMessagePath(newEntity.getProperty("mimeMessage").toString()); |
96 | auto parts = mimeMessagePath.split('/'); | ||
97 | const auto key = parts.takeLast(); | ||
98 | const auto path = parts.join("/") + "/cur/"; | ||
99 | |||
100 | QDir dir(path); | ||
101 | const QFileInfoList list = dir.entryInfoList(QStringList() << (key+"*"), QDir::Files); | ||
102 | if (list.size() != 1) { | ||
103 | Warning() << "Failed to find message " << path << key << list.size(); | ||
104 | return; | ||
105 | } | ||
106 | 113 | ||
107 | KMime::Message *msg = new KMime::Message; | 114 | KMime::Message *msg = new KMime::Message; |
108 | msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(list.first().filePath()))); | 115 | msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(filePath))); |
109 | msg->parse(); | 116 | msg->parse(); |
110 | 117 | ||
111 | newEntity.setProperty("subject", msg->subject(true)->asUnicodeString()); | 118 | newEntity.setProperty("subject", msg->subject(true)->asUnicodeString()); |
@@ -408,15 +415,7 @@ KAsync::Job<void> MaildirResource::replay(Sink::Storage &synchronizationStore, c | |||
408 | } else if (type == ENTITY_TYPE_MAIL) { | 415 | } else if (type == ENTITY_TYPE_MAIL) { |
409 | if (operation == Sink::Operation_Creation) { | 416 | if (operation == Sink::Operation_Creation) { |
410 | const Sink::ApplicationDomain::Mail mail(mResourceInstanceIdentifier, Sink::Storage::uidFromKey(key), revision, mMailAdaptorFactory->createAdaptor(entity)); | 417 | const Sink::ApplicationDomain::Mail mail(mResourceInstanceIdentifier, Sink::Storage::uidFromKey(key), revision, mMailAdaptorFactory->createAdaptor(entity)); |
411 | auto parentFolder = mail.getProperty("folder").toByteArray(); | 418 | const auto remoteId = getFilePathFromMimeMessagePath(mail.getMimeMessagePath()); |
412 | QByteArray parentFolderRemoteId; | ||
413 | if (!parentFolder.isEmpty()) { | ||
414 | parentFolderRemoteId = resolveLocalId(ENTITY_TYPE_FOLDER, parentFolder, synchronizationTransaction); | ||
415 | } else { | ||
416 | parentFolderRemoteId = mMaildirPath.toUtf8(); | ||
417 | } | ||
418 | const auto parentFolderPath = parentFolderRemoteId; | ||
419 | const auto remoteId = mail.getProperty("mimeMessage").toString().split('/').last(); | ||
420 | Trace() << "Creating a new mail." << remoteId; | 419 | Trace() << "Creating a new mail." << remoteId; |
421 | if (remoteId.isEmpty()) { | 420 | if (remoteId.isEmpty()) { |
422 | Warning() << "Failed to create mail: " << remoteId; | 421 | Warning() << "Failed to create mail: " << remoteId; |
@@ -436,11 +435,18 @@ KAsync::Job<void> MaildirResource::replay(Sink::Storage &synchronizationStore, c | |||
436 | const auto remoteId = resolveLocalId(ENTITY_TYPE_MAIL, uid, synchronizationTransaction); | 435 | const auto remoteId = resolveLocalId(ENTITY_TYPE_MAIL, uid, synchronizationTransaction); |
437 | Trace() << "Modifying a mail: " << remoteId; | 436 | Trace() << "Modifying a mail: " << remoteId; |
438 | 437 | ||
439 | const auto maildirPath = KPIM::Maildir::getDirectoryFromFile(remoteId); | 438 | const Sink::ApplicationDomain::Mail mail(mResourceInstanceIdentifier, Sink::Storage::uidFromKey(key), revision, mMailAdaptorFactory->createAdaptor(entity)); |
439 | |||
440 | const auto filePath = getFilePathFromMimeMessagePath(mail.getMimeMessagePath()); | ||
441 | const auto maildirPath = KPIM::Maildir::getDirectoryFromFile(filePath); | ||
440 | KPIM::Maildir maildir(maildirPath, false); | 442 | KPIM::Maildir maildir(maildirPath, false); |
441 | 443 | ||
442 | const Sink::ApplicationDomain::Mail mail(mResourceInstanceIdentifier, Sink::Storage::uidFromKey(key), revision, mMailAdaptorFactory->createAdaptor(entity)); | 444 | const auto messagePathParts = filePath.split("/"); |
443 | auto newIdentifier = mail.getMimeMessagePath().split("/").last(); | 445 | if (messagePathParts.isEmpty()) { |
446 | Warning() << "No message path available: " << remoteId; | ||
447 | return KAsync::error<void>(1, "No message path available."); | ||
448 | } | ||
449 | const auto newIdentifier = messagePathParts.last(); | ||
444 | QString identifier; | 450 | QString identifier; |
445 | if (newIdentifier != KPIM::Maildir::getKeyFromFile(remoteId)) { | 451 | if (newIdentifier != KPIM::Maildir::getKeyFromFile(remoteId)) { |
446 | //Remove the old mime message if it changed | 452 | //Remove the old mime message if it changed |
@@ -449,6 +455,7 @@ KAsync::Job<void> MaildirResource::replay(Sink::Storage &synchronizationStore, c | |||
449 | identifier = newIdentifier; | 455 | identifier = newIdentifier; |
450 | } else { | 456 | } else { |
451 | //The identifier needs to contain the flags for changeEntryFlags to work | 457 | //The identifier needs to contain the flags for changeEntryFlags to work |
458 | Q_ASSERT(!remoteId.split('/').isEmpty()); | ||
452 | identifier = remoteId.split('/').last(); | 459 | identifier = remoteId.split('/').last(); |
453 | } | 460 | } |
454 | 461 | ||
@@ -480,12 +487,23 @@ KAsync::Job<void> MaildirResource::inspect(int inspectionType, const QByteArray | |||
480 | { | 487 | { |
481 | auto synchronizationStore = QSharedPointer<Sink::Storage>::create(Sink::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Sink::Storage::ReadOnly); | 488 | auto synchronizationStore = QSharedPointer<Sink::Storage>::create(Sink::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Sink::Storage::ReadOnly); |
482 | auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::ReadOnly); | 489 | auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::ReadOnly); |
490 | |||
491 | auto mainStore = QSharedPointer<Sink::Storage>::create(Sink::storageLocation(), mResourceInstanceIdentifier, Sink::Storage::ReadOnly); | ||
492 | auto transaction = mainStore->createTransaction(Sink::Storage::ReadOnly); | ||
493 | |||
483 | Trace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; | 494 | Trace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; |
495 | |||
484 | if (domainType == ENTITY_TYPE_MAIL) { | 496 | if (domainType == ENTITY_TYPE_MAIL) { |
497 | auto mainDatabase = Sink::Storage::mainDatabase(transaction, ENTITY_TYPE_MAIL); | ||
498 | auto bufferAdaptor = getLatest(mainDatabase, entityId, *mMailAdaptorFactory); | ||
499 | Q_ASSERT(bufferAdaptor); | ||
500 | |||
501 | const Sink::ApplicationDomain::Mail mail(mResourceInstanceIdentifier, entityId, 0, bufferAdaptor); | ||
502 | const auto filePath = getFilePathFromMimeMessagePath(mail.getMimeMessagePath()); | ||
503 | |||
485 | if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { | 504 | if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { |
486 | if (property == "unread") { | 505 | if (property == "unread") { |
487 | const auto remoteId = resolveLocalId(ENTITY_TYPE_MAIL, entityId, synchronizationTransaction); | 506 | const auto flags = KPIM::Maildir::readEntryFlags(filePath.split('/').last()); |
488 | const auto flags = KPIM::Maildir::readEntryFlags(remoteId.split('/').last()); | ||
489 | if (expectedValue.toBool() && (flags & KPIM::Maildir::Seen)) { | 507 | if (expectedValue.toBool() && (flags & KPIM::Maildir::Seen)) { |
490 | return KAsync::error<void>(1, "Expected unread but couldn't find it."); | 508 | return KAsync::error<void>(1, "Expected unread but couldn't find it."); |
491 | } | 509 | } |
@@ -495,10 +513,8 @@ KAsync::Job<void> MaildirResource::inspect(int inspectionType, const QByteArray | |||
495 | return KAsync::null<void>(); | 513 | return KAsync::null<void>(); |
496 | } | 514 | } |
497 | if (property == "subject") { | 515 | if (property == "subject") { |
498 | const auto remoteId = resolveLocalId(ENTITY_TYPE_MAIL, entityId, synchronizationTransaction); | ||
499 | |||
500 | KMime::Message *msg = new KMime::Message; | 516 | KMime::Message *msg = new KMime::Message; |
501 | msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(remoteId))); | 517 | msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(filePath))); |
502 | msg->parse(); | 518 | msg->parse(); |
503 | 519 | ||
504 | if (msg->subject(true)->asUnicodeString() != expectedValue.toString()) { | 520 | if (msg->subject(true)->asUnicodeString() != expectedValue.toString()) { |
@@ -508,9 +524,32 @@ KAsync::Job<void> MaildirResource::inspect(int inspectionType, const QByteArray | |||
508 | } | 524 | } |
509 | } | 525 | } |
510 | if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { | 526 | if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { |
511 | const auto remoteId = resolveLocalId(ENTITY_TYPE_MAIL, entityId, synchronizationTransaction); | 527 | if (QFileInfo(filePath).exists() != expectedValue.toBool()) { |
512 | if (QFileInfo(remoteId).exists() != expectedValue.toBool()) { | 528 | return KAsync::error<void>(1, "Wrong file existence: " + filePath); |
513 | return KAsync::error<void>(1, "Wrong file existence: " + remoteId); | 529 | } |
530 | } | ||
531 | } | ||
532 | if (domainType == ENTITY_TYPE_FOLDER) { | ||
533 | const auto remoteId = resolveLocalId(ENTITY_TYPE_FOLDER, entityId, synchronizationTransaction); | ||
534 | |||
535 | if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { | ||
536 | if (!QDir(remoteId).exists()) { | ||
537 | return KAsync::error<void>(1, "The directory is not existing: " + remoteId); | ||
538 | } | ||
539 | |||
540 | int expectedCount = 0; | ||
541 | Index index("mail.index.folder", transaction); | ||
542 | index.lookup(entityId, [&](const QByteArray &sinkId) { | ||
543 | expectedCount++; | ||
544 | }, | ||
545 | [&](const Index::Error &error) { | ||
546 | Warning() << "Error in index: " << error.message << property; | ||
547 | }); | ||
548 | |||
549 | QDir dir(remoteId + "/cur"); | ||
550 | const QFileInfoList list = dir.entryInfoList(QDir::Files); | ||
551 | if (list.size() != expectedCount) { | ||
552 | return KAsync::error<void>(1, QString("Wrong number of files; found %1 instead of %2.").arg(list.size()).arg(expectedCount)); | ||
514 | } | 553 | } |
515 | } | 554 | } |
516 | } | 555 | } |
diff --git a/tests/mailtest.cpp b/tests/mailtest.cpp index 3ca8eaa..496b7ef 100644 --- a/tests/mailtest.cpp +++ b/tests/mailtest.cpp | |||
@@ -42,6 +42,7 @@ void MailTest::initTestCase() | |||
42 | VERIFYEXEC(Store::create(resource)); | 42 | VERIFYEXEC(Store::create(resource)); |
43 | 43 | ||
44 | mResourceInstanceIdentifier = resource.identifier(); | 44 | mResourceInstanceIdentifier = resource.identifier(); |
45 | mCapabilities = resource.getProperty("capabilities").value<QByteArrayList>(); | ||
45 | } | 46 | } |
46 | 47 | ||
47 | void MailTest::cleanup() | 48 | void MailTest::cleanup() |
@@ -131,13 +132,8 @@ void MailTest::testCreateModifyDeleteFolder() | |||
131 | 132 | ||
132 | void MailTest::testCreateModifyDeleteMail() | 133 | void MailTest::testCreateModifyDeleteMail() |
133 | { | 134 | { |
134 | |||
135 | const auto subject = QString::fromLatin1("Foobar"); | 135 | const auto subject = QString::fromLatin1("Foobar"); |
136 | 136 | ||
137 | Query query; | ||
138 | query.resources << mResourceInstanceIdentifier; | ||
139 | query.request<Mail::Folder>().request<Mail::Subject>(); | ||
140 | |||
141 | auto folder = Folder::create(mResourceInstanceIdentifier); | 137 | auto folder = Folder::create(mResourceInstanceIdentifier); |
142 | folder.setName("folder"); | 138 | folder.setName("folder"); |
143 | VERIFYEXEC(Store::create(folder)); | 139 | VERIFYEXEC(Store::create(folder)); |
@@ -151,7 +147,7 @@ void MailTest::testCreateModifyDeleteMail() | |||
151 | mail.setFolder(folder); | 147 | mail.setFolder(folder); |
152 | 148 | ||
153 | VERIFYEXEC(Store::create(mail)); | 149 | VERIFYEXEC(Store::create(mail)); |
154 | VERIFYEXEC(ResourceControl::flushMessageQueue(query.resources)); | 150 | VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); |
155 | { | 151 | { |
156 | auto job = Store::fetchAll<Mail>(Query::RequestedProperties(QByteArrayList() << Mail::Folder::name << Mail::Subject::name << Mail::MimeMessage::name)) | 152 | auto job = Store::fetchAll<Mail>(Query::RequestedProperties(QByteArrayList() << Mail::Folder::name << Mail::Subject::name << Mail::MimeMessage::name)) |
157 | .then<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { | 153 | .then<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { |
@@ -160,14 +156,13 @@ void MailTest::testCreateModifyDeleteMail() | |||
160 | QCOMPARE(mail.getSubject(), subject); | 156 | QCOMPARE(mail.getSubject(), subject); |
161 | QCOMPARE(mail.getFolder(), folder.identifier()); | 157 | QCOMPARE(mail.getFolder(), folder.identifier()); |
162 | QVERIFY(QFile(mail.getMimeMessagePath()).exists()); | 158 | QVERIFY(QFile(mail.getMimeMessagePath()).exists()); |
163 | |||
164 | // return Store::remove(*mail) | ||
165 | // .then(ResourceControl::flushReplayQueue(query.resources)) // The change needs to be replayed already | ||
166 | // .then(ResourceControl::inspect<Mail>(ResourceControl::Inspection::ExistenceInspection(*mail, false))); | ||
167 | }); | 159 | }); |
168 | VERIFYEXEC(job); | 160 | VERIFYEXEC(job); |
169 | } | 161 | } |
170 | 162 | ||
163 | VERIFYEXEC(ResourceControl::inspect<ApplicationDomain::Mail>(ResourceControl::Inspection::ExistenceInspection(mail, true))); | ||
164 | VERIFYEXEC(ResourceControl::inspect<ApplicationDomain::Folder>(ResourceControl::Inspection::CacheIntegrityInspection(folder))); | ||
165 | |||
171 | const auto subject2 = QString::fromLatin1("Foobar2"); | 166 | const auto subject2 = QString::fromLatin1("Foobar2"); |
172 | auto message2 = KMime::Message::Ptr::create(); | 167 | auto message2 = KMime::Message::Ptr::create(); |
173 | message2->subject(true)->fromUnicodeString(subject2, "utf8"); | 168 | message2->subject(true)->fromUnicodeString(subject2, "utf8"); |
@@ -175,7 +170,7 @@ void MailTest::testCreateModifyDeleteMail() | |||
175 | mail.setMimeMessage(message2->encodedContent()); | 170 | mail.setMimeMessage(message2->encodedContent()); |
176 | 171 | ||
177 | VERIFYEXEC(Store::modify(mail)); | 172 | VERIFYEXEC(Store::modify(mail)); |
178 | VERIFYEXEC(ResourceControl::flushMessageQueue(query.resources)); | 173 | VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); |
179 | { | 174 | { |
180 | auto job = Store::fetchAll<Mail>(Query::RequestedProperties(QByteArrayList() << Mail::Folder::name << Mail::Subject::name)) | 175 | auto job = Store::fetchAll<Mail>(Query::RequestedProperties(QByteArrayList() << Mail::Folder::name << Mail::Subject::name)) |
181 | .then<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { | 176 | .then<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { |
@@ -188,9 +183,11 @@ void MailTest::testCreateModifyDeleteMail() | |||
188 | }); | 183 | }); |
189 | VERIFYEXEC(job); | 184 | VERIFYEXEC(job); |
190 | } | 185 | } |
186 | VERIFYEXEC(ResourceControl::inspect<ApplicationDomain::Mail>(ResourceControl::Inspection::ExistenceInspection(mail, true))); | ||
187 | VERIFYEXEC(ResourceControl::inspect<ApplicationDomain::Folder>(ResourceControl::Inspection::CacheIntegrityInspection(folder))); | ||
191 | 188 | ||
192 | VERIFYEXEC(Store::remove(mail)); | 189 | VERIFYEXEC(Store::remove(mail)); |
193 | VERIFYEXEC(ResourceControl::flushMessageQueue(query.resources)); | 190 | VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); |
194 | { | 191 | { |
195 | auto job = Store::fetchAll<Mail>(Query::RequestedProperties(QByteArrayList() << Mail::Folder::name << Mail::Subject::name)) | 192 | auto job = Store::fetchAll<Mail>(Query::RequestedProperties(QByteArrayList() << Mail::Folder::name << Mail::Subject::name)) |
196 | .then<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { | 193 | .then<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { |
@@ -198,6 +195,95 @@ void MailTest::testCreateModifyDeleteMail() | |||
198 | }); | 195 | }); |
199 | VERIFYEXEC(job); | 196 | VERIFYEXEC(job); |
200 | } | 197 | } |
198 | VERIFYEXEC(ResourceControl::inspect<ApplicationDomain::Mail>(ResourceControl::Inspection::ExistenceInspection(mail, false))); | ||
199 | VERIFYEXEC(ResourceControl::inspect<ApplicationDomain::Folder>(ResourceControl::Inspection::CacheIntegrityInspection(folder))); | ||
200 | } | ||
201 | |||
202 | void MailTest::testMarkMailAsRead() | ||
203 | { | ||
204 | auto folder = Folder::create(mResourceInstanceIdentifier); | ||
205 | folder.setName("folder"); | ||
206 | VERIFYEXEC(Store::create(folder)); | ||
207 | |||
208 | auto message = KMime::Message::Ptr::create(); | ||
209 | message->subject(true)->fromUnicodeString("subject", "utf8"); | ||
210 | message->assemble(); | ||
211 | |||
212 | auto mail = Mail::create(mResourceInstanceIdentifier); | ||
213 | mail.setMimeMessage(message->encodedContent()); | ||
214 | mail.setFolder(folder); | ||
215 | mail.setUnread(false); | ||
216 | VERIFYEXEC(Store::create(mail)); | ||
217 | VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); | ||
218 | |||
219 | auto job = Store::fetchAll<Mail>(Query::ResourceFilter(mResourceInstanceIdentifier) + | ||
220 | Query::RequestedProperties(QByteArrayList() << Mail::Folder::name | ||
221 | << Mail::Subject::name)) | ||
222 | .then<void, KAsync::Job<void>, QList<Mail::Ptr>>([this](const QList<Mail::Ptr> &mails) { | ||
223 | ASYNCCOMPARE(mails.size(), 1); | ||
224 | auto mail = mails.first(); | ||
225 | mail->setProperty("unread", true); | ||
226 | return Store::modify(*mail) | ||
227 | .then<void>(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier)) // The change needs to be replayed already | ||
228 | .then(ResourceControl::inspect<Mail>(ResourceControl::Inspection::PropertyInspection(*mail, Mail::Unread::name, true))) | ||
229 | .then(ResourceControl::inspect<Mail>(ResourceControl::Inspection::PropertyInspection(*mail, Mail::Subject::name, mail->getSubject()))); | ||
230 | }); | ||
231 | VERIFYEXEC(job); | ||
232 | |||
233 | // Verify that we can still query for all relevant information | ||
234 | auto job2 = Store::fetchAll<Mail>( | ||
235 | Query::ResourceFilter(mResourceInstanceIdentifier) + Query::RequestedProperties(QByteArrayList() << Mail::Folder::name | ||
236 | << Mail::Subject::name | ||
237 | << Mail::MimeMessage::name | ||
238 | << Mail::Unread::name)) | ||
239 | .then<void, KAsync::Job<void>, QList<Mail::Ptr>>([](const QList<Mail::Ptr> &mails) { | ||
240 | ASYNCCOMPARE(mails.size(), 1); | ||
241 | auto mail = mails.first(); | ||
242 | ASYNCVERIFY(!mail->getSubject().isEmpty()); | ||
243 | ASYNCCOMPARE(mail->getUnread(), true); | ||
244 | ASYNCVERIFY(QFileInfo(mail->getMimeMessagePath()).exists()); | ||
245 | return KAsync::null<void>(); | ||
246 | }); | ||
247 | VERIFYEXEC(job2); | ||
248 | } | ||
249 | |||
250 | void MailTest::testCreateDraft() | ||
251 | { | ||
252 | if (!mCapabilities.contains("drafts")) { | ||
253 | QSKIP("Resource doesn't have the drafts capability"); | ||
254 | } | ||
255 | |||
256 | auto message = KMime::Message::Ptr::create(); | ||
257 | message->subject(true)->fromUnicodeString(QString::fromLatin1("Foobar"), "utf8"); | ||
258 | message->assemble(); | ||
259 | |||
260 | auto mail = ApplicationDomain::Mail::create(mResourceInstanceIdentifier); | ||
261 | mail.setMimeMessage(message->encodedContent()); | ||
262 | mail.setDraft(true); | ||
263 | |||
264 | VERIFYEXEC(Store::create(mail)); | ||
265 | VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); | ||
266 | |||
267 | QByteArray folderIdentifier; | ||
268 | auto job = Store::fetchOne<ApplicationDomain::Mail>(Query::IdentityFilter(mail.identifier()) + Query::RequestedProperties(QByteArrayList() << Mail::MimeMessage::name << Mail::Folder::name)) | ||
269 | .then<void, ApplicationDomain::Mail>([&](const ApplicationDomain::Mail &mail) { | ||
270 | folderIdentifier = mail.getProperty("folder").toByteArray(); | ||
271 | QVERIFY(!folderIdentifier.isEmpty()); | ||
272 | }); | ||
273 | VERIFYEXEC(job); | ||
274 | |||
275 | //Ensure we can also query by folder | ||
276 | auto job2 = Store::fetchAll<ApplicationDomain::Mail>(Query::PropertyFilter("folder", folderIdentifier)) | ||
277 | .then<void, QList<ApplicationDomain::Mail::Ptr> >([&](const QList<ApplicationDomain::Mail::Ptr> &mails) { | ||
278 | bool found = false; | ||
279 | for (const auto m : mails) { | ||
280 | if (m->identifier() == mail.identifier()) { | ||
281 | found = true; | ||
282 | } | ||
283 | } | ||
284 | QVERIFY(found); | ||
285 | }); | ||
286 | VERIFYEXEC(job2); | ||
201 | } | 287 | } |
202 | 288 | ||
203 | #include "mailtest.moc" | 289 | #include "mailtest.moc" |
diff --git a/tests/mailtest.h b/tests/mailtest.h index 0729a91..43d4f75 100644 --- a/tests/mailtest.h +++ b/tests/mailtest.h | |||
@@ -51,6 +51,7 @@ class MailTest : public QObject | |||
51 | 51 | ||
52 | protected: | 52 | protected: |
53 | QByteArray mResourceInstanceIdentifier; | 53 | QByteArray mResourceInstanceIdentifier; |
54 | QByteArrayList mCapabilities; | ||
54 | 55 | ||
55 | virtual void resetTestEnvironment() = 0; | 56 | virtual void resetTestEnvironment() = 0; |
56 | virtual Sink::ApplicationDomain::SinkResource createResource() = 0; | 57 | virtual Sink::ApplicationDomain::SinkResource createResource() = 0; |
@@ -63,6 +64,8 @@ private slots: | |||
63 | 64 | ||
64 | void testCreateModifyDeleteFolder(); | 65 | void testCreateModifyDeleteFolder(); |
65 | void testCreateModifyDeleteMail(); | 66 | void testCreateModifyDeleteMail(); |
67 | void testMarkMailAsRead(); | ||
68 | void testCreateDraft(); | ||
66 | }; | 69 | }; |
67 | 70 | ||
68 | } | 71 | } |