1 /* This file is part of the KDE project
2 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
3 SPDX-FileContributor: Kevin Krammer <krake@kdab.com>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
8 #include "mixedmaildirstore.h"
9
10 #include "collectioncreatejob.h"
11 #include "collectiondeletejob.h"
12 #include "collectionfetchjob.h"
13 #include "collectionmodifyjob.h"
14 #include "collectionmovejob.h"
15 #include "itemcreatejob.h"
16 #include "itemdeletejob.h"
17 #include "itemfetchjob.h"
18 #include "itemmodifyjob.h"
19 #include "itemmovejob.h"
20 #include "sessionimpls_p.h"
21 #include "storecompactjob.h"
22
23 #include <Akonadi/KMime/MessageParts>
24
25 #include <Akonadi/CachePolicy>
26
27 #include <KMime/Message>
28
29 #include <KRandom>
30 #include <QRandomGenerator>
31 #include <QTemporaryDir>
32
33 #include <QTest>
34
35 using namespace Akonadi;
36
37 class TestStore : public MixedMaildirStore
38 {
39 Q_OBJECT
40
41 public:
TestStore()42 TestStore()
43 : mLastCheckedJob(nullptr)
44 , mErrorCode(0)
45 {
46 }
47
48 public:
49 Collection mTopLevelCollection;
50
51 mutable FileStore::Job *mLastCheckedJob = nullptr;
52 mutable int mErrorCode;
53 mutable QString mErrorText;
54
55 protected:
setTopLevelCollection(const Collection & collection)56 void setTopLevelCollection(const Collection &collection) override
57 {
58 MixedMaildirStore::setTopLevelCollection(collection);
59 }
60
checkCollectionMove(FileStore::CollectionMoveJob * job,int & errorCode,QString & errorText) const61 void checkCollectionMove(FileStore::CollectionMoveJob *job, int &errorCode, QString &errorText) const override
62 {
63 MixedMaildirStore::checkCollectionMove(job, errorCode, errorText);
64
65 mLastCheckedJob = job;
66 mErrorCode = errorCode;
67 mErrorText = errorText;
68 }
69
checkItemCreate(FileStore::ItemCreateJob * job,int & errorCode,QString & errorText) const70 void checkItemCreate(FileStore::ItemCreateJob *job, int &errorCode, QString &errorText) const override
71 {
72 MixedMaildirStore::checkItemCreate(job, errorCode, errorText);
73
74 mLastCheckedJob = job;
75 mErrorCode = errorCode;
76 mErrorText = errorText;
77 }
78 };
79
80 class TemplateMethodsTest : public QObject
81 {
82 Q_OBJECT
83
84 public:
TemplateMethodsTest()85 TemplateMethodsTest()
86 : QObject()
87 , mStore(nullptr)
88 {
89 }
90
~TemplateMethodsTest()91 ~TemplateMethodsTest() override
92 {
93 delete mStore;
94 }
95
96 private:
97 QTemporaryDir mDir;
98 TestStore *mStore = nullptr;
99
100 private Q_SLOTS:
101 void init();
102 void testSetTopLevelCollection();
103 void testMoveCollection();
104 void testCreateItem();
105 };
106
init()107 void TemplateMethodsTest::init()
108 {
109 delete mStore;
110 mStore = new TestStore;
111 QVERIFY(mDir.isValid());
112 QVERIFY(QDir(mDir.path()).exists());
113 }
114
testSetTopLevelCollection()115 void TemplateMethodsTest::testSetTopLevelCollection()
116 {
117 const QString file = KRandom::randomString(10);
118 const QString path = mDir.path() + file;
119
120 mStore->setPath(path);
121
122 // check the adjustments on the top level collection
123 const Collection collection = mStore->topLevelCollection();
124 QCOMPARE(collection.contentMimeTypes(), QStringList() << Collection::mimeType());
125 QCOMPARE(collection.rights(), Collection::CanCreateCollection | Collection::CanChangeCollection | Collection::CanDeleteCollection);
126 const CachePolicy cachePolicy = collection.cachePolicy();
127 QVERIFY(!cachePolicy.inheritFromParent());
128 QCOMPARE(cachePolicy.localParts(), QStringList() << QLatin1String(MessagePart::Envelope));
129 QVERIFY(cachePolicy.syncOnDemand());
130 }
131
testMoveCollection()132 void TemplateMethodsTest::testMoveCollection()
133 {
134 mStore->setPath(mDir.path());
135
136 FileStore::CollectionMoveJob *job = nullptr;
137
138 // test moving into itself
139 Collection collection(QRandomGenerator::global()->generate());
140 collection.setParentCollection(mStore->topLevelCollection());
141 collection.setRemoteId(QStringLiteral("collection"));
142 job = mStore->moveCollection(collection, collection);
143 QVERIFY(job != nullptr);
144 QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext);
145 QVERIFY(!job->errorText().isEmpty());
146 QCOMPARE(mStore->mLastCheckedJob, job);
147 QCOMPARE(mStore->mErrorCode, job->error());
148 QCOMPARE(mStore->mErrorText, job->errorText());
149
150 QVERIFY(!job->exec());
151
152 // test moving into child
153 Collection childCollection(collection.id() + 1);
154 childCollection.setParentCollection(collection);
155 childCollection.setRemoteId(QStringLiteral("child"));
156 job = mStore->moveCollection(collection, childCollection);
157 QVERIFY(job != nullptr);
158 QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext);
159 QVERIFY(!job->errorText().isEmpty());
160 QCOMPARE(mStore->mLastCheckedJob, job);
161 QCOMPARE(mStore->mErrorCode, job->error());
162 QCOMPARE(mStore->mErrorText, job->errorText());
163
164 QVERIFY(!job->exec());
165
166 // test moving into grand child child
167 Collection grandChildCollection(collection.id() + 2);
168 grandChildCollection.setParentCollection(childCollection);
169 grandChildCollection.setRemoteId(QStringLiteral("grandchild"));
170 job = mStore->moveCollection(collection, grandChildCollection);
171 QVERIFY(job != nullptr);
172 QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext);
173 QVERIFY(!job->errorText().isEmpty());
174 QCOMPARE(mStore->mLastCheckedJob, job);
175 QCOMPARE(mStore->mErrorCode, job->error());
176 QCOMPARE(mStore->mErrorText, job->errorText());
177
178 QVERIFY(!job->exec());
179
180 // test moving into unrelated collection
181 Collection otherCollection(collection.id() + QRandomGenerator::global()->generate());
182 otherCollection.setParentCollection(mStore->topLevelCollection());
183 otherCollection.setRemoteId(QStringLiteral("other"));
184 job = mStore->moveCollection(collection, otherCollection);
185 QVERIFY(job != nullptr);
186 QCOMPARE(job->error(), 0);
187 QVERIFY(job->errorText().isEmpty());
188 QCOMPARE(mStore->mLastCheckedJob, job);
189
190 // collections don't exist in the store, so processing still fails
191 QVERIFY(!job->exec());
192 }
193
testCreateItem()194 void TemplateMethodsTest::testCreateItem()
195 {
196 mStore->setPath(mDir.path());
197
198 Collection collection(QRandomGenerator::global()->generate());
199 collection.setParentCollection(mStore->topLevelCollection());
200 collection.setRemoteId(QStringLiteral("collection"));
201
202 FileStore::ItemCreateJob *job = nullptr;
203
204 // test item without payload
205 Item item(KMime::Message::mimeType());
206 job = mStore->createItem(item, collection);
207 QVERIFY(job != nullptr);
208 QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext);
209 QVERIFY(!job->errorText().isEmpty());
210 QCOMPARE(mStore->mLastCheckedJob, job);
211 QCOMPARE(mStore->mErrorCode, job->error());
212 QCOMPARE(mStore->mErrorText, job->errorText());
213
214 QVERIFY(!job->exec());
215
216 // test item with payload
217 item.setPayloadFromData("Subject: dummy payload\n\nwith some content");
218 job = mStore->createItem(item, collection);
219 QVERIFY(job != nullptr);
220 QCOMPARE(job->error(), 0);
221 QVERIFY(job->errorText().isEmpty());
222 QCOMPARE(mStore->mLastCheckedJob, job);
223
224 // collections don't exist in the store, so processing still fails
225 QVERIFY(!job->exec());
226 }
227
228 QTEST_MAIN(TemplateMethodsTest)
229
230 #include "templatemethodstest.moc"
231