1 /*
2     SPDX-FileCopyrightText: 2009 Constantin Berzan <exit3219@gmail.com>
3 
4     SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "filteractiontest.h"
8 #include <collectionpathresolver_p.h>
9 #include <testattribute.h>
10 
11 #include <Akonadi/AttributeFactory>
12 #include <Akonadi/CollectionCreateJob>
13 #include <Akonadi/ItemCreateJob>
14 #include <Akonadi/ItemFetchJob>
15 #include <Akonadi/ItemFetchScope>
16 #include <Akonadi/ItemModifyJob>
17 #include <akonadi/qtest_akonadi.h>
18 #include <filteractionjob_p.h>
19 
20 using namespace Akonadi;
21 
22 QTEST_AKONADIMAIN(FilterActionTest, NoGUI)
23 
24 static const QByteArray acceptable = "acceptable";
25 static const QByteArray unacceptable = "unacceptable";
26 static const QByteArray modified = "modified";
27 static Collection res1;
28 
29 class MyFunctor : public FilterAction
30 {
fetchScope() const31     virtual Akonadi::ItemFetchScope fetchScope() const
32     {
33         ItemFetchScope scope;
34         scope.fetchAttribute<TestAttribute>();
35         return scope;
36     }
37 
itemAccepted(const Akonadi::Item & item) const38     virtual bool itemAccepted(const Akonadi::Item &item) const
39     {
40         if (!item.hasAttribute<TestAttribute>()) {
41             return false;
42         }
43         return item.attribute<TestAttribute>()->data == acceptable;
44     }
45 
itemAction(const Akonadi::Item & item,FilterActionJob * parent) const46     virtual Akonadi::Job *itemAction(const Akonadi::Item &item, FilterActionJob *parent) const
47     {
48         Item cp(item);
49         TestAttribute *newa = new TestAttribute;
50         newa->data = modified;
51         cp.addAttribute(newa);
52         return new ItemModifyJob(cp, parent);
53     }
54 };
55 
initTestCase()56 void FilterActionTest::initTestCase()
57 {
58     AttributeFactory::registerAttribute<TestAttribute>();
59 
60     CollectionPathResolver *resolver = new CollectionPathResolver("res1", this);
61     QVERIFY(resolver->exec());
62     res1 = Collection(resolver->collection());
63 }
64 
testMassModifyItem()65 void FilterActionTest::testMassModifyItem()
66 {
67     Collection col = createCollection("testMassModifyItem");
68 
69     // Test acceptable item.
70     Item item = createItem(col, true);
71     FilterActionJob *mjob = new FilterActionJob(item, new MyFunctor, this);
72     AKVERIFYEXEC(mjob);
73     ItemFetchJob *fjob = new ItemFetchJob(item, this);
74     fjob->fetchScope().fetchAllAttributes();
75     AKVERIFYEXEC(fjob);
76     QCOMPARE(fjob->items().count(), 1);
77     item = fjob->items().first();
78     QVERIFY(item.hasAttribute<TestAttribute>());
79     TestAttribute *attr = item.attribute<TestAttribute>();
80     QCOMPARE(attr->data, modified);
81 
82     // Test unacceptable item.
83     item = createItem(col, false);
84     mjob = new FilterActionJob(item, new MyFunctor, this);
85     AKVERIFYEXEC(mjob);
86     fjob = new ItemFetchJob(item, this);
87     fjob->fetchScope().fetchAllAttributes();
88     AKVERIFYEXEC(fjob);
89     QCOMPARE(fjob->items().count(), 1);
90     item = fjob->items().first();
91     QVERIFY(item.hasAttribute<TestAttribute>());
92     attr = item.attribute<TestAttribute>();
93     QCOMPARE(attr->data, unacceptable);
94 }
95 
testMassModifyItems()96 void FilterActionTest::testMassModifyItems()
97 {
98     Collection col = createCollection("testMassModifyItems");
99 
100     // Test a bunch of acceptable and unacceptable items.
101     Item::List acc, unacc;
102     for (int i = 0; i < 5; i++) {
103         acc.append(createItem(col, true));
104         unacc.append(createItem(col, false));
105     }
106     Item::List all = acc + unacc;
107     QCOMPARE(all.count(), 10);
108     FilterActionJob *mjob = new FilterActionJob(all, new MyFunctor, this);
109     AKVERIFYEXEC(mjob);
110     ItemFetchJob *fjob = new ItemFetchJob(col, this);
111     fjob->fetchScope().fetchAllAttributes();
112     AKVERIFYEXEC(fjob);
113     QCOMPARE(fjob->items().count(), 10);
114     const auto fJobItems{fjob->items()};
115     for (const Item &item : fJobItems) {
116         QVERIFY(item.hasAttribute<TestAttribute>());
117         const QByteArray data = item.attribute<TestAttribute>()->data;
118         if (data == unacceptable) {
119             QVERIFY(unacc.contains(item));
120             unacc.removeAll(item);
121         } else if (data == modified) {
122             QVERIFY(acc.contains(item));
123             acc.removeAll(item);
124         } else {
125             QVERIFY2(false, QByteArray(QByteArray("Got bad data \"") + data + QByteArray("\"")));
126         }
127     }
128     QCOMPARE(acc.count(), 0);
129     QCOMPARE(unacc.count(), 0);
130 }
131 
testMassModifyCollection()132 void FilterActionTest::testMassModifyCollection()
133 {
134     Collection col = createCollection("testMassModifyCollection");
135 
136     // Test a bunch of acceptable and unacceptable items.
137     Item::List acc, unacc;
138     for (int i = 0; i < 5; i++) {
139         acc.append(createItem(col, true));
140         unacc.append(createItem(col, false));
141     }
142     FilterActionJob *mjob = new FilterActionJob(col, new MyFunctor, this);
143     qDebug() << "Executing FilterActionJob.";
144     AKVERIFYEXEC(mjob);
145     ItemFetchJob *fjob = new ItemFetchJob(col, this);
146     fjob->fetchScope().fetchAllAttributes();
147     AKVERIFYEXEC(fjob);
148     QCOMPARE(fjob->items().count(), 10);
149     const auto fjobItems{fjob->items()};
150     for (const Item &item : fjobItems) {
151         QVERIFY(item.hasAttribute<TestAttribute>());
152         const QByteArray data = item.attribute<TestAttribute>()->data;
153         if (data == unacceptable) {
154             QVERIFY(unacc.contains(item));
155             unacc.removeAll(item);
156         } else if (data == modified) {
157             QVERIFY(acc.contains(item));
158             acc.removeAll(item);
159         } else {
160             QVERIFY2(false, QByteArray(QByteArray("Got bad data \"") + data + QByteArray("\"")));
161         }
162     }
163     QCOMPARE(acc.count(), 0);
164     QCOMPARE(unacc.count(), 0);
165 }
166 
createCollection(const QString & name)167 Collection FilterActionTest::createCollection(const QString &name)
168 {
169     Collection col;
170     col.setParentCollection(res1);
171     col.setName(name);
172     CollectionCreateJob *ccjob = new CollectionCreateJob(col, this);
173     Q_ASSERT(ccjob->exec());
174     return ccjob->collection();
175 }
176 
createItem(const Collection & col,bool accept)177 Item FilterActionTest::createItem(const Collection &col, bool accept)
178 {
179     Q_ASSERT(col.isValid());
180 
181     Item item;
182     item.setMimeType("text/directory");
183     TestAttribute *attr = new TestAttribute;
184     if (accept) {
185         attr->data = acceptable;
186     } else {
187         attr->data = unacceptable;
188     }
189     item.addAttribute(attr);
190     ItemCreateJob *cjob = new ItemCreateJob(item, col, this);
191     Q_ASSERT(cjob->exec());
192     return cjob->item();
193 }
194