[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kdepimlibs/KDE/4.11] akonadi/calendar/tests: sync the unit-tests with master.
From: Sergio Martins <iamsergio () gmail ! com>
Date: 2013-10-31 21:45:18
Message-ID: E1Vc03K-00014u-5A () scm ! kde ! org
[Download RAW message or body]
Git commit d662dbc0c4947b3cffacc4410f5852710a6df481 by Sergio Martins.
Committed on 31/10/2013 at 21:41.
Pushed by smartins into branch 'KDE/4.11'.
sync the unit-tests with master.
This makes much easier to be able to commit in KDE/4.11 and merge
to master. Otherwise I'd have to commit a fix in KDE/4.11 and then
commit the unit test in master, since akonadi isolated tests
don't run on KDE/4.11
A +41 -0 akonadi/calendar/tests/helper.cpp [License: UNKNOWN] *
A +32 -0 akonadi/calendar/tests/helper.h [License: LGPL (v2+)]
M +6 -53 akonadi/calendar/tests/historytest.cpp
M +2 -6 akonadi/calendar/tests/historytest.h
M +7 -1 akonadi/calendar/tests/incidencechangertest.cpp
A +47 -0 akonadi/calendar/tests/itip_data/bug235749
A +41 -0 akonadi/calendar/tests/itip_data/expected_data/cancel1
A +22 -0 akonadi/calendar/tests/itip_data/expected_data/update1
A +23 -0 akonadi/calendar/tests/itip_data/expected_data/update2
A +42 -0 akonadi/calendar/tests/itip_data/expected_data/update3
A +23 -0 akonadi/calendar/tests/itip_data/invited_us
A +24 -0 akonadi/calendar/tests/itip_data/invited_us_cancel01
A +27 -0 akonadi/calendar/tests/itip_data/invited_us_daily
A +43 -0 akonadi/calendar/tests/itip_data/invited_us_daily_cancel01
A +22 -0 akonadi/calendar/tests/itip_data/invited_us_daily_cancel_recid01
A +25 -0 akonadi/calendar/tests/itip_data/invited_us_daily_update01
A +26 -0 akonadi/calendar/tests/itip_data/invited_us_daily_update_recid01
A +23 -0 akonadi/calendar/tests/itip_data/invited_us_update01
A +616 -0 akonadi/calendar/tests/itiphandlertest.cpp [License: LGPL (v2+)]
A +92 -0 akonadi/calendar/tests/itiphandlertest.h [License: LGPL (v2+)]
M +50 -37 akonadi/calendar/tests/mailclienttest.cpp
A +207 -0 akonadi/calendar/tests/todopurgertest.cpp [License: LGPL (v2+)]
A +65 -0 akonadi/calendar/tests/todopurgertest.h [License: LGPL (v2+)]
A +198 -0 akonadi/calendar/tests/unittestbase.cpp [License: LGPL (v2+)]
A +60 -0 akonadi/calendar/tests/unittestbase.h [License: LGPL (v2+)]
M +0 -2 akonadi/calendar/tests/unittestenv/config-sqlite-db.xml
D +0 -2 akonadi/calendar/tests/unittestenv/kdehome/share/config/akonadi_maildir_resource_0rc
D +0 -2 akonadi/calendar/tests/unittestenv/kdehome/share/config/akonadi_mailtransport_dummy_resource_0rc
A +1672 -0 akonadi/calendar/tests/unittestenv/kdehome/share/config/kdebugrc
The files marked with a * at the end have a non valid license. Please read: \
http://techbase.kde.org/Policies/Licensing_Policy and use the headers which are \
listed at that page.
http://commits.kde.org/kdepimlibs/d662dbc0c4947b3cffacc4410f5852710a6df481
diff --git a/akonadi/calendar/tests/helper.cpp b/akonadi/calendar/tests/helper.cpp
new file mode 100644
index 0000000..a152345
--- /dev/null
+++ b/akonadi/calendar/tests/helper.cpp
@@ -0,0 +1,41 @@
+#include "helper.h"
+
+#include <akonadi/itemfetchjob.h>
+#include <akonadi/collectionfetchjob.h>
+#include <akonadi/collectionfetchscope.h>
+
+#include <QLatin1String>
+#include <QStringList>
+
+using namespace Akonadi;
+
+bool Helper::confirmExists(const Akonadi::Item &item)
+{
+ ItemFetchJob *job = new ItemFetchJob(item);
+ return job->exec() != 0;
+}
+
+bool Helper::confirmDoesntExist(const Akonadi::Item &item)
+{
+ ItemFetchJob *job = new ItemFetchJob(item);
+ return job->exec() == 0;
+}
+
+
+Akonadi::Collection Helper::fetchCollection()
+{
+ CollectionFetchJob *job = new CollectionFetchJob(Collection::root(),
+ CollectionFetchJob::Recursive);
+ // Get list of collections
+ job->fetchScope().setContentMimeTypes(QStringList() << \
QLatin1String("application/x-vnd.akonadi.calendar.event")); + const bool ret = \
job->exec(); + Q_ASSERT(ret);
+
+ // Find our collection
+ Collection::List collections = job->collections();
+ Collection collection = collections.first();
+
+ Q_ASSERT(collection.isValid());
+
+ return collection;
+}
diff --git a/akonadi/calendar/tests/helper.h b/akonadi/calendar/tests/helper.h
new file mode 100644
index 0000000..2aee89b
--- /dev/null
+++ b/akonadi/calendar/tests/helper.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (c) 2013 Sérgio Martins <iamsergio@gmail.com>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#ifndef HELPER_H_
+#define HELPER_H_
+
+#include <akonadi/collection.h>
+#include <akonadi/item.h>
+
+namespace Helper {
+ bool confirmExists(const Akonadi::Item &item);
+ bool confirmDoesntExist(const Akonadi::Item &item);
+ Akonadi::Collection fetchCollection();
+}
+
+#endif
diff --git a/akonadi/calendar/tests/historytest.cpp \
b/akonadi/calendar/tests/historytest.cpp index b2b8bd3..2344c30 100644
--- a/akonadi/calendar/tests/historytest.cpp
+++ b/akonadi/calendar/tests/historytest.cpp
@@ -18,6 +18,7 @@
*/
#include "historytest.h"
+#include "helper.h"
#include <akonadi/itemfetchjob.h>
#include <akonadi/itemcreatejob.h>
@@ -25,7 +26,6 @@
#include <akonadi/collectionfetchscope.h>
#include <akonadi/itemfetchscope.h>
#include <akonadi/qtest_akonadi.h>
-
#include <kcalcore/event.h>
#include <QTestEventLoop>
@@ -35,17 +35,6 @@ using namespace KCalCore;
Q_DECLARE_METATYPE(QList<Akonadi::IncidenceChanger::ChangeType>)
-static bool confirmExists(const Akonadi::Item &item)
-{
- ItemFetchJob *job = new ItemFetchJob(item);
- return job->exec() != 0;
-}
-
-static bool confirmDoesntExists(const Akonadi::Item &item)
-{
- ItemFetchJob *job = new ItemFetchJob(item);
- return job->exec() == 0;
-}
static bool checkSummary(const Akonadi::Item &item, const QString &expected)
{
@@ -85,48 +74,12 @@ static Akonadi::Item createItem(const Akonadi::Collection \
&collection) return createJob->item();
}
-void HistoryTest::createIncidence(const QString &uid)
-{
- Item item;
- item.setMimeType(Event::eventMimeType());
- Incidence::Ptr incidence = Incidence::Ptr(new Event());
- incidence->setUid(uid);
- incidence->setSummary(QLatin1String("summary"));
- item.setPayload<KCalCore::Incidence::Ptr>(incidence);
- ItemCreateJob *job = new ItemCreateJob(item, mCollection, this);
- AKVERIFYEXEC(job);
-}
-
-void HistoryTest::fetchCollection()
-{
- CollectionFetchJob *job = new CollectionFetchJob(Collection::root(),
- CollectionFetchJob::Recursive,
- this);
- // Get list of collections
- job->fetchScope().setContentMimeTypes(QStringList() << \
QLatin1String("application/x-vnd.akonadi.calendar.event"));
- AKVERIFYEXEC(job);
-
- // Find our collection
- Collection::List collections = job->collections();
- QVERIFY(!collections.isEmpty());
- mCollection = collections.first();
-
- QVERIFY(mCollection.isValid());
-}
-
void HistoryTest::initTestCase()
{
AkonadiTest::checkTestIsIsolated();
- fetchCollection();
- qRegisterMetaType<Akonadi::Item>("Akonadi::Item");
- qRegisterMetaType<QList<Akonadi::IncidenceChanger::ChangeType> \
>("QList<Akonadi::IncidenceChanger::ChangeType>");
- qRegisterMetaType<QVector<Akonadi::Item::Id> >("QVector<Akonadi::Item::Id>");
- mChanger = new IncidenceChanger(this);
- mChanger->setShowDialogsOnError(false);
- mChanger->setHistoryEnabled(true);
mHistory = mChanger->history();
- mChanger->setDefaultCollection(mCollection);
+
connect(mChanger,
SIGNAL(createFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)),
SLOT(createFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)));
@@ -165,7 +118,7 @@ void HistoryTest::testCreation()
waitForSignals();
// Check that it was created
- QVERIFY(confirmExists(mItemByChangeId.value(changeId)));
+ QVERIFY(Helper::confirmExists(mItemByChangeId.value(changeId)));
QCOMPARE(mHistory->d->redoCount(), 0);
QCOMPARE(mHistory->d->undoCount(), 1);
@@ -176,7 +129,7 @@ void HistoryTest::testCreation()
waitForSignals();
// Check that it doesn't exist anymore
- QVERIFY(confirmDoesntExists(mItemByChangeId.value(changeId)));
+ QVERIFY(Helper::confirmDoesntExist(mItemByChangeId.value(changeId)));
QCOMPARE(mHistory->d->redoCount(), 1);
QCOMPARE(mHistory->d->undoCount(), 0);
@@ -227,7 +180,7 @@ void HistoryTest::testDeletion()
// Check that it doesn't exist anymore
foreach(const Akonadi::Item &item, items) {
- QVERIFY(confirmDoesntExists(item));
+ QVERIFY(Helper::confirmDoesntExist(item));
}
mPendingSignals[UndoSignal] = 1;
@@ -397,7 +350,7 @@ void HistoryTest::testAtomicOperations()
// It changed id, have no way to verify
break;
case IncidenceChanger::ChangeTypeDelete:
- QVERIFY(confirmDoesntExists(item));
+ QVERIFY(Helper::confirmDoesntExist(item));
break;
case IncidenceChanger::ChangeTypeModify:
QVERIFY(checkSummary(item, QLatin1String("random summary")));
diff --git a/akonadi/calendar/tests/historytest.h \
b/akonadi/calendar/tests/historytest.h index f66d2ad..c274acf 100644
--- a/akonadi/calendar/tests/historytest.h
+++ b/akonadi/calendar/tests/historytest.h
@@ -20,6 +20,7 @@
#ifndef HISTORY_TEST_H
#define HISTORY_TEST_H
+#include "unittestbase.h"
#include "../history.h"
#include "../history_p.h"
#include "../incidencechanger.h"
@@ -33,19 +34,14 @@ enum SignalType {
NumSignals
};
-class HistoryTest : public QObject
+class HistoryTest : public UnitTestBase
{
Q_OBJECT
- Collection mCollection;
- IncidenceChanger *mChanger;
History *mHistory;
QHash<SignalType, int> mPendingSignals;
QHash<int, Akonadi::Item> mItemByChangeId;
QList<int> mKnownChangeIds;
- void createIncidence(const QString &uid);
- void fetchCollection();
-
private Q_SLOTS:
void initTestCase();
diff --git a/akonadi/calendar/tests/incidencechangertest.cpp \
b/akonadi/calendar/tests/incidencechangertest.cpp index b9136a9..aa844f2 100644
--- a/akonadi/calendar/tests/incidencechangertest.cpp
+++ b/akonadi/calendar/tests/incidencechangertest.cpp
@@ -165,6 +165,12 @@ class IncidenceChangerTest : public QObject
<< \
IncidenceChanger::DestinationPolicyDefault
<< false << \
IncidenceChanger::ResultCodeSuccess;
+ // In this case, the collection dialog shouldn't be shown, as we only have 1 \
collection + QTest::newRow( "Only one collection" ) << false << "SomeUid6" << \
"Summary6" << Collection() + << \
Collection() << true + << \
IncidenceChanger::DestinationPolicyAsk + \
<< false << IncidenceChanger::ResultCodeSuccess; +
Collection collectionWithoutRights = Collection( mCollection.id() );
collectionWithoutRights.setRights( Collection::Rights() );
Q_ASSERT( ( mCollection.rights() & Akonadi::Collection::CanCreateItem ) );
@@ -250,7 +256,7 @@ class IncidenceChangerTest : public QObject
Item::List items = fetchJob->items();
// 5 Incidences were created in testCreating(). Keep this in sync.
- QVERIFY( items.count() == 4 );
+ QCOMPARE( items.count(), 5 );
QTest::newRow( "Simple delete" ) << (Item::List() << items.at( 0 ) ) << true \
<< false
<< IncidenceChanger::ResultCodeSuccess;
diff --git a/akonadi/calendar/tests/itip_data/bug235749 \
b/akonadi/calendar/tests/itip_data/bug235749 new file mode 100644
index 0000000..6854c94
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/bug235749
@@ -0,0 +1,47 @@
+BEGIN:VCALENDAR
+PRODID:-//Unittest
+VERSION:2.0
+CALSCALE:GREGORIAN
+METHOD:REQUEST
+
+BEGIN:VTIMEZONE
+TZID:America/Toronto
+X-LIC-LOCATION:America/Toronto
+BEGIN:DAYLIGHT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+TZNAME:EDT
+DTSTART:19700308T020000
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=2SU;BYMONTH=3
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+TZNAME:EST
+DTSTART:19701101T020000
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=11
+END:STANDARD
+END:VTIMEZONE
+
+BEGIN:VEVENT
+DTSTART:20100430T140000Z
+DTEND:20100430T150000Z
+ORGANIZER;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:xyz@yahoo.ca
+UID:b6f0466a-8877-49d0-a4fc-8ee18ffd8e07
+ATTENDEE;RSVP=TRUE;CN=XYZ;PARTSTAT=NEEDS-ACTION;
+ ROLE=REQ-PARTICIPANT:mailto:mailto:unittests@dev.nul
+ATTENDEE;RSVP=TRUE;CN=XYZ;PARTSTAT=NEEDS-ACTION;
+ ROLE=REQ-PARTICIPANT:mailto:xyz@pqr.com
+ATTENDEE;RSVP=TRUE;CN='XYZ';PARTSTAT=NEEDS-ACTION;
+ ROLE=REQ-PARTICIPANT:mailto:xyz@pqr.com
+CREATED:20100429T181532Z
+LAST-MODIFIED:20100429T182209Z
+DTSTAMP:20100429T182209Z
+SEQUENCE:0
+STATUS:CONFIRMED
+SUMMARY:sync up on deployment practices
+LOCATION:BoardroomA
+DESCRIPTION:- sync up on current deployment practices\n- discuss futuredeployment \
steps\, production environment +TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
diff --git a/akonadi/calendar/tests/itip_data/expected_data/cancel1 \
b/akonadi/calendar/tests/itip_data/expected_data/cancel1 new file mode 100644
index 0000000..d91d016
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/expected_data/cancel1
@@ -0,0 +1,41 @@
+BEGIN:VCALENDAR
+PRODID:-//K Desktop Environment//NONSGML libkcal 4.3//EN
+VERSION:2.0
+BEGIN:VEVENT
+ORGANIZER:MAILTO:their-email@dev.nul
+DTSTAMP:20131025T103442Z
+ATTENDEE;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT;
+ X-UID=their-email@dev.nul:mailto:their-email@dev.nul
+ATTENDEE;CN="unittests@dev.nul";RSVP=TRUE;PARTSTAT=ACCEPTED;
+ ROLE=REQ-PARTICIPANT;X-UID=unittests@dev.nul:mailto:unittests@dev.nul
+CREATED:20131022T230432Z
+UID:uosj936i6arrtl9c2i5r2mfuvg
+LAST-MODIFIED:20131025T103442Z
+DESCRIPTION:Foo
+SUMMARY:Daily stuff
+STATUS:CONFIRMED
+RRULE:FREQ=DAILY
+DTSTART:20131022T090000Z
+DTEND:20131022T100000Z
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+ORGANIZER:MAILTO:their-email@dev.nul
+DTSTAMP:20131025T103442Z
+ATTENDEE;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT;
+ X-UID=their-email@dev.nul:mailto:their-email@dev.nul
+ATTENDEE;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT;
+ X-UID=unittests@dev.nul:mailto:unittests@dev.nul
+CREATED:20131023T175039Z
+UID:uosj936i6arrtl9c2i5r2mfuvg
+SEQUENCE:1
+LAST-MODIFIED:20131025T103442Z
+DESCRIPTION:Foo
+SUMMARY:Daily stuff
+STATUS:CANCELLED
+RECURRENCE-ID:20131024T000000Z
+DTSTART:20131024T000000Z
+DTEND:20131024T010000Z
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
diff --git a/akonadi/calendar/tests/itip_data/expected_data/update1 \
b/akonadi/calendar/tests/itip_data/expected_data/update1 new file mode 100644
index 0000000..c767ecb
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/expected_data/update1
@@ -0,0 +1,22 @@
+BEGIN:VCALENDAR
+PRODID:-//K Desktop Environment//NONSGML libkcal 4.3//EN
+VERSION:2.0
+BEGIN:VEVENT
+ORGANIZER;CN="iamsergio@gmail.com":MAILTO:iamsergio@gmail.com
+DTSTAMP:20131025T103442Z
+ATTENDEE;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT;
+ X-UID=140218346340032:mailto:their-email@dev.nul
+ATTENDEE;CN="sergio.martins@kdab.com";RSVP=TRUE;PARTSTAT=ACCEPTED;
+ ROLE=REQ-PARTICIPANT;X-UID=140218346000928:mailto:unittests@dev.nul
+CREATED:20131019T224011Z
+UID:uosj936i6arrtl9c2i5r2mfuvg
+SEQUENCE:2
+LAST-MODIFIED:20131025T103442Z
+DESCRIPTION:Random desc
+SUMMARY:new-summary
+STATUS:CONFIRMED
+DTSTART:20131022T102000Z
+DTEND:20131022T112000Z
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
diff --git a/akonadi/calendar/tests/itip_data/expected_data/update2 \
b/akonadi/calendar/tests/itip_data/expected_data/update2 new file mode 100644
index 0000000..6c929a3
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/expected_data/update2
@@ -0,0 +1,23 @@
+BEGIN:VCALENDAR
+PRODID:-//K Desktop Environment//NONSGML libkcal 4.3//EN
+VERSION:2.0
+BEGIN:VEVENT
+ORGANIZER:MAILTO:their-email@dev.nul
+DTSTAMP:20131025T103442Z
+ATTENDEE;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT;
+ X-UID=140218346311392:mailto:their-email@dev.nul
+ATTENDEE;CN="unittests@dev.nul";RSVP=TRUE;PARTSTAT=ACCEPTED;
+ ROLE=REQ-PARTICIPANT;X-UID=140218344168032:mailto:unittests@dev.nul
+CREATED:20131023T175039Z
+UID:uosj936i6arrtl9c2i5r2mfuvg
+SEQUENCE:2
+LAST-MODIFIED:20131025T103442Z
+DESCRIPTION:Foo
+SUMMARY:new-summary
+STATUS:CONFIRMED
+RRULE:FREQ=DAILY
+DTSTART:20131022T090000Z
+DTEND:20131022T100000Z
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
diff --git a/akonadi/calendar/tests/itip_data/expected_data/update3 \
b/akonadi/calendar/tests/itip_data/expected_data/update3 new file mode 100644
index 0000000..1e77f88
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/expected_data/update3
@@ -0,0 +1,42 @@
+BEGIN:VCALENDAR
+PRODID:-//K Desktop Environment//NONSGML libkcal 4.3//EN
+VERSION:2.0
+BEGIN:VEVENT
+ORGANIZER:MAILTO:their-email@dev.nul
+DTSTAMP:20131025T103442Z
+ATTENDEE;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT;
+ X-UID=140218344167648:mailto:their-email@dev.nul
+ATTENDEE;CN="unittests@dev.nul";RSVP=TRUE;PARTSTAT=ACCEPTED;
+ ROLE=REQ-PARTICIPANT;X-UID=140218344958464:mailto:unittests@dev.nul
+CREATED:20131022T230432Z
+UID:uosj936i6arrtl9c2i5r2mfuvg
+LAST-MODIFIED:20131025T103442Z
+DESCRIPTION:Foo
+SUMMARY:Daily stuff
+STATUS:CONFIRMED
+RRULE:FREQ=DAILY
+DTSTART:20131022T090000Z
+DTEND:20131022T100000Z
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+ORGANIZER:MAILTO:their-email@dev.nul
+DTSTAMP:20131025T103442Z
+ATTENDEE;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT;
+ X-UID=140218346119456:mailto:their-email@dev.nul
+ATTENDEE;CN="unittests@dev.nul";RSVP=TRUE;PARTSTAT=ACCEPTED;
+ ROLE=REQ-PARTICIPANT;X-UID=140218346001408:mailto:unittests@dev.nul
+CREATED:20131023T175039Z
+UID:uosj936i6arrtl9c2i5r2mfuvg
+SEQUENCE:1
+LAST-MODIFIED:20131025T103442Z
+DESCRIPTION:Foo
+SUMMARY:new-summary-for-second-occurrence
+STATUS:CONFIRMED
+RECURRENCE-ID:20131023T090000Z
+RRULE:FREQ=DAILY
+DTSTART:20131023T090000Z
+DTEND:20131023T100000Z
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
diff --git a/akonadi/calendar/tests/itip_data/invited_us \
b/akonadi/calendar/tests/itip_data/invited_us new file mode 100644
index 0000000..cfc0740
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/invited_us
@@ -0,0 +1,23 @@
+BEGIN:VCALENDAR
+PRODID:-//Unittest
+VERSION:2.0
+CALSCALE:GREGORIAN
+METHOD:REQUEST
+BEGIN:VEVENT
+DTSTART:20131010T110000Z
+DTEND:20131010T140000Z
+DTSTAMP:20131010T210701Z
+ORGANIZER;CN=their-email@dev.nul:mailto:their-email@dev.nul
+UID:uosj936i6arrtl9c2i5r2mfuvg
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE;X-NUM-GUESTS=0:mailto:their-email@dev.nul
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=sergio.martins@kdab.com;X-NUM-GUESTS=0:mailto:unittests@dev.nul
+CREATED:20131010T210701Z
+DESCRIPTION:Random desc
+LAST-MODIFIED:20131010T210701Z
+LOCATION:
+SEQUENCE:0
+STATUS:CONFIRMED
+SUMMARY:asd
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
\ No newline at end of file
diff --git a/akonadi/calendar/tests/itip_data/invited_us_cancel01 \
b/akonadi/calendar/tests/itip_data/invited_us_cancel01 new file mode 100644
index 0000000..e8f0c87
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/invited_us_cancel01
@@ -0,0 +1,24 @@
+BEGIN:VCALENDAR
+PRODID:-//Unittest
+VERSION:2.0
+CALSCALE:GREGORIAN
+METHOD:CANCEL
+BEGIN:VEVENT
+DTSTART:20131010T110000Z
+DTEND:20131010T140000Z
+DTSTAMP:20131022T221237Z
+ORGANIZER;CN=their-email@dev.nul:mailto:their-email@dev.nul
+UID:uosj936i6arrtl9c2i5r2mfuvg
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
+ STS=0:mailto:their-email@dev.nul
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=unittests@dev.nul;X-NUM-GUESTS=0:mailto:unittests@dev.nul
+CREATED:20131022T221005Z
+DESCRIPTION:
+LAST-MODIFIED:20131022T221237Z
+LOCATION:
+SEQUENCE:1
+STATUS:CANCELLED
+SUMMARY:asd
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
diff --git a/akonadi/calendar/tests/itip_data/invited_us_daily \
b/akonadi/calendar/tests/itip_data/invited_us_daily new file mode 100644
index 0000000..d6dccd5
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/invited_us_daily
@@ -0,0 +1,27 @@
+BEGIN:VCALENDAR
+PRODID:-//
+VERSION:2.0
+CALSCALE:GREGORIAN
+METHOD:REQUEST
+
+BEGIN:VEVENT
+DTSTART:20131022T090000Z
+DTEND:20131022T100000Z
+RRULE:FREQ=DAILY
+DTSTAMP:20131022T230432Z
+ORGANIZER:mailto:their-email@dev.nul
+UID:uosj936i6arrtl9c2i5r2mfuvg
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE
+ ;X-NUM-GUESTS=0:mailto:their-email@dev.nul
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
+ TRUE;CN=unittests@dev.nul;X-NUM-GUESTS=0:mailto:unittests@dev.nul
+CREATED:20131022T230432Z
+DESCRIPTION:Foo
+LAST-MODIFIED:20131022T230432Z
+LOCATION:
+SEQUENCE:0
+STATUS:CONFIRMED
+SUMMARY:Daily stuff
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
diff --git a/akonadi/calendar/tests/itip_data/invited_us_daily_cancel01 \
b/akonadi/calendar/tests/itip_data/invited_us_daily_cancel01 new file mode 100644
index 0000000..5d0c347
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/invited_us_daily_cancel01
@@ -0,0 +1,43 @@
+BEGIN:VCALENDAR
+PRODID:-//
+VERSION:2.0
+CALSCALE:GREGORIAN
+METHOD:CANCEL
+BEGIN:VTIMEZONE
+TZID:Europe/London
+X-LIC-LOCATION:Europe/London
+BEGIN:DAYLIGHT
+TZOFFSETFROM:+0000
+TZOFFSETTO:+0100
+TZNAME:BST
+DTSTART:19700329T010000
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0000
+TZNAME:GMT
+DTSTART:19701025T020000
+RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTART;TZID=Europe/London:20131022T090000
+DTEND;TZID=Europe/London:20131022T100000
+RRULE:FREQ=DAILY
+DTSTAMP:20131022T232159Z
+ORGANIZER:mailto:their-email@dev.nul
+UID:uosj936i6arrtl9c2i5r2mfuvg
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
+ STS=0:mailto:their-email@dev.nul
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=unittests@dev.nul;X-NUM-GUESTS=0:mailto:unittests@dev.nul
+CREATED:20131022T230432Z
+DESCRIPTION:
+LAST-MODIFIED:20131022T232159Z
+LOCATION:
+SEQUENCE:1
+STATUS:CANCELLED
+SUMMARY:Daily stuff
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
diff --git a/akonadi/calendar/tests/itip_data/invited_us_daily_cancel_recid01 \
b/akonadi/calendar/tests/itip_data/invited_us_daily_cancel_recid01 new file mode \
100644 index 0000000..058d8b3
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/invited_us_daily_cancel_recid01
@@ -0,0 +1,22 @@
+BEGIN:VCALENDAR
+PRODID:Zimbra-Calendar-Provider
+VERSION:2.0
+METHOD:CANCEL
+BEGIN:VEVENT
+UID:uosj936i6arrtl9c2i5r2mfuvg
+SUMMARY:Daily stuff
+ATTENDEE;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT;
+ X-UID=140218344167648:mailto:their-email@dev.nul
+ATTENDEE;RSVP=TRUE:mailto:unittests@dev.nul
+ORGANIZER;mailto:their-email@dev.nul
+DTSTART:20131024T000000Z
+DTEND:20131024T010000Z
+STATUS:CANCELLED
+CLASS:PUBLIC
+TRANSP:OPAQUE
+RECURRENCE-ID:20131024T000000Z
+DTSTAMP:20131026T004419Z
+SEQUENCE:1
+DESCRIPTION:Foo
+END:VEVENT
+END:VCALENDAR
\ No newline at end of file
diff --git a/akonadi/calendar/tests/itip_data/invited_us_daily_update01 \
b/akonadi/calendar/tests/itip_data/invited_us_daily_update01 new file mode 100644
index 0000000..5a8f9bb
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/invited_us_daily_update01
@@ -0,0 +1,25 @@
+BEGIN:VCALENDAR
+PRODID:-//Unit-test
+VERSION:2.0
+CALSCALE:GREGORIAN
+METHOD:REQUEST
+BEGIN:VEVENT
+DTSTART:20131022T090000Z
+DTEND:20131022T100000Z
+RRULE:FREQ=DAILY
+DTSTAMP:20131023T175057Z
+ORGANIZER:mailto:their-email@dev.nul
+UID:uosj936i6arrtl9c2i5r2mfuvg
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE
+ ;X-NUM-GUESTS=0:mailto:their-email@dev.nul
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
+ TRUE;CN=unittests@dev.nul;X-NUM-GUESTS=0:mailto:unittests@dev.nul
+CREATED:20131023T175039Z
+DESCRIPTION:Foo
+LAST-MODIFIED:20131023T175057Z
+LOCATION:
+SEQUENCE:1
+STATUS:CONFIRMED
+SUMMARY:new-summary
+END:VEVENT
+END:VCALENDAR
diff --git a/akonadi/calendar/tests/itip_data/invited_us_daily_update_recid01 \
b/akonadi/calendar/tests/itip_data/invited_us_daily_update_recid01 new file mode \
100644 index 0000000..cfcff96
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/invited_us_daily_update_recid01
@@ -0,0 +1,26 @@
+BEGIN:VCALENDAR
+PRODID:-//Unit-test
+VERSION:2.0
+CALSCALE:GREGORIAN
+METHOD:REQUEST
+BEGIN:VEVENT
+DTSTART:20131023T090000Z
+DTEND:20131023T100000Z
+RRULE:FREQ=DAILY
+DTSTAMP:20131023T175057Z
+ORGANIZER:mailto:their-email@dev.nul
+UID:uosj936i6arrtl9c2i5r2mfuvg
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE
+ ;X-NUM-GUESTS=0:mailto:their-email@dev.nul
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
+ TRUE;CN=unittests@dev.nul;X-NUM-GUESTS=0:mailto:unittests@dev.nul
+CREATED:20131023T175039Z
+DESCRIPTION:Foo
+LAST-MODIFIED:20131023T175057Z
+RECURRENCE-ID:20131023T090000Z
+LOCATION:
+SEQUENCE:1
+STATUS:CONFIRMED
+SUMMARY:new-summary-for-second-occurrence
+END:VEVENT
+END:VCALENDAR
diff --git a/akonadi/calendar/tests/itip_data/invited_us_update01 \
b/akonadi/calendar/tests/itip_data/invited_us_update01 new file mode 100644
index 0000000..120b4bf
--- /dev/null
+++ b/akonadi/calendar/tests/itip_data/invited_us_update01
@@ -0,0 +1,23 @@
+BEGIN:VCALENDAR
+PRODID:-//Google Inc//Google Calendar 70.9054//EN
+VERSION:2.0
+CALSCALE:GREGORIAN
+METHOD:REQUEST
+BEGIN:VEVENT
+DTSTART:20131022T102000Z
+DTEND:20131022T112000Z
+DTSTAMP:20131019T224236Z
+ORGANIZER;CN=iamsergio@gmail.com:mailto:iamsergio@gmail.com
+UID:uosj936i6arrtl9c2i5r2mfuvg
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE;X-NUM-GUESTS=0:mailto:their-email@dev.nul
+ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=sergio.martins@kdab.com;X-NUM-GUESTS=0:mailto:unittests@dev.nul
+CREATED:20131019T224011Z
+DESCRIPTION:Random desc
+LAST-MODIFIED:20131019T224236Z
+LOCATION:
+SEQUENCE:1
+STATUS:CONFIRMED
+SUMMARY:new-summary
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
diff --git a/akonadi/calendar/tests/itiphandlertest.cpp \
b/akonadi/calendar/tests/itiphandlertest.cpp new file mode 100644
index 0000000..c601037
--- /dev/null
+++ b/akonadi/calendar/tests/itiphandlertest.cpp
@@ -0,0 +1,616 @@
+/*
+ Copyright (c) 2013 Sérgio Martins <iamsergio@gmail.com>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include "itiphandlertest.h"
+#include "helper.h"
+#include "../mailclient_p.h"
+#include "../fetchjobcalendar.h"
+
+#include <kcalcore/icalformat.h>
+#include <kcalcore/attendee.h>
+#include <akonadi/itemdeletejob.h>
+#include <akonadi/collectionfetchjob.h>
+#include <akonadi/collectionfetchscope.h>
+#include <akonadi/itemfetchscope.h>
+#include <akonadi/qtest_akonadi.h>
+
+#include <kcalcore/event.h>
+
+#include <QString>
+#include <QTestEventLoop>
+
+using namespace Akonadi;
+using namespace KCalCore;
+
+Q_DECLARE_METATYPE(Akonadi::IncidenceChanger::InvitationPolicy)
+Q_DECLARE_METATYPE(QList<Akonadi::IncidenceChanger::ChangeType>)
+Q_DECLARE_METATYPE(Akonadi::ITIPHandler::Result)
+Q_DECLARE_METATYPE(KCalCore::Attendee::PartStat)
+Q_DECLARE_METATYPE(QList<int>)
+
+static const char *s_ourEmail = "unittests@dev.nul"; // change also in \
kdepimlibs/akonadi/calendar/tests/unittestenv/kdehome/share/config +
+void ITIPHandlerTest::initTestCase()
+{
+ AkonadiTest::checkTestIsIsolated();
+ m_pendingItipMessageSignal = 0;
+ m_pendingIncidenceChangerSignal = 0;
+ MailClient::sRunningUnitTests = true;
+ m_itipHandler = 0;
+ m_changer = new IncidenceChanger(this);
+ m_changer->setHistoryEnabled(false);
+ m_changer->setGroupwareCommunication(true);
+ m_changer->setInvitationPolicy(IncidenceChanger::InvitationPolicySend); // don't \
show dialogs +
+ connect(m_changer, \
SIGNAL(createFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)),
+ SLOT(onCreateFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)) \
); +
+ connect(m_changer, \
SIGNAL(deleteFinished(int,QVector<Akonadi::Item::Id>,Akonadi::IncidenceChanger::ResultCode,QString)),
+ SLOT(onDeleteFinished(int,QVector<Akonadi::Item::Id>,Akonadi::IncidenceChanger::ResultCode,QString)) \
); +
+ connect(m_changer,SIGNAL(modifyFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)),
+ SLOT(onModifyFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)) \
); +}
+
+void ITIPHandlerTest::testProcessITIPMessage_data()
+{
+ QTest::addColumn<QString>("data_filename");
+ QTest::addColumn<QString>("action");
+ QTest::addColumn<QString>("receiver");
+ QTest::addColumn<QString>("incidenceUid"); // uid of incidence in invitation
+ QTest::addColumn<Akonadi::ITIPHandler::Result>("expectedResult");
+ QTest::addColumn<int>("expectedNumIncidences");
+ QTest::addColumn<KCalCore::Attendee::PartStat>("expectedPartStat");
+
+ QString data_filename;
+ QString action = QLatin1String("accepted");
+ QString incidenceUid = QString::fromLatin1("uosj936i6arrtl9c2i5r2mfuvg");
+ QString receiver = QLatin1String(s_ourEmail);
+ Akonadi::ITIPHandler::Result expectedResult;
+ int expectedNumIncidences = 0;
+ KCalCore::Attendee::PartStat expectedPartStat;
+
+ //----------------------------------------------------------------------------------------------
+ // Someone invited us to an event, and we accept
+ expectedResult = ITIPHandler::ResultSuccess;
+ data_filename = QLatin1String("invited_us");
+ expectedNumIncidences = 1;
+ expectedPartStat = KCalCore::Attendee::Accepted;
+ action = QLatin1String("accepted");
+ QTest::newRow("invited us1") << data_filename << action << receiver << \
incidenceUid + << expectedResult
+ << expectedNumIncidences
+ << expectedPartStat;
+ //----------------------------------------------------------------------------------------------
+ // Someone invited us to an event, and we accept conditionally
+ expectedResult = ITIPHandler::ResultSuccess;
+ data_filename = QLatin1String("invited_us");
+ expectedNumIncidences = 1;
+ expectedPartStat = KCalCore::Attendee::Tentative;
+ action = QLatin1String("tentative");
+ QTest::newRow("invited us2") << data_filename << action << receiver << \
incidenceUid + << expectedResult
+ << expectedNumIncidences
+ << expectedPartStat;
+ //----------------------------------------------------------------------------------------------
+ // Someone invited us to an event, we delegate it
+ expectedResult = ITIPHandler::ResultSuccess;
+ data_filename = QLatin1String("invited_us");
+
+ // The e-mail to the delegate is sent by kmail's text_calendar.cpp
+ expectedNumIncidences = 1;
+ expectedPartStat = KCalCore::Attendee::Delegated;
+ action = QLatin1String("delegated");
+ QTest::newRow("invited us3") << data_filename << action << receiver << \
incidenceUid + << expectedResult
+ << expectedNumIncidences
+ << expectedPartStat;
+ //----------------------------------------------------------------------------------------------
+ // Process a CANCEL without having the incidence in our calendar.
+ // itiphandler should return success and not error
+ expectedResult = ITIPHandler::ResultSuccess;
+ data_filename = QLatin1String("invited_us");
+ expectedNumIncidences = 0;
+ action = QLatin1String("cancel");
+ QTest::newRow("invited us4") << data_filename << action << receiver << \
incidenceUid + << expectedResult
+ << expectedNumIncidences
+ << expectedPartStat;
+ //----------------------------------------------------------------------------------------------
+ // Here we're testing an error case, where data is null.
+ expectedResult = ITIPHandler::ResultError;
+ expectedNumIncidences = 0;
+ action = QLatin1String("accepted");
+ QTest::newRow("invalid data") << QString() << action << receiver << incidenceUid
+ << expectedResult
+ << expectedNumIncidences
+ << expectedPartStat;
+ //----------------------------------------------------------------------------------------------
+ // Testing invalid action
+ expectedResult = ITIPHandler::ResultError;
+ data_filename = QLatin1String("invitation_us");
+ expectedNumIncidences = 0;
+ action = QLatin1String("accepted");
+ QTest::newRow("invalid action") << data_filename << QString() << receiver << \
incidenceUid + << expectedResult
+ << expectedNumIncidences
+ << expectedPartStat;
+ //----------------------------------------------------------------------------------------------
+ // Test bug 235749
+ expectedResult = ITIPHandler::ResultSuccess;
+ data_filename = QLatin1String("bug235749");
+ expectedNumIncidences = 1;
+ expectedPartStat = KCalCore::Attendee::Accepted;
+ action = QLatin1String("accepted");
+ incidenceUid = QLatin1String("b6f0466a-8877-49d0-a4fc-8ee18ffd8e07"); // Don't \
change, hardcoded in data file + QTest::newRow("bug 235749") << data_filename << \
action << receiver << incidenceUid + << expectedResult
+ << expectedNumIncidences
+ << expectedPartStat;
+ //----------------------------------------------------------------------------------------------
+ // Test counterproposal without a UI delegat set
+ expectedResult = ITIPHandler::ResultError;
+ data_filename = QLatin1String("invited_us");
+ expectedNumIncidences = 0;
+ expectedPartStat = KCalCore::Attendee::Accepted;
+ action = QLatin1String("counter");
+ incidenceUid = QLatin1String("b6f0466a-8877-49d0-a4fc-8ee18ffd8e07");
+ QTest::newRow("counter error") << data_filename << action << receiver << \
incidenceUid + << expectedResult
+ << expectedNumIncidences
+ << expectedPartStat;
+ //----------------------------------------------------------------------------------------------
+}
+
+void ITIPHandlerTest::testProcessITIPMessage()
+{
+ QFETCH(QString, data_filename);
+ QFETCH(QString, action);
+ QFETCH(QString, receiver);
+ QFETCH(QString, incidenceUid);
+ QFETCH(Akonadi::ITIPHandler::Result, expectedResult);
+ QFETCH(int, expectedNumIncidences);
+ QFETCH(KCalCore::Attendee::PartStat, expectedPartStat);
+
+ MailClient::sUnitTestResults.clear();
+ createITIPHandler();
+
+ m_expectedResult = expectedResult;
+
+ QString iCalData = icalData(data_filename);
+ Akonadi::Item::List items;
+ processItip(iCalData, receiver, action, expectedNumIncidences, items);
+
+ if (expectedNumIncidences == 1) {
+ KCalCore::Incidence::Ptr incidence = \
items.first().payload<KCalCore::Incidence::Ptr>(); + QVERIFY(incidence);
+ QCOMPARE(incidence->schedulingID(), incidenceUid);
+ QVERIFY(incidence->schedulingID() != incidence->uid());
+
+ KCalCore::Attendee::Ptr me = ourAttendee(incidence);
+ QVERIFY(me);
+ QCOMPARE(me->status(), expectedPartStat);
+ }
+
+ cleanup();
+}
+
+void ITIPHandlerTest::testProcessITIPMessages_data()
+{
+ QTest::addColumn<QStringList>("invitation_filenames"); // filename to create \
incidence (inputs) + QTest::addColumn<QString>("expected_filename"); // filename \
with expected data (reference) + QTest::addColumn<QStringList>("actions"); // we \
must specify the METHOD. This is an ITipHandler API workaround, not sure why we must \
pass it as argument since it's already inside the icaldata. + QStringList \
invitation_filenames; + QString expected_filename;
+ QStringList actions;
+ actions << QLatin1String("accepted") << QLatin1String("accepted");
+
+ //----------------------------------------------------------------------------------------------
+ // Someone invited us to an event, we accept, then organizer changes event, and \
we record update: + invitation_filenames.clear();
+ invitation_filenames << QLatin1String("invited_us") << \
QLatin1String("invited_us_update01"); + expected_filename = \
QLatin1String("expected_data/update1"); + QTest::newRow("accept update") << \
invitation_filenames << expected_filename << actions; + \
//----------------------------------------------------------------------------------------------
+ // Someone invited us to an event, we accept, then organizer changes event, and \
we record update: + invitation_filenames.clear();
+ invitation_filenames << QLatin1String("invited_us") << \
QLatin1String("invited_us_daily_update01"); + expected_filename = \
QLatin1String("expected_data/update2"); + QTest::newRow("accept recurringupdate") \
<< invitation_filenames << expected_filename << actions; + \
//----------------------------------------------------------------------------------------------
+ // We accept a recurring event, then the organizer changes the summary to the \
second instance (RECID) + expected_filename = \
QLatin1String("expected_data/update3"); + invitation_filenames.clear();
+ invitation_filenames << QLatin1String("invited_us_daily") << \
QLatin1String("invited_us_daily_update_recid01"); + QTest::newRow("accept recid \
update") << invitation_filenames << expected_filename << actions; + \
//----------------------------------------------------------------------------------------------
+ // We accept a recurring event, then we accept a CANCEL with recuring-id.
+ // The result is that a exception with status CANCELLED should be created, and \
our main incidence + // should not be touched
+ invitation_filenames.clear();
+ invitation_filenames << QLatin1String("invited_us_daily") << \
QLatin1String("invited_us_daily_cancel_recid01"); + expected_filename = \
QLatin1String("expected_data/cancel1"); + actions << QLatin1String("accepted") << \
QLatin1String("cancel"); + QTest::newRow("accept recid cancel") << \
invitation_filenames << expected_filename << actions; +
+ //----------------------------------------------------------------------------------------------
+}
+
+void ITIPHandlerTest::testProcessITIPMessages()
+{
+ QFETCH(QStringList, invitation_filenames);
+ QFETCH(QString, expected_filename);
+ QFETCH(QStringList, actions);
+
+ const QString receiver = QLatin1String(s_ourEmail);
+
+ MailClient::sUnitTestResults.clear();
+ createITIPHandler();
+
+ m_expectedResult = Akonadi::ITIPHandler::ResultSuccess;
+
+ for (int i=0; i<invitation_filenames.count(); i++) {
+ // First accept the invitation that creates the incidence:
+ QString iCalData = icalData(invitation_filenames.at(i));
+ Item::List items;
+ qDebug() << "Processing " << invitation_filenames.at(i);
+ processItip(iCalData, receiver, actions.at(i), -1, items);
+ }
+
+
+ QString expectedICalData = icalData(expected_filename);
+ KCalCore::MemoryCalendar::Ptr expectedCalendar = \
KCalCore::MemoryCalendar::Ptr(new KCalCore::MemoryCalendar(KDateTime::UTC)); + \
KCalCore::ICalFormat format; + format.fromString(expectedCalendar, \
expectedICalData); + compareCalendars(expectedCalendar); // Here's where the cool \
and complex comparations are done +
+ cleanup();
+}
+
+void ITIPHandlerTest::testProcessITIPMessageCancel_data()
+{
+ QTest::addColumn<QString>("creation_data_filename"); // filename to create \
incidence + QTest::addColumn<QString>("cancel_data_filename"); // filename with \
incidence cancelation + QTest::addColumn<QString>("incidenceUid"); // uid of \
incidence in invitation +
+
+ QString creation_data_filename;
+ QString cancel_data_filename;
+ QString incidenceUid = QString::fromLatin1("uosj936i6arrtl9c2i5r2mfuvg");
+ //----------------------------------------------------------------------------------------------
+ // Someone invited us to an event, we accept, then organizer cancels event
+ creation_data_filename = QLatin1String("invited_us");
+ cancel_data_filename = QLatin1String("invited_us_cancel01");
+
+ QTest::newRow("cancel1") << creation_data_filename << cancel_data_filename
+ << incidenceUid;
+ //----------------------------------------------------------------------------------------------
+ // Someone invited us to daily event, we accept, then organizer cancels the \
whole recurrence series + creation_data_filename = \
QLatin1String("invited_us_daily"); + cancel_data_filename = \
QLatin1String("invited_us_daily_cancel01"); +
+ QTest::newRow("cancel_daily") << creation_data_filename << cancel_data_filename
+ << incidenceUid;
+ //----------------------------------------------------------------------------------------------
+}
+
+void ITIPHandlerTest::testProcessITIPMessageCancel()
+{
+ QFETCH(QString, creation_data_filename);
+ QFETCH(QString, cancel_data_filename);
+ QFETCH(QString, incidenceUid);
+
+ const QString receiver = QLatin1String(s_ourEmail);
+ MailClient::sUnitTestResults.clear();
+ createITIPHandler();
+
+ m_expectedResult = Akonadi::ITIPHandler::ResultSuccess;
+
+ // First accept the invitation that creates the incidence:
+ QString iCalData = icalData(creation_data_filename);
+ Item::List items;
+ processItip(iCalData, receiver, QLatin1String("accepted"), 1, items);
+
+ KCalCore::Incidence::Ptr incidence = \
items.first().payload<KCalCore::Incidence::Ptr>(); + QVERIFY(incidence);
+
+ // good, now accept the invitation that has the CANCEL
+ iCalData = icalData(cancel_data_filename);
+ processItip(iCalData, receiver, QLatin1String("accepted"), 0, items);
+}
+
+void ITIPHandlerTest::testOutgoingInvitations_data()
+{
+ QTest::addColumn<Akonadi::Item>("item"); // existing incidence that will be \
target of creation, deletion or modification + \
QTest::addColumn<Akonadi::IncidenceChanger::ChangeType>("changeType"); // creation, \
deletion, modification + QTest::addColumn<int>("expectedEmailCount");
+ QTest::addColumn<IncidenceChanger::InvitationPolicy>("invitationPolicy");
+
+ Akonadi::Item item;
+ KCalCore::Incidence::Ptr incidence;
+ IncidenceChanger::ChangeType changeType;
+ const IncidenceChanger::InvitationPolicy invitationPolicyAsk = \
IncidenceChanger::InvitationPolicyAsk; + const IncidenceChanger::InvitationPolicy \
invitationPolicySend = IncidenceChanger::InvitationPolicySend; + const \
IncidenceChanger::InvitationPolicy invitationPolicyDontSend = \
IncidenceChanger::InvitationPolicyDontSend; + int expectedEmailCount = 0;
+ Q_UNUSED(invitationPolicyAsk);
+
+ const QString ourEmail = QLatin1String(s_ourEmail);
+ const Attendee::Ptr us = Attendee::Ptr(new Attendee(QString(), ourEmail));
+ const Attendee::Ptr mia = Attendee::Ptr(new Attendee(QLatin1String("Mia \
Wallace"), QLatin1String("mia@dev.nul"))); + const Attendee::Ptr vincent = \
Attendee::Ptr(new Attendee(QLatin1String("Vincent"), \
QLatin1String("vincent@dev.nul"))); + const Attendee::Ptr jules = \
Attendee::Ptr(new Attendee(QLatin1String("Jules"), QLatin1String("jules@dev.nul"))); \
+ const QString uid = QLatin1String("random-uid-123"); +
+ //----------------------------------------------------------------------------------------------
+ // Creation. We are organizer. We invite another person.
+ changeType = IncidenceChanger::ChangeTypeCreate;
+ item = generateIncidence(uid, /**organizer=*/ourEmail);
+ incidence = item.payload<KCalCore::Incidence::Ptr>();
+ incidence->addAttendee(vincent);
+ incidence->addAttendee(jules);
+ expectedEmailCount = 1;
+ QTest::newRow("Creation. We organize.") << item << changeType << \
expectedEmailCount << invitationPolicySend; + \
//----------------------------------------------------------------------------------------------
+ // Creation. We are organizer. We invite another person. But we choose not to \
send invitation e-mail. + changeType = IncidenceChanger::ChangeTypeCreate;
+ item = generateIncidence(uid, /**organizer=*/ourEmail);
+ incidence = item.payload<KCalCore::Incidence::Ptr>();
+ incidence->addAttendee(vincent);
+ incidence->addAttendee(jules);
+ expectedEmailCount = 0;
+ QTest::newRow("Creation. We organize.2") << item << changeType << \
expectedEmailCount << invitationPolicyDontSend; + \
//----------------------------------------------------------------------------------------------
+ // We delete an event that we organized, and has attendees, that will be \
notified. + changeType = IncidenceChanger::ChangeTypeDelete;
+ item = generateIncidence(uid, /**organizer=*/ourEmail);
+ incidence = item.payload<KCalCore::Incidence::Ptr>();
+ incidence->addAttendee(vincent);
+ incidence->addAttendee(jules);
+ expectedEmailCount = 1;
+ QTest::newRow("Deletion. We organized.") << item << changeType << \
expectedEmailCount << invitationPolicySend; + \
//----------------------------------------------------------------------------------------------
+ // We delete an event that we organized, and has attendees. We won't send \
e-mail notifications. + changeType = IncidenceChanger::ChangeTypeDelete;
+ item = generateIncidence(uid, /**organizer=*/ourEmail);
+ incidence = item.payload<KCalCore::Incidence::Ptr>();
+ incidence->addAttendee(vincent);
+ incidence->addAttendee(jules);
+ expectedEmailCount = 0;
+ QTest::newRow("Deletion. We organized.2") << item << changeType << \
expectedEmailCount << invitationPolicyDontSend; + \
//----------------------------------------------------------------------------------------------
+ // We delete an event that we organized, and has attendees, who will be \
notified. + changeType = IncidenceChanger::ChangeTypeModify;
+ item = generateIncidence(uid, /**organizer=*/ourEmail);
+ incidence = item.payload<KCalCore::Incidence::Ptr>();
+ incidence->addAttendee(vincent);
+ incidence->addAttendee(jules);
+ expectedEmailCount = 1;
+ QTest::newRow("Modification. We organizd.") << item << changeType << \
expectedEmailCount << invitationPolicySend; + \
//----------------------------------------------------------------------------------------------
+ // We delete an event that we organized, and has attendees, who wont be \
notified. + changeType = IncidenceChanger::ChangeTypeModify;
+ item = generateIncidence(uid, /**organizer=*/ourEmail);
+ incidence = item.payload<KCalCore::Incidence::Ptr>();
+ incidence->addAttendee(vincent); // TODO: test that all attendees got the e-mail
+ incidence->addAttendee(jules);
+ expectedEmailCount = 0;
+ QTest::newRow("Modification. We organizd.2") << item << changeType << \
expectedEmailCount << invitationPolicyDontSend; + \
//----------------------------------------------------------------------------------------------
+ // We delete an event which we're not the organizer of. Organizer gets REPLY \
with PartState=Declined + changeType = IncidenceChanger::ChangeTypeDelete;
+ item = generateIncidence(uid, /**organizer=*/mia->email());
+ incidence = item.payload<KCalCore::Incidence::Ptr>();
+ incidence->addAttendee(vincent);
+ incidence->addAttendee(jules);
+ us->setStatus(Attendee::Accepted); // TODO: Test without accepted status
+ incidence->addAttendee(us); // TODO: test that attendees didn't receive the \
REPLY + expectedEmailCount = 1; // REPLY is always sent, there are no dialogs to \
control this. Dialogs only control REQUEST and CANCEL. Bug or feature ? + \
QTest::newRow("Deletion. We didnt organize.") << item << changeType << \
expectedEmailCount << invitationPolicyDontSend; + \
//----------------------------------------------------------------------------------------------
+ // We delete an event which we're not the organizer of. Organizer gets REPLY \
with PartState=Declined + changeType = IncidenceChanger::ChangeTypeDelete;
+ item = generateIncidence(uid, /**organizer=*/mia->email());
+ incidence = item.payload<KCalCore::Incidence::Ptr>();
+ incidence->addAttendee(vincent);
+ incidence->addAttendee(jules); // TODO: test that attendees didn't receive the \
REPLY + us->setStatus(Attendee::Accepted); // TODO: Test without accepted status
+ incidence->addAttendee(us);
+ expectedEmailCount = 1;
+ QTest::newRow("Deletion. We didnt organize.2") << item << changeType << \
expectedEmailCount << invitationPolicySend; + \
//----------------------------------------------------------------------------------------------
+}
+
+void ITIPHandlerTest::testOutgoingInvitations()
+{
+ QFETCH(Akonadi::Item, item);
+ QFETCH(IncidenceChanger::ChangeType, changeType);
+ QFETCH(int, expectedEmailCount);
+ QFETCH(IncidenceChanger::InvitationPolicy, invitationPolicy);
+ KCalCore::Incidence::Ptr incidence = item.payload<KCalCore::Incidence::Ptr>();
+
+ m_pendingIncidenceChangerSignal = 1;
+ MailClient::sUnitTestResults.clear();
+ m_changer->setInvitationPolicy(invitationPolicy);
+
+ switch(changeType) {
+ case IncidenceChanger::ChangeTypeCreate:
+ m_changer->createIncidence(incidence, mCollection);
+ waitForIt();
+ QCOMPARE(MailClient::sUnitTestResults.count(), expectedEmailCount);
+ break;
+ case IncidenceChanger::ChangeTypeModify: {
+ // Create if first, so we have something to modify
+ m_changer->setGroupwareCommunication(false); // we disable groupware because \
creating an incidence which we're not the organizer of is not permitted. + \
m_changer->createIncidence(incidence, mCollection); + waitForIt();
+ m_changer->setGroupwareCommunication(true);
+ QCOMPARE(MailClient::sUnitTestResults.count(), 0);
+ QVERIFY(mLastInsertedItem.isValid());
+ m_pendingIncidenceChangerSignal = 1;
+ Incidence::Ptr oldIncidence = Incidence::Ptr(incidence->clone());
+ incidence->setSummary(QLatin1String("the-new-summary"));
+ int changeId = m_changer->modifyIncidence(mLastInsertedItem, oldIncidence);
+ QVERIFY(changeId != 1);
+ waitForIt();
+ QCOMPARE(MailClient::sUnitTestResults.count(), expectedEmailCount);
+ }
+ break;
+ case IncidenceChanger::ChangeTypeDelete:
+ // Create if first, so we have something to delete
+ m_changer->setGroupwareCommunication(false);
+ m_changer->createIncidence(incidence, mCollection);
+ waitForIt();
+ m_changer->setGroupwareCommunication(true);
+ QCOMPARE(MailClient::sUnitTestResults.count(), 0);
+
+ QVERIFY(mLastInsertedItem.isValid());
+ m_pendingIncidenceChangerSignal = 1;
+ m_changer->deleteIncidence(mLastInsertedItem);
+ waitForIt();
+ QCOMPARE(MailClient::sUnitTestResults.count(), expectedEmailCount);
+ break;
+ default:
+ Q_ASSERT(false);
+ }
+
+}
+
+void ITIPHandlerTest::cleanup()
+{
+ Akonadi::Item::List items = calendarItems();
+ foreach (const Akonadi::Item &item, items) {
+ ItemDeleteJob *job = new ItemDeleteJob(item);
+ AKVERIFYEXEC(job);
+ }
+
+ delete m_itipHandler;
+ m_itipHandler = 0;
+}
+
+void ITIPHandlerTest::createITIPHandler()
+{
+ m_itipHandler = new Akonadi::ITIPHandler();
+ m_itipHandler->setShowDialogsOnError(false);
+ connect(m_itipHandler, \
SIGNAL(iTipMessageProcessed(Akonadi::ITIPHandler::Result,QString)), + \
SLOT(oniTipMessageProcessed(Akonadi::ITIPHandler::Result,QString)) ); +}
+
+QString ITIPHandlerTest::icalData(const QString &data_filename)
+{
+ QString absolutePath = QLatin1String(ITIP_DATA_DIR) + QLatin1Char('/') + \
data_filename; + return QString::fromLatin1(readFile(absolutePath));
+}
+
+void ITIPHandlerTest::processItip(const QString &icaldata, const QString &receiver,
+ const QString &action, int expectedNumIncidences,
+ Akonadi::Item::List &items)
+{
+ items.clear();
+ m_pendingItipMessageSignal = 1;
+ m_itipHandler->processiTIPMessage(receiver, icaldata, action);
+ waitForIt();
+
+ // 0 e-mails are sent because the status update e-mail is sent by
+ // kmail's text_calendar.cpp.
+ QCOMPARE(MailClient::sUnitTestResults.count(), 0);
+
+ items = calendarItems();
+
+ if (expectedNumIncidences != -1) {
+ QCOMPARE(items.count(), expectedNumIncidences);
+ }
+}
+
+Attendee::Ptr ITIPHandlerTest::ourAttendee(const KCalCore::Incidence::Ptr \
&incidence) const +{
+ KCalCore::Attendee::List attendees = incidence->attendees();
+ KCalCore::Attendee::Ptr me;
+ foreach (const KCalCore::Attendee::Ptr &attendee, attendees) {
+ if (attendee->email() == QLatin1String(s_ourEmail)) {
+ me = attendee;
+ break;
+ }
+ }
+
+ return me;
+}
+
+void ITIPHandlerTest::oniTipMessageProcessed(ITIPHandler::Result result, const \
QString &errorMessage) +{
+ if (result != ITIPHandler::ResultSuccess && result != m_expectedResult) {
+ qDebug() << "ITIPHandlerTest::oniTipMessageProcessed() error = " << \
errorMessage; + }
+
+ m_pendingItipMessageSignal--;
+ QVERIFY(m_pendingItipMessageSignal >= 0);
+ if (m_pendingItipMessageSignal == 0) {
+ stopWaiting();
+ }
+
+ QCOMPARE(m_expectedResult, result);
+}
+
+void ITIPHandlerTest::onCreateFinished(int changeId, const Item &item,
+ IncidenceChanger::ResultCode resultCode,
+ const QString &errorString)
+{
+ Q_UNUSED(changeId);
+ Q_UNUSED(errorString);
+ mLastInsertedItem = item;
+ QCOMPARE(resultCode, IncidenceChanger::ResultCodeSuccess);
+ m_pendingIncidenceChangerSignal--;
+ QVERIFY(m_pendingIncidenceChangerSignal >= 0);
+ if (m_pendingIncidenceChangerSignal == 0) {
+ stopWaiting();
+ }
+}
+
+void ITIPHandlerTest::onDeleteFinished(int changeId, const QVector<Entity::Id> \
&deletedIds, + IncidenceChanger::ResultCode \
resultCode, + const QString &errorString)
+{
+ Q_UNUSED(changeId);
+ Q_UNUSED(errorString);
+ Q_UNUSED(deletedIds);
+ QCOMPARE(resultCode, IncidenceChanger::ResultCodeSuccess);
+ m_pendingIncidenceChangerSignal--;
+ QVERIFY(m_pendingIncidenceChangerSignal >= 0);
+ if (m_pendingIncidenceChangerSignal == 0) {
+ stopWaiting();
+ }
+}
+
+void ITIPHandlerTest::onModifyFinished(int changeId, const Item &item,
+ IncidenceChanger::ResultCode resultCode,
+ const QString &errorString)
+{
+ Q_UNUSED(changeId);
+ Q_UNUSED(errorString);
+ Q_UNUSED(item);
+
+ QCOMPARE(resultCode, IncidenceChanger::ResultCodeSuccess);
+ m_pendingIncidenceChangerSignal--;
+ QVERIFY(m_pendingIncidenceChangerSignal >= 0);
+ if (m_pendingIncidenceChangerSignal == 0) {
+ stopWaiting();
+ }
+}
+
+QTEST_AKONADIMAIN(ITIPHandlerTest, GUI)
diff --git a/akonadi/calendar/tests/itiphandlertest.h \
b/akonadi/calendar/tests/itiphandlertest.h new file mode 100644
index 0000000..df3844c
--- /dev/null
+++ b/akonadi/calendar/tests/itiphandlertest.h
@@ -0,0 +1,92 @@
+/*
+ Copyright (c) 2013 Sérgio Martins <iamsergio@gmail.com>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#ifndef ITIPHANDLER_TEST_H
+#define ITIPHANDLER_TEST_H
+
+#include "../incidencechanger.h"
+#include "../itiphandler.h"
+#include "unittestbase.h"
+
+#include <akonadi/collection.h>
+#include <akonadi/item.h>
+
+#include <QObject>
+#include <QHash>
+
+
+class ITIPHandlerTest : public UnitTestBase
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void initTestCase();
+
+ void testProcessITIPMessages_data();
+ void testProcessITIPMessages();
+
+ // Deprecated methods, use testProcessITIPMessages() for new stuff
+ void testProcessITIPMessage_data();
+ void testProcessITIPMessage();
+
+ // Deprecated methods do test CANCEL.
+ void testProcessITIPMessageCancel_data();
+ void testProcessITIPMessageCancel();
+
+ // These ones don't have to do with kmail. It's when doing a modification, itip \
REQUESTs are sent. + // Also tests cases where we're not the organizer.
+ void testOutgoingInvitations_data();
+ void testOutgoingInvitations();
+
+private:
+ void waitForSignals();
+ void cleanup();
+ void createITIPHandler();
+ QString icalData(const QString &filename);
+ void processItip(const QString &icaldata, const QString &receiver,
+ const QString &action, int expectedNumIncidences,
+ Akonadi::Item::List &items);
+ KCalCore::Attendee::Ptr ourAttendee(const KCalCore::Incidence::Ptr &incidence) \
const; +
+public Q_SLOTS:
+ void oniTipMessageProcessed(Akonadi::ITIPHandler::Result result,
+ const QString &errorMessage);
+
+ void onCreateFinished(int changeId, const Akonadi::Item &item,
+ Akonadi::IncidenceChanger::ResultCode resultCode,
+ const QString &errorString);
+
+ void onDeleteFinished(int changeId, const QVector<Akonadi::Item::Id> \
&deletedIds, + Akonadi::IncidenceChanger::ResultCode \
resultCode, + const QString &errorMessage);
+
+ void onModifyFinished(int changeId, const Akonadi::Item &item,
+ Akonadi::IncidenceChanger::ResultCode resultCode,
+ const QString &errorString);
+
+private:
+ int m_pendingItipMessageSignal;
+ int m_pendingIncidenceChangerSignal;
+ Akonadi::Item mLastInsertedItem;
+ Akonadi::ITIPHandler::Result m_expectedResult;
+ Akonadi::ITIPHandler *m_itipHandler;
+ Akonadi::IncidenceChanger *m_changer;
+};
+
+#endif
diff --git a/akonadi/calendar/tests/mailclienttest.cpp \
b/akonadi/calendar/tests/mailclienttest.cpp index 425b231..2231401 100644
--- a/akonadi/calendar/tests/mailclienttest.cpp
+++ b/akonadi/calendar/tests/mailclienttest.cpp
@@ -19,19 +19,20 @@
// mailclient_p.cpp isn't exported so we include it directly.
-#define MAILCLIENTTEST_UNITTEST
-#include "../mailclient_p.cpp"
-#include "../moc_mailclient_p.cpp"
+#include "../mailclient_p.h"
#include <kcalcore/incidence.h>
#include <kcalcore/freebusy.h>
#include <mailtransport/messagequeuejob.h>
+#include <kpimidentities/identity.h>
#include <akonadi/qtest_akonadi.h>
#include <QTestEventLoop>
#include <QtCore/QObject>
+static const char *s_ourEmail = "unittests@dev.nul"; // change also in \
kdepimlibs/akonadi/calendar/tests/unittestenv/kdehome/share/config +
using namespace Akonadi;
Q_DECLARE_METATYPE( KPIMIdentities::Identity )
@@ -55,6 +56,7 @@ private slots:
mPendingSignals = 0;
mMailClient = new MailClient( this );
+ mMailClient->sRunningUnitTests = true;
mLastResult = MailClient::ResultSuccess;
connect( mMailClient, SIGNAL(finished(Akonadi::MailClient::Result,QString)),
SLOT(handleFinished(Akonadi::MailClient::Result,QString)) );
@@ -114,7 +116,7 @@ private slots:
incidence->addAttendee( attendee );
incidence->setOrganizer( organizer );
expectedResult = MailClient::ResultSuccess;
- toList << QLatin1String( "name1 <test@foo.org>" );
+ toList << QLatin1String( "test@foo.org" );
QTest::newRow("One attendee") << incidence << identity << bccMe << attachment << \
transport
<< expectedResult << expectedTransportId << \
expectedFrom << toList << toCcList << toBccList;
@@ -142,11 +144,11 @@ private slots:
expectedResult = MailClient::ResultSuccess;
// Should default to the default transport
toBccList.clear();
- toBccList << QLatin1String( "Organizer <unittests@dev.nul>" );
- QTest::newRow("Invalid transport") << incidence << identity << /*bccMe*/true << \
attachment
- << transport << expectedResult
- << expectedTransportId << expectedFrom
- << toList << toCcList << toBccList;
+ toBccList << QLatin1String( "unittests@dev.nul" );
+ QTest::newRow("Test bcc") << incidence << identity << /*bccMe*/true << \
attachment + << transport << \
expectedResult + << expectedTransportId << \
expectedFrom + << toList << toCcList << \
toBccList;
//----------------------------------------------------------------------------------------------
// Test CC list
attendee = KCalCore::Attendee::Ptr ( new KCalCore::Attendee( QLatin1String( \
"name1" ), @@ -167,15 +169,15 @@ private slots:
expectedResult = MailClient::ResultSuccess;
// Should default to the default transport
toBccList.clear();
- toBccList << QLatin1String( "Organizer <unittests@dev.nul>" );
+ toBccList << QLatin1String( "unittests@dev.nul" );
toCcList.clear();
- toCcList << QLatin1String( "opt <optional@foo.org>" )
- << QLatin1String( "non <non@foo.org>" );
- QTest::newRow("Invalid transport") << incidence << identity << /*bccMe*/true << \
attachment
- << transport << expectedResult
- << expectedTransportId << expectedFrom
- << toList << toCcList << toBccList;
+ toCcList << QLatin1String( "optional@foo.org" )
+ << QLatin1String( "non@foo.org" );
+ QTest::newRow("Test cc") << incidence << identity << /*bccMe*/true << attachment
+ << transport << expectedResult
+ << expectedTransportId << expectedFrom
+ << toList << toCcList << toBccList;
}
void testMailAttendees()
@@ -191,6 +193,7 @@ private slots:
QFETCH( QStringList, expectedToList );
QFETCH( QStringList, expectedCcList );
QFETCH( QStringList, expectedBccList );
+ mMailClient->sUnitTestResults.clear();
mPendingSignals = 1;
mMailClient->mailAttendees( incidence, identity, bccMe, attachment, transport );
@@ -202,18 +205,23 @@ private slots:
QVERIFY( false );
}
+ UnitTestResult unitTestResult;
+ if ( mMailClient->sUnitTestResults.isEmpty() ) {
+ qDebug() << "mail results are empty";
+ } else {
+ unitTestResult = mMailClient->sUnitTestResults.first();
+ }
- if ( expectedTransportId != -1 &&
- mMailClient->mUnitTestResult.transportId != expectedTransportId ) {
- qDebug() << "got " << mMailClient->mUnitTestResult.transportId
+ if ( expectedTransportId != -1 && unitTestResult.transportId != \
expectedTransportId ) { + qDebug() << "got " << unitTestResult.transportId
<< "; expected=" << expectedTransportId;
QVERIFY( false );
}
- QCOMPARE( mMailClient->mUnitTestResult.from, expectedFrom );
- QCOMPARE( mMailClient->mUnitTestResult.to, expectedToList );
- QCOMPARE( mMailClient->mUnitTestResult.cc, expectedCcList );
- QCOMPARE( mMailClient->mUnitTestResult.bcc, expectedBccList );
+ QCOMPARE( unitTestResult.from, expectedFrom );
+ QCOMPARE( unitTestResult.to, expectedToList );
+ QCOMPARE( unitTestResult.cc, expectedCcList );
+ QCOMPARE( unitTestResult.bcc, expectedBccList );
}
void testMailOrganizer_data()
@@ -234,7 +242,7 @@ private slots:
KCalCore::IncidenceBase::Ptr incidence( new KCalCore::Event() );
KPIMIdentities::Identity identity;
- const QString from = QLatin1String( "from@kde.org" );
+ const QString from = QLatin1String( s_ourEmail );
bool bccMe;
QString attachment;
QString subject = QLatin1String( "subject1" );
@@ -247,7 +255,7 @@ private slots:
incidence->setOrganizer( organizer );
QStringList toList;
- toList << QLatin1String( "Organizer <unittests@dev.nul>" );
+ toList << QLatin1String( "unittests@dev.nul" );
QStringList toBccList;
QString expectedSubject;
//----------------------------------------------------------------------------------------------
@@ -279,18 +287,21 @@ private slots:
QFETCH( QStringList, expectedToList );
QFETCH( QStringList, expectedBccList );
QFETCH( QString, expectedSubject );
+ mMailClient->sUnitTestResults.clear();
mPendingSignals = 1;
mMailClient->mailOrganizer( incidence, identity, from, bccMe, attachment, \
subject, transport ); waitForSignals();
QCOMPARE( mLastResult, expectedResult );
+
+ UnitTestResult unitTestResult = mMailClient->sUnitTestResults.first();
if ( expectedTransportId != -1 )
- QCOMPARE( mMailClient->mUnitTestResult.transportId, expectedTransportId );
+ QCOMPARE( unitTestResult.transportId, expectedTransportId );
- QCOMPARE( mMailClient->mUnitTestResult.from, expectedFrom );
- QCOMPARE( mMailClient->mUnitTestResult.to, expectedToList );
- QCOMPARE( mMailClient->mUnitTestResult.bcc, expectedBccList );
- QCOMPARE( mMailClient->mUnitTestResult.message->subject()->asUnicodeString(), \
expectedSubject ); + QCOMPARE( unitTestResult.from, expectedFrom );
+ QCOMPARE( unitTestResult.to, expectedToList );
+ QCOMPARE( unitTestResult.bcc, expectedBccList );
+ QCOMPARE( unitTestResult.message->subject()->asUnicodeString(), expectedSubject \
); }
void testMailTo_data()
@@ -310,9 +321,9 @@ private slots:
KCalCore::IncidenceBase::Ptr incidence( new KCalCore::Event() );
KPIMIdentities::Identity identity;
- const QString from = QLatin1String( "from@kde.org" );
+ const QString from = QLatin1String( s_ourEmail );
bool bccMe;
- const QString recipients = QLatin1String( "Organizer <unittests@dev.nul>" );
+ const QString recipients = QLatin1String( "unittests@dev.nul" );
QString attachment;
QString transport;
MailClient::Result expectedResult = MailClient::ResultSuccess;
@@ -321,7 +332,7 @@ private slots:
KCalCore::Person::Ptr organizer( new KCalCore::Person( QLatin1String( \
"Organizer" ),
QLatin1String( \
"unittests@dev.nul" ) ) ); QStringList toList;
- toList << QLatin1String( "Organizer <unittests@dev.nul>" );
+ toList << QLatin1String( s_ourEmail );
QStringList toBccList;
//----------------------------------------------------------------------------------------------
QTest::newRow("test1") << incidence << identity << from << bccMe << recipients \
<< attachment @@ -343,17 +354,19 @@ private slots:
QFETCH( QString, expectedFrom );
QFETCH( QStringList, expectedToList );
QFETCH( QStringList, expectedBccList );
+ mMailClient->sUnitTestResults.clear();
mPendingSignals = 1;
mMailClient->mailTo( incidence, identity, from, bccMe, recipients, attachment, \
transport ); waitForSignals();
QCOMPARE( mLastResult, expectedResult );
+ UnitTestResult unitTestResult = mMailClient->sUnitTestResults.first();
if ( expectedTransportId != -1 )
- QCOMPARE( mMailClient->mUnitTestResult.transportId, expectedTransportId );
+ QCOMPARE( unitTestResult.transportId, expectedTransportId );
- QCOMPARE( mMailClient->mUnitTestResult.from, expectedFrom );
- QCOMPARE( mMailClient->mUnitTestResult.to, expectedToList );
- QCOMPARE( mMailClient->mUnitTestResult.bcc, expectedBccList );
+ QCOMPARE( unitTestResult.from, expectedFrom );
+ QCOMPARE( unitTestResult.to, expectedToList );
+ QCOMPARE( unitTestResult.bcc, expectedBccList );
}
void handleFinished( Akonadi::MailClient::Result result, const QString \
&errorMessage )
diff --git a/akonadi/calendar/tests/todopurgertest.cpp \
b/akonadi/calendar/tests/todopurgertest.cpp new file mode 100644
index 0000000..c568d32
--- /dev/null
+++ b/akonadi/calendar/tests/todopurgertest.cpp
@@ -0,0 +1,207 @@
+/*
+ Copyright (c) 2013 Sérgio Martins <iamsergio@gmail.com>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include "todopurgertest.h"
+
+#include "../etmcalendar.h"
+#include "../todopurger.h"
+#include <akonadi/itemcreatejob.h>
+#include <akonadi/qtest_akonadi.h>
+#include <akonadi/collectionfetchjob.h>
+#include <akonadi/collectionfetchscope.h>
+#include <akonadi/collectionmodifyjob.h>
+#include <akonadi/itemdeletejob.h>
+#include <akonadi/itemmodifyjob.h>
+#include <KCheckableProxyModel>
+
+#include <QTestEventLoop>
+
+using namespace Akonadi;
+using namespace KCalCore;
+
+Q_DECLARE_METATYPE( QSet<QByteArray> )
+
+void TodoPurgerTest::createTodo(const QString &uid, const QString &parentUid, bool \
completed, bool recurring ) +{
+ Item item;
+ item.setMimeType(Todo::todoMimeType());
+ Todo::Ptr todo = Todo::Ptr(new Todo());
+ todo->setUid(uid);
+
+ const KDateTime today = KDateTime::currentDateTime(KDateTime::UTC);
+ const KDateTime yesterday = today.addDays(-1);
+
+ todo->setDtStart(yesterday);
+ todo->setRelatedTo(parentUid);
+
+ if (recurring)
+ todo->recurrence()->setDaily(1);
+
+ if (recurring && completed) {
+ todo->setCompleted(today);
+ } else {
+ todo->setCompleted(completed);
+ }
+
+ todo->setSummary(QLatin1String("summary"));
+
+
+ item.setPayload<KCalCore::Incidence::Ptr>(todo);
+ ItemCreateJob *job = new ItemCreateJob(item, m_collection, this);
+ m_pendingCreations++;
+ AKVERIFYEXEC(job);
+}
+
+void TodoPurgerTest::fetchCollection()
+{
+ CollectionFetchJob *job = new CollectionFetchJob(Collection::root(),
+ CollectionFetchJob::Recursive,
+ this);
+ // Get list of collections
+ job->fetchScope().setContentMimeTypes(QStringList() << \
QLatin1String("application/x-vnd.akonadi.calendar.todo")); + AKVERIFYEXEC(job);
+
+ // Find our collection
+ Collection::List collections = job->collections();
+ QVERIFY(!collections.isEmpty());
+ m_collection = collections.first();
+
+ QVERIFY(m_collection.isValid());
+}
+
+void TodoPurgerTest::initTestCase()
+{
+ AkonadiTest::checkTestIsIsolated();
+
+ qRegisterMetaType<QSet<QByteArray> >("QSet<QByteArray>");
+ fetchCollection();
+
+ m_pendingCreations = 0;
+ m_pendingDeletions = 0;
+ m_calendar = new ETMCalendar();
+ m_calendar->registerObserver(this);
+ m_todoPurger = new TodoPurger(this);
+
+ connect(m_todoPurger, SIGNAL(todosPurged(bool,int,int)), \
SLOT(onTodosPurged(bool,int,int))); +
+ connect(m_calendar, SIGNAL(collectionsAdded(Akonadi::Collection::List)),
+ &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ // Wait for the collection
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ KCheckableProxyModel *checkable = m_calendar->checkableProxyModel();
+ const QModelIndex firstIndex = checkable->index(0, 0);
+ QVERIFY(firstIndex.isValid());
+ checkable->setData(firstIndex, Qt::Checked, Qt::CheckStateRole);
+}
+
+void TodoPurgerTest::cleanupTestCase()
+{
+ delete m_calendar;
+}
+
+void TodoPurgerTest::testPurge()
+{
+ createTree();
+
+ m_pendingDeletions = 8;
+ m_pendingPurgeSignal = true;
+
+ m_todoPurger->purgeCompletedTodos();
+
+ // Wait for deletions and purged signal
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(m_numDeleted, 10);
+ QCOMPARE(m_numIgnored, 2);
+}
+
+void TodoPurgerTest::calendarIncidenceAdded(const Incidence::Ptr &)
+{
+ --m_pendingCreations;
+ if (m_pendingCreations == 0) {
+ QTestEventLoop::instance().exitLoop();
+ }
+}
+
+void TodoPurgerTest::calendarIncidenceDeleted(const Incidence::Ptr &)
+{
+ --m_pendingDeletions;
+ if (m_pendingDeletions == 0 && !m_pendingPurgeSignal) {
+ QTestEventLoop::instance().exitLoop();
+ }
+}
+
+void TodoPurgerTest::onTodosPurged(bool success, int numDeleted, int numIgnored)
+{
+ QVERIFY(success);
+ m_pendingPurgeSignal = false;
+ m_numDeleted = numDeleted;
+ m_numIgnored = numIgnored;
+
+ if (m_pendingDeletions == 0) {
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ }
+}
+
+void TodoPurgerTest::createTree()
+{
+ createTodo(tr("a"), QString(), true); // Will be deleted
+ createTodo(tr("b"), QString(), false); // Won't be deleted
+
+ // Completed tree
+ createTodo(tr("c"), QString(), true); // Will be deleted
+ createTodo(tr("c1"), tr("c"), true); // Will be deleted
+ createTodo(tr("c1.1"), tr("c1"), true); // Will be deleted
+ createTodo(tr("c1.2"), tr("c1"), true); // Will be deleted
+
+ // Root completed but children not completed
+ createTodo(tr("d"), QString(), true); // Will be ignored (uncomplete \
children) + createTodo(tr("d1"), tr("d"), false); // Won't be deleted
+ createTodo(tr("d1.1"), tr("d1"), false); // Won't be deleted
+ createTodo(tr("d1.2"), tr("d1"), false); // Won't be deleted
+
+ // Root uncomplete with children complete
+ createTodo(tr("e"), QString(), false); // Won't be deleted
+ createTodo(tr("e1"), tr("e"), true); // Will be deleted
+ createTodo(tr("e1.1"), tr("e1"), true); // Will be deleted
+ createTodo(tr("e1.2"), tr("e1"), true); // Will be deleted
+
+ // Recurring uncomplete
+ createTodo(tr("f"), QString(), false, true); // Won't be deleted
+
+ // Recurring complete, this one is not deleted because recurrence didn't end
+ createTodo(tr("g"), QString(), true, true); // Won't be deleted
+
+ createTodo(tr("h"), QString(), true); // Will be ignored (uncomplete \
children) + createTodo(tr("h1"), tr("h"), false); // Won't be deleted
+ createTodo(tr("h1.1"), tr("h1"), true); // Will be deleted
+ createTodo(tr("h1.2"), tr("h1"), true); // Will be deleted
+
+
+ // Now wait for incidences do be created
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+}
+
+QTEST_AKONADIMAIN(TodoPurgerTest, GUI)
diff --git a/akonadi/calendar/tests/todopurgertest.h \
b/akonadi/calendar/tests/todopurgertest.h new file mode 100644
index 0000000..7cb5839
--- /dev/null
+++ b/akonadi/calendar/tests/todopurgertest.h
@@ -0,0 +1,65 @@
+/*
+ Copyright (c) 2013 Sérgio Martins <iamsergio@gmail.com>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#ifndef TODOPURGER_TEST_H_
+#define TODOPURGER_TEST_H_
+
+#include <kcalcore/calendar.h>
+#include <akonadi/collection.h>
+#include <QObject>
+#include <QString>
+
+namespace Akonadi {
+ class ETMCalendar;
+ class TodoPurger;
+}
+
+class TodoPurgerTest : public QObject, KCalCore::Calendar::CalendarObserver
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void initTestCase();
+ void cleanupTestCase();
+ void testPurge();
+
+public:
+ void calendarIncidenceAdded( const KCalCore::Incidence::Ptr &incidence ); \
/**Q_DECL_OVERRIDE*/ + void calendarIncidenceDeleted( const \
KCalCore::Incidence::Ptr &incidence ); /**Q_DECL_OVERRIDE*/ +
+public Q_SLOTS:
+ void onTodosPurged(bool success, int numDeleted, int numIgnored);
+
+private:
+ void createTree();
+ void createTodo(const QString &uid, const QString &parentUid, bool completed, \
bool recurring = false); + void fetchCollection();
+
+ Akonadi::ETMCalendar *m_calendar;
+ Akonadi::Collection m_collection;
+ int m_pendingCreations;
+ int m_pendingDeletions;
+ bool m_pendingPurgeSignal;
+
+ int m_numDeleted;
+ int m_numIgnored;
+
+ Akonadi::TodoPurger *m_todoPurger;
+};
+
+#endif
diff --git a/akonadi/calendar/tests/unittestbase.cpp \
b/akonadi/calendar/tests/unittestbase.cpp new file mode 100644
index 0000000..9e7b868
--- /dev/null
+++ b/akonadi/calendar/tests/unittestbase.cpp
@@ -0,0 +1,198 @@
+/*
+ Copyright (c) 2013 Sérgio Martins <iamsergio@gmail.com>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+
+#include "unittestbase.h"
+#include "helper.h"
+#include "../fetchjobcalendar.h"
+#include "mailclient_p.h"
+
+#include <kcalcore/event.h>
+#include <kcalcore/icalformat.h>
+#include <akonadi/item.h>
+#include <akonadi/itemcreatejob.h>
+#include <akonadi/calendar/incidencechanger.h>
+#include <akonadi/calendar/itiphandler.h>
+
+#include <QString>
+#include <QFile>
+#include <QByteArray>
+#include <QTestEventLoop>
+#include <qtest.h>
+
+using namespace Akonadi;
+using namespace KCalCore;
+
+UnitTestBase::UnitTestBase()
+{
+ qRegisterMetaType<Akonadi::Item>("Akonadi::Item");
+ qRegisterMetaType<QList<Akonadi::IncidenceChanger::ChangeType> \
>("QList<Akonadi::IncidenceChanger::ChangeType>"); + \
> qRegisterMetaType<QVector<Akonadi::Item::Id> >("QVector<Akonadi::Item::Id>");
+ qRegisterMetaType<Akonadi::MailClient::Result>("Akonadi::MailClient::Result");
+
+ mChanger = new IncidenceChanger(this);
+ mChanger->setShowDialogsOnError(false);
+ mChanger->setHistoryEnabled(true);
+
+ mCollection = Helper::fetchCollection();
+ Q_ASSERT(mCollection.isValid());
+ mChanger->setDefaultCollection(mCollection);
+}
+
+void UnitTestBase::waitForIt()
+{
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+}
+
+void UnitTestBase::stopWaiting()
+{
+ QTestEventLoop::instance().exitLoop();
+}
+
+void UnitTestBase::createIncidence(const QString &uid)
+{
+ Item item = generateIncidence(uid);
+ createIncidence(item);
+}
+
+void UnitTestBase::createIncidence(const Item &item)
+{
+ QVERIFY(mCollection.isValid());
+ ItemCreateJob *job = new ItemCreateJob(item, mCollection, this);
+ QVERIFY(job->exec());
+}
+
+void UnitTestBase::verifyExists(const QString &uid, bool exists)
+{
+ FetchJobCalendar *calendar = new FetchJobCalendar();
+ connect(calendar, SIGNAL(loadFinished(bool,QString)), \
SLOT(onLoadFinished(bool,QString))); + waitForIt();
+ calendar->deleteLater();
+
+ QCOMPARE(calendar->incidence(uid) != 0, exists);
+}
+
+Akonadi::Item::List UnitTestBase::calendarItems()
+{
+ FetchJobCalendar::Ptr calendar = FetchJobCalendar::Ptr(new FetchJobCalendar());
+ connect(calendar.data(), SIGNAL(loadFinished(bool,QString)), \
SLOT(onLoadFinished(bool,QString))); + waitForIt();
+ KCalCore::ICalFormat format;
+ QString dump = format.toString(calendar.staticCast<KCalCore::Calendar>());
+ qDebug() << dump;
+ calendar->deleteLater();
+ return calendar->items();
+}
+
+void UnitTestBase::onLoadFinished(bool success, const QString &)
+{
+ QVERIFY(success);
+ stopWaiting();
+}
+
+void UnitTestBase::compareCalendars(const KCalCore::Calendar::Ptr &expectedCalendar)
+{
+ FetchJobCalendar::Ptr calendar = FetchJobCalendar::Ptr(new FetchJobCalendar());
+ connect(calendar.data(), SIGNAL(loadFinished(bool,QString)), \
SLOT(onLoadFinished(bool,QString))); + waitForIt();
+
+
+ // Now compare the expected calendar to the calendar we got.
+ Incidence::List incidences = calendar->incidences();
+ Incidence::List expectedIncidences = expectedCalendar->incidences();
+
+ // First, replace the randomly generated UIDs with the UID that came in the \
invitation e-mail... + foreach (const KCalCore::Incidence::Ptr &incidence, \
incidences) { + incidence->setUid(incidence->schedulingID());
+ qDebug() << "We have incidece with uid=" << incidence->uid()
+ << "; instanceidentifier=" << incidence->instanceIdentifier();
+ foreach (const KCalCore::Attendee::Ptr &attendee, incidence->attendees()) {
+ attendee->setUid(attendee->email());
+ }
+ }
+
+ // ... so we can compare them
+ foreach (const KCalCore::Incidence::Ptr &incidence, expectedIncidences) {
+ incidence->setUid(incidence->schedulingID());
+ qDebug() << "We expect incidece with uid=" << incidence->uid()
+ << "; instanceidentifier=" << incidence->instanceIdentifier();
+ foreach (const KCalCore::Attendee::Ptr &attendee, incidence->attendees()) {
+ attendee->setUid(attendee->email());
+ }
+ }
+
+ QCOMPARE(incidences.count(), expectedIncidences.count());
+
+ foreach (const KCalCore::Incidence::Ptr &expectedIncidence, expectedIncidences) \
{ + KCalCore::Incidence::Ptr incidence;
+ for (int i=0; i<incidences.count(); i++) {
+ if (incidences.at(i)->instanceIdentifier() == \
expectedIncidence->instanceIdentifier()) { + incidence = \
incidences.at(i); + incidences.remove(i);
+ break;
+ }
+ }
+ QVERIFY(incidence);
+ // Don't fail on creation times, which are obviously different
+ expectedIncidence->setCreated(incidence->created());
+
+ if (*expectedIncidence != *incidence) {
+ ICalFormat format;
+ QString expectedData = format.toString(expectedIncidence);
+ QString gotData = format.toString(incidence);
+ qDebug() << "Test failed, expected:\n" << expectedData << "\nbut got " \
<< gotData; + QVERIFY(false);
+ }
+ }
+}
+
+/** static */
+QByteArray UnitTestBase::readFile(const QString &filename)
+{
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ return QByteArray();
+ }
+
+ return file.readAll();
+}
+
+Item UnitTestBase::generateIncidence(const QString &uid, const QString &organizer)
+{
+ Item item;
+ item.setMimeType(KCalCore::Event::eventMimeType());
+ KCalCore::Incidence::Ptr incidence = KCalCore::Incidence::Ptr(new \
KCalCore::Event()); +
+ if (!uid.isEmpty()) {
+ incidence->setUid(uid);
+ }
+
+ const KDateTime now = KDateTime::currentUtcDateTime();
+ incidence->setDtStart(now);
+ incidence->setDateTime(now.addSecs(3600), Incidence::RoleEnd);
+ incidence->setSummary(QLatin1String("summary"));
+ item.setPayload<KCalCore::Incidence::Ptr>(incidence);
+
+ if (!organizer.isEmpty()) {
+ incidence->setOrganizer(organizer);
+ }
+
+ return item;
+}
diff --git a/akonadi/calendar/tests/unittestbase.h \
b/akonadi/calendar/tests/unittestbase.h new file mode 100644
index 0000000..14dec78
--- /dev/null
+++ b/akonadi/calendar/tests/unittestbase.h
@@ -0,0 +1,60 @@
+/*
+ Copyright (c) 2013 Sérgio Martins <iamsergio@gmail.com>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+
+#ifndef UNITTEST_BASE_H
+#define UNITTEST_BASE_H
+
+#include <kcalcore/calendar.h>
+#include <akonadi/collection.h>
+#include <akonadi/item.h>
+
+#include <QObject>
+#include <QString>
+
+namespace Akonadi {
+ class IncidenceChanger;
+}
+
+class UnitTestBase : public QObject {
+ Q_OBJECT
+public:
+ UnitTestBase();
+ void waitForIt(); // Waits 10 seconds for signals
+ void stopWaiting();
+ void createIncidence(const QString &uid);
+ void createIncidence(const Akonadi::Item &item);
+
+ void verifyExists(const QString &uid, bool exists);
+ Akonadi::Item::List calendarItems();
+
+public Q_SLOTS:
+ void onLoadFinished(bool success, const QString &errorMessage);
+
+protected:
+
+ void compareCalendars(const KCalCore::Calendar::Ptr &expectedCalendar);
+ static QByteArray readFile(const QString &filename);
+ static Akonadi::Item generateIncidence(const QString &uid, const QString \
&organizer = QString()); +
+ Akonadi::Collection mCollection;
+ Akonadi::IncidenceChanger *mChanger;
+};
+
+#endif
diff --git a/akonadi/calendar/tests/unittestenv/config-sqlite-db.xml \
b/akonadi/calendar/tests/unittestenv/config-sqlite-db.xml index 6e8388f..1ba6b3f \
100644
--- a/akonadi/calendar/tests/unittestenv/config-sqlite-db.xml
+++ b/akonadi/calendar/tests/unittestenv/config-sqlite-db.xml
@@ -3,8 +3,6 @@
<confighome>xdgconfig-sqlite.db</confighome>
<datahome>xdglocal</datahome>
<agent synchronize="true">akonadi_ical_resource</agent>
- <agent synchronize="true">akonadi_maildir_resource</agent>
- <agent synchronize="true">akonadi_mailtransport_dummy_resource</agent>
<envvar name="AKONADI_DISABLE_AGENT_AUTOSTART">true</envvar>
<envvar name="TESTRUNNER_DB_ENVIRONMENT">sqlite</envvar>
</config>
diff --git a/akonadi/calendar/tests/unittestenv/kdehome/share/config/akonadi_maildir_resource_0rc \
b/akonadi/calendar/tests/unittestenv/kdehome/share/config/akonadi_maildir_resource_0rc
deleted file mode 100644
index 2488d2d..0000000
--- a/akonadi/calendar/tests/unittestenv/kdehome/share/config/akonadi_maildir_resource_0rc
+++ /dev/null
@@ -1,2 +0,0 @@
-[General]
-Path[$e]=$HOME/.local/share/local-mail
diff --git a/akonadi/calendar/tests/unittestenv/kdehome/share/config/akonadi_mailtransport_dummy_resource_0rc \
b/akonadi/calendar/tests/unittestenv/kdehome/share/config/akonadi_mailtransport_dummy_resource_0rc
deleted file mode 100644
index eddc6c7..0000000
--- a/akonadi/calendar/tests/unittestenv/kdehome/share/config/akonadi_mailtransport_dummy_resource_0rc
+++ /dev/null
@@ -1,2 +0,0 @@
-[General]
-Sink=4
diff --git a/akonadi/calendar/tests/unittestenv/kdehome/share/config/kdebugrc \
b/akonadi/calendar/tests/unittestenv/kdehome/share/config/kdebugrc new file mode \
100644 index 0000000..848ed66
--- /dev/null
+++ b/akonadi/calendar/tests/unittestenv/kdehome/share/config/kdebugrc
@@ -0,0 +1,1672 @@
+DisableAll=false
+
+[1000]
+InfoOutput=2
+
+[10000]
+InfoOutput=2
+
+[100000]
+InfoOutput=2
+
+[100001]
+InfoOutput=2
+
+[100100]
+InfoOutput=2
+
+[100101]
+InfoOutput=2
+
+[100200]
+InfoOutput=2
+
+[10500]
+InfoOutput=2
+
+[1100]
+InfoOutput=2
+
+[11000]
+InfoOutput=2
+
+[11002]
+InfoOutput=2
+
+[11003]
+InfoOutput=2
+
+[11004]
+InfoOutput=2
+
+[11005]
+InfoOutput=2
+
+[12000]
+InfoOutput=2
+
+[12001]
+InfoOutput=2
+
+[12002]
+InfoOutput=2
+
+[12003]
+InfoOutput=2
+
+[12004]
+InfoOutput=2
+
+[12005]
+InfoOutput=2
+
+[12006]
+InfoOutput=2
+
+[12007]
+InfoOutput=2
+
+[12008]
+InfoOutput=2
+
+[12009]
+InfoOutput=2
+
+[1201]
+InfoOutput=2
+
+[12010]
+InfoOutput=2
+
+[12011]
+InfoOutput=2
+
+[12012]
+InfoOutput=2
+
+[1203]
+InfoOutput=2
+
+[1204]
+InfoOutput=2
+
+[1205]
+InfoOutput=2
+
+[1206]
+InfoOutput=2
+
+[1207]
+InfoOutput=2
+
+[1208]
+InfoOutput=2
+
+[1209]
+InfoOutput=2
+
+[1211]
+InfoOutput=2
+
+[1212]
+InfoOutput=2
+
+[1215]
+InfoOutput=2
+
+[1216]
+InfoOutput=2
+
+[1218]
+InfoOutput=2
+
+[1220]
+InfoOutput=2
+
+[1221]
+InfoOutput=2
+
+[1222]
+InfoOutput=2
+
+[13000]
+InfoOutput=2
+
+[13001]
+InfoOutput=2
+
+[13002]
+InfoOutput=2
+
+[13010]
+InfoOutput=2
+
+[13020]
+InfoOutput=2
+
+[13025]
+InfoOutput=2
+
+[13030]
+InfoOutput=2
+
+[13033]
+InfoOutput=2
+
+[13035]
+InfoOutput=2
+
+[13040]
+InfoOutput=2
+
+[13050]
+InfoOutput=2
+
+[13051]
+InfoOutput=2
+
+[13060]
+InfoOutput=2
+
+[13070]
+InfoOutput=2
+
+[1400]
+InfoOutput=2
+
+[14000]
+InfoOutput=2
+
+[14001]
+InfoOutput=2
+
+[1401]
+InfoOutput=2
+
+[14010]
+InfoOutput=2
+
+[1402]
+InfoOutput=2
+
+[1410]
+InfoOutput=2
+
+[14100]
+InfoOutput=2
+
+[14101]
+InfoOutput=2
+
+[14110]
+InfoOutput=2
+
+[14111]
+InfoOutput=2
+
+[14120]
+InfoOutput=2
+
+[14121]
+InfoOutput=2
+
+[14130]
+InfoOutput=2
+
+[14131]
+InfoOutput=2
+
+[14140]
+InfoOutput=2
+
+[14141]
+InfoOutput=2
+
+[14150]
+InfoOutput=2
+
+[14151]
+InfoOutput=2
+
+[14152]
+InfoOutput=2
+
+[14153]
+InfoOutput=2
+
+[14160]
+InfoOutput=2
+
+[14161]
+InfoOutput=2
+
+[14170]
+InfoOutput=2
+
+[14171]
+InfoOutput=2
+
+[14180]
+InfoOutput=2
+
+[14181]
+InfoOutput=2
+
+[14190]
+InfoOutput=2
+
+[14191]
+InfoOutput=2
+
+[14192]
+InfoOutput=2
+
+[1420]
+InfoOutput=2
+
+[14200]
+InfoOutput=2
+
+[1421]
+InfoOutput=2
+
+[14210]
+InfoOutput=2
+
+[14220]
+InfoOutput=2
+
+[1430]
+InfoOutput=2
+
+[14300]
+InfoOutput=2
+
+[14301]
+InfoOutput=2
+
+[14302]
+InfoOutput=2
+
+[14303]
+InfoOutput=2
+
+[14304]
+InfoOutput=2
+
+[14305]
+InfoOutput=2
+
+[14306]
+InfoOutput=2
+
+[14307]
+InfoOutput=2
+
+[14308]
+InfoOutput=2
+
+[14309]
+InfoOutput=2
+
+[1431]
+InfoOutput=2
+
+[14310]
+InfoOutput=2
+
+[14311]
+InfoOutput=2
+
+[14312]
+InfoOutput=2
+
+[14313]
+InfoOutput=2
+
+[14314]
+InfoOutput=2
+
+[14315]
+InfoOutput=2
+
+[14316]
+InfoOutput=2
+
+[14317]
+InfoOutput=2
+
+[14318]
+InfoOutput=2
+
+[1432]
+InfoOutput=2
+
+[1433]
+InfoOutput=2
+
+[1440]
+InfoOutput=2
+
+[14400]
+InfoOutput=2
+
+[1441]
+InfoOutput=2
+
+[15000]
+InfoOutput=2
+
+[1511]
+InfoOutput=2
+
+[1512]
+InfoOutput=2
+
+[1601]
+InfoOutput=2
+
+[161]
+InfoOutput=2
+
+[170]
+InfoOutput=2
+
+[174]
+InfoOutput=2
+
+[175]
+InfoOutput=2
+
+[176]
+InfoOutput=2
+
+[179]
+InfoOutput=2
+
+[180]
+InfoOutput=2
+
+[1800]
+InfoOutput=2
+
+[1801]
+InfoOutput=2
+
+[1802]
+InfoOutput=2
+
+[1803]
+InfoOutput=2
+
+[1804]
+InfoOutput=2
+
+[1805]
+InfoOutput=2
+
+[1806]
+InfoOutput=2
+
+[1901]
+InfoOutput=2
+
+[1902]
+InfoOutput=2
+
+[1903]
+InfoOutput=2
+
+[2000]
+InfoOutput=2
+
+[20000]
+InfoOutput=2
+
+[200000]
+InfoOutput=2
+
+[200001]
+InfoOutput=2
+
+[200002]
+InfoOutput=2
+
+[200003]
+InfoOutput=2
+
+[200004]
+InfoOutput=2
+
+[20001]
+InfoOutput=2
+
+[2001]
+InfoOutput=2
+
+[20010]
+InfoOutput=2
+
+[20011]
+InfoOutput=2
+
+[20012]
+InfoOutput=2
+
+[2002]
+InfoOutput=2
+
+[2003]
+InfoOutput=2
+
+[2100]
+InfoOutput=2
+
+[2200]
+InfoOutput=2
+
+[23000]
+InfoOutput=2
+
+[23100]
+InfoOutput=2
+
+[240]
+InfoOutput=2
+
+[2400]
+InfoOutput=2
+
+[24000]
+InfoOutput=2
+
+[24001]
+InfoOutput=2
+
+[24002]
+InfoOutput=2
+
+[2401]
+InfoOutput=2
+
+[2402]
+InfoOutput=2
+
+[2403]
+InfoOutput=2
+
+[2404]
+InfoOutput=2
+
+[2405]
+InfoOutput=2
+
+[260]
+InfoOutput=2
+
+[265]
+InfoOutput=2
+
+[26500]
+InfoOutput=2
+
+[26550]
+InfoOutput=2
+
+[26560]
+InfoOutput=2
+
+[26600]
+InfoOutput=2
+
+[26650]
+InfoOutput=2
+
+[28000]
+InfoOutput=2
+
+[281]
+InfoOutput=2
+
+[282]
+InfoOutput=2
+
+[283]
+InfoOutput=2
+
+[285]
+InfoOutput=2
+
+[29000]
+InfoOutput=2
+
+[291]
+InfoOutput=2
+
+[292]
+InfoOutput=2
+
+[293]
+InfoOutput=2
+
+[297]
+InfoOutput=2
+
+[299]
+InfoOutput=2
+
+[3000]
+InfoOutput=2
+
+[300000]
+InfoOutput=2
+
+[300001]
+InfoOutput=2
+
+[300100]
+InfoOutput=2
+
+[300101]
+InfoOutput=2
+
+[300102]
+InfoOutput=2
+
+[300103]
+InfoOutput=2
+
+[300104]
+InfoOutput=2
+
+[300105]
+InfoOutput=2
+
+[300106]
+InfoOutput=2
+
+[300200]
+InfoOutput=2
+
+[30501]
+InfoOutput=2
+
+[30502]
+InfoOutput=2
+
+[30503]
+InfoOutput=2
+
+[30504]
+InfoOutput=2
+
+[30505]
+InfoOutput=2
+
+[30506]
+InfoOutput=2
+
+[30507]
+InfoOutput=2
+
+[30508]
+InfoOutput=2
+
+[30509]
+InfoOutput=2
+
+[30510]
+InfoOutput=2
+
+[30511]
+InfoOutput=2
+
+[30512]
+InfoOutput=2
+
+[30513]
+InfoOutput=2
+
+[30514]
+InfoOutput=2
+
+[30515]
+InfoOutput=2
+
+[30516]
+InfoOutput=2
+
+[30517]
+InfoOutput=2
+
+[30518]
+InfoOutput=2
+
+[30519]
+InfoOutput=2
+
+[30520]
+InfoOutput=2
+
+[30521]
+InfoOutput=2
+
+[30522]
+InfoOutput=2
+
+[30523]
+InfoOutput=2
+
+[30525]
+InfoOutput=2
+
+[3100]
+InfoOutput=2
+
+[32500]
+InfoOutput=2
+
+[32600]
+InfoOutput=2
+
+[34001]
+InfoOutput=2
+
+[35000]
+InfoOutput=2
+
+[38000]
+InfoOutput=2
+
+[399]
+InfoOutput=2
+
+[410]
+InfoOutput=2
+
+[4300]
+InfoOutput=2
+
+[4400]
+InfoOutput=2
+
+[44000]
+InfoOutput=2
+
+[44001]
+InfoOutput=2
+
+[44010]
+InfoOutput=2
+
+[44019]
+InfoOutput=2
+
+[44020]
+InfoOutput=2
+
+[44021]
+InfoOutput=2
+
+[44022]
+InfoOutput=2
+
+[44023]
+InfoOutput=2
+
+[44024]
+InfoOutput=2
+
+[4500]
+InfoOutput=2
+
+[4600]
+InfoOutput=2
+
+[4610]
+InfoOutput=2
+
+[4620]
+InfoOutput=2
+
+[4630]
+InfoOutput=2
+
+[4640]
+InfoOutput=2
+
+[4700]
+InfoOutput=2
+
+[4710]
+InfoOutput=2
+
+[4711]
+InfoOutput=2
+
+[4712]
+InfoOutput=2
+
+[4713]
+InfoOutput=2
+
+[4714]
+InfoOutput=2
+
+[4715]
+InfoOutput=2
+
+[500]
+InfoOutput=2
+
+[50001]
+InfoOutput=2
+
+[50003]
+InfoOutput=2
+
+[50004]
+InfoOutput=2
+
+[50005]
+InfoOutput=2
+
+[50006]
+InfoOutput=2
+
+[50007]
+InfoOutput=2
+
+[5001]
+InfoOutput=2
+
+[5002]
+InfoOutput=2
+
+[5003]
+InfoOutput=2
+
+[5005]
+InfoOutput=2
+
+[5007]
+InfoOutput=2
+
+[5009]
+InfoOutput=2
+
+[5010]
+InfoOutput=2
+
+[5011]
+InfoOutput=2
+
+[5012]
+InfoOutput=2
+
+[5050]
+InfoOutput=2
+
+[5051]
+InfoOutput=2
+
+[5052]
+InfoOutput=2
+
+[5100]
+InfoOutput=2
+
+[51000]
+InfoOutput=2
+
+[51001]
+InfoOutput=2
+
+[51002]
+InfoOutput=2
+
+[51003]
+InfoOutput=2
+
+[51004]
+InfoOutput=2
+
+[51005]
+InfoOutput=2
+
+[51006]
+InfoOutput=2
+
+[51007]
+InfoOutput=2
+
+[51010]
+InfoOutput=2
+
+[51011]
+InfoOutput=2
+
+[51012]
+InfoOutput=2
+
+[51013]
+InfoOutput=2
+
+[51014]
+InfoOutput=2
+
+[51020]
+InfoOutput=2
+
+[5149]
+InfoOutput=2
+
+[5150]
+InfoOutput=2
+
+[5151]
+InfoOutput=2
+
+[5152]
+InfoOutput=2
+
+[5153]
+InfoOutput=2
+
+[5154]
+InfoOutput=2
+
+[5200]
+InfoOutput=2
+
+[5250]
+InfoOutput=2
+
+[5251]
+InfoOutput=2
+
+[5252]
+InfoOutput=2
+
+[5253]
+InfoOutput=2
+
+[5254]
+InfoOutput=2
+
+[5255]
+InfoOutput=2
+
+[5256]
+InfoOutput=2
+
+[5257]
+InfoOutput=2
+
+[5258]
+InfoOutput=2
+
+[5259]
+InfoOutput=2
+
+[5260]
+InfoOutput=2
+
+[5261]
+InfoOutput=2
+
+[5262]
+InfoOutput=2
+
+[5263]
+InfoOutput=2
+
+[5264]
+InfoOutput=2
+
+[5265]
+InfoOutput=2
+
+[5266]
+InfoOutput=2
+
+[5295]
+InfoOutput=2
+
+[5300]
+InfoOutput=2
+
+[5310]
+InfoOutput=2
+
+[5320]
+InfoOutput=2
+
+[5321]
+InfoOutput=2
+
+[5322]
+InfoOutput=2
+
+[5323]
+InfoOutput=2
+
+[5324]
+InfoOutput=2
+
+[5325]
+InfoOutput=2
+
+[5326]
+InfoOutput=2
+
+[5327]
+InfoOutput=2
+
+[5328]
+InfoOutput=2
+
+[5329]
+InfoOutput=2
+
+[5350]
+InfoOutput=2
+
+[550]
+InfoOutput=2
+
+[5500]
+InfoOutput=2
+
+[551]
+InfoOutput=2
+
+[5510]
+InfoOutput=2
+
+[5511]
+InfoOutput=2
+
+[5512]
+InfoOutput=2
+
+[5600]
+InfoOutput=2
+
+[5601]
+InfoOutput=2
+
+[5602]
+InfoOutput=2
+
+[5650]
+InfoOutput=2
+
+[5700]
+InfoOutput=2
+
+[5720]
+InfoOutput=2
+
+[5800]
+InfoOutput=2
+
+[5810]
+InfoOutput=2
+
+[5820]
+InfoOutput=2
+
+[5850]
+InfoOutput=2
+
+[5860]
+InfoOutput=2
+
+[5890]
+InfoOutput=2
+
+[5900]
+InfoOutput=2
+
+[5950]
+InfoOutput=2
+
+[5951]
+InfoOutput=2
+
+[5952]
+InfoOutput=2
+
+[5953]
+InfoOutput=2
+
+[5954]
+InfoOutput=2
+
+[5955]
+InfoOutput=2
+
+[5960]
+InfoOutput=2
+
+[5970]
+InfoOutput=2
+
+[5975]
+InfoOutput=2
+
+[600]
+InfoOutput=2
+
+[6000]
+InfoOutput=2
+
+[60001]
+InfoOutput=2
+
+[60002]
+InfoOutput=2
+
+[60005]
+InfoOutput=2
+
+[60010]
+InfoOutput=2
+
+[6005]
+InfoOutput=2
+
+[601]
+InfoOutput=2
+
+[6010]
+InfoOutput=2
+
+[6011]
+InfoOutput=2
+
+[6020]
+InfoOutput=2
+
+[6030]
+InfoOutput=2
+
+[6031]
+InfoOutput=2
+
+[6035]
+InfoOutput=2
+
+[6036]
+InfoOutput=2
+
+[6040]
+InfoOutput=2
+
+[6041]
+InfoOutput=2
+
+[6045]
+InfoOutput=2
+
+[6050]
+InfoOutput=2
+
+[6060]
+InfoOutput=2
+
+[6061]
+InfoOutput=2
+
+[6070]
+InfoOutput=2
+
+[6080]
+InfoOutput=2
+
+[6090]
+InfoOutput=2
+
+[6100]
+InfoOutput=2
+
+[6200]
+InfoOutput=2
+
+[6201]
+InfoOutput=2
+
+[6210]
+InfoOutput=2
+
+[65432]
+InfoOutput=2
+
+[66666]
+InfoOutput=2
+
+[67000]
+InfoOutput=2
+
+[67100]
+InfoOutput=2
+
+[67200]
+InfoOutput=2
+
+[700]
+InfoOutput=2
+
+[7000]
+InfoOutput=2
+
+[7002]
+InfoOutput=2
+
+[7003]
+InfoOutput=2
+
+[7004]
+InfoOutput=2
+
+[7005]
+InfoOutput=2
+
+[7006]
+InfoOutput=2
+
+[7007]
+InfoOutput=2
+
+[7008]
+InfoOutput=2
+
+[701]
+InfoOutput=2
+
+[7011]
+InfoOutput=2
+
+[7014]
+InfoOutput=2
+
+[7015]
+InfoOutput=2
+
+[7016]
+InfoOutput=2
+
+[7017]
+InfoOutput=2
+
+[7019]
+InfoOutput=2
+
+[702]
+InfoOutput=2
+
+[7020]
+InfoOutput=2
+
+[7021]
+InfoOutput=2
+
+[7022]
+InfoOutput=2
+
+[7023]
+InfoOutput=2
+
+[7024]
+InfoOutput=2
+
+[7025]
+InfoOutput=2
+
+[7027]
+InfoOutput=2
+
+[7028]
+InfoOutput=2
+
+[7029]
+InfoOutput=2
+
+[7030]
+InfoOutput=2
+
+[7031]
+InfoOutput=2
+
+[7032]
+InfoOutput=2
+
+[7033]
+InfoOutput=2
+
+[7034]
+InfoOutput=2
+
+[704]
+InfoOutput=2
+
+[7040]
+InfoOutput=2
+
+[7041]
+InfoOutput=2
+
+[7042]
+InfoOutput=2
+
+[7043]
+InfoOutput=2
+
+[7044]
+InfoOutput=2
+
+[710]
+InfoOutput=2
+
+[7101]
+InfoOutput=2
+
+[7102]
+InfoOutput=2
+
+[7103]
+InfoOutput=2
+
+[7104]
+InfoOutput=2
+
+[7105]
+InfoOutput=2
+
+[7106]
+InfoOutput=2
+
+[7107]
+InfoOutput=2
+
+[7108]
+InfoOutput=2
+
+[7109]
+InfoOutput=2
+
+[711]
+InfoOutput=2
+
+[7110]
+InfoOutput=2
+
+[7111]
+InfoOutput=2
+
+[7112]
+InfoOutput=2
+
+[7115]
+InfoOutput=2
+
+[7116]
+InfoOutput=2
+
+[7117]
+InfoOutput=2
+
+[7119]
+InfoOutput=2
+
+[712]
+InfoOutput=2
+
+[7120]
+InfoOutput=2
+
+[7121]
+InfoOutput=2
+
+[7122]
+InfoOutput=2
+
+[7123]
+InfoOutput=2
+
+[7124]
+InfoOutput=2
+
+[7125]
+InfoOutput=2
+
+[7126]
+InfoOutput=2
+
+[7127]
+InfoOutput=2
+
+[7128]
+InfoOutput=2
+
+[7129]
+InfoOutput=2
+
+[713]
+InfoOutput=2
+
+[7131]
+InfoOutput=2
+
+[800]
+InfoOutput=2
+
+[80001]
+InfoOutput=2
+
+[8050]
+InfoOutput=2
+
+[8051]
+InfoOutput=2
+
+[8060]
+InfoOutput=2
+
+[8100]
+InfoOutput=2
+
+[8101]
+InfoOutput=2
+
+[8102]
+InfoOutput=2
+
+[8103]
+InfoOutput=2
+
+[8104]
+InfoOutput=2
+
+[8105]
+InfoOutput=2
+
+[8106]
+InfoOutput=2
+
+[8110]
+InfoOutput=2
+
+[8111]
+InfoOutput=2
+
+[8112]
+InfoOutput=2
+
+[8113]
+InfoOutput=2
+
+[9000]
+InfoOutput=2
+
+[90000]
+InfoOutput=2
+
+[9001]
+InfoOutput=2
+
+[90010]
+InfoOutput=2
+
+[9002]
+InfoOutput=2
+
+[90020]
+InfoOutput=2
+
+[9003]
+InfoOutput=2
+
+[9004]
+InfoOutput=2
+
+[9007]
+InfoOutput=2
+
+[9010]
+InfoOutput=2
+
+[90100]
+InfoOutput=2
+
+[9011]
+InfoOutput=2
+
+[90110]
+InfoOutput=2
+
+[9012]
+InfoOutput=2
+
+[90120]
+InfoOutput=2
+
+[9013]
+InfoOutput=2
+
+[90130]
+InfoOutput=2
+
+[90150]
+InfoOutput=2
+
+[90160]
+InfoOutput=2
+
+[9017]
+InfoOutput=2
+
+[90170]
+InfoOutput=2
+
+[90180]
+InfoOutput=2
+
+[90190]
+InfoOutput=2
+
+[90210]
+InfoOutput=2
+
+[9024]
+InfoOutput=2
+
+[9025]
+InfoOutput=2
+
+[9032]
+InfoOutput=2
+
+[9035]
+InfoOutput=2
+
+[9037]
+InfoOutput=2
+
+[9038]
+InfoOutput=2
+
+[9039]
+InfoOutput=2
+
+[9040]
+InfoOutput=2
+
+[9041]
+InfoOutput=2
+
+[9042]
+InfoOutput=2
+
+[9043]
+InfoOutput=2
+
+[9044]
+InfoOutput=2
+
+[9045]
+InfoOutput=2
+
+[9046]
+InfoOutput=2
+
+[912]
+InfoOutput=2
+
+[920]
+InfoOutput=2
+
+[921]
+InfoOutput=2
+
+[930]
+InfoOutput=2
+
+[9500]
+InfoOutput=2
+
+[9501]
+InfoOutput=2
+
+[9502]
+InfoOutput=2
+
+[9503]
+InfoOutput=2
+
+[9504]
+InfoOutput=2
+
+[9505]
+InfoOutput=2
+
+[9506]
+InfoOutput=2
+
+[9507]
+InfoOutput=2
+
+[9508]
+InfoOutput=2
+
+[9509]
+InfoOutput=2
+
+[9510]
+InfoOutput=2
+
+[9511]
+InfoOutput=2
+
+[9512]
+InfoOutput=2
+
+[9513]
+InfoOutput=2
+
+[9514]
+InfoOutput=2
+
+[9515]
+InfoOutput=2
+
+[9516]
+InfoOutput=2
+
+[9517]
+InfoOutput=2
+
+[9518]
+InfoOutput=2
+
+[9519]
+InfoOutput=2
+
+[9520]
+InfoOutput=2
+
+[9521]
+InfoOutput=2
+
+[9522]
+InfoOutput=2
+
+[9523]
+InfoOutput=2
+
+[9524]
+InfoOutput=2
+
+[9525]
+InfoOutput=2
+
+[9526]
+InfoOutput=2
+
+[9527]
+InfoOutput=2
+
+[9528]
+InfoOutput=2
+
+[9529]
+InfoOutput=2
+
+[9530]
+InfoOutput=2
+
+[9531]
+InfoOutput=2
+
+[9532]
+InfoOutput=2
+
+[AkonadiAgentServer]
+InfoOutput=2
+
+[KSharedDataCache]
+InfoOutput=4
+
+[Oxygen ( style )]
+InfoOutput=2
+
+[akonadi_archivemail_agent]
+InfoOutput=2
+
+[akonadi_folderarchive_agent]
+InfoOutput=2
+
+[akonadi_maildispatcher_agent]
+InfoOutput=2
+
+[akonadi_mailfilter_agent]
+InfoOutput=2
+
+[akonadi_migration_agent]
+InfoOutput=2
+
+[akonadi_nepomuk_feeder]
+InfoOutput=2
+
+[akonadiconsole]
+InfoOutput=2
+
+[kbuildsycoca4]
+InfoOutput=2
+
+[kdecore (KConfigSkeleton)]
+InfoOutput=2
+
+[unnamed app]
+InfoOutput=2
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic