diff --git a/src/akonadi/akonadiserializer.h b/src/akonadi/akonadiserializer.h --- a/src/akonadi/akonadiserializer.h +++ b/src/akonadi/akonadiserializer.h @@ -25,6 +25,7 @@ #ifndef AKONADI_SERIALIZER_H #define AKONADI_SERIALIZER_H +#include #include "akonadiserializerinterface.h" namespace Akonadi { @@ -90,6 +91,8 @@ bool hasContextTags(Akonadi::Item item) const Q_DECL_OVERRIDE; bool hasAkonadiTags(Akonadi::Item item) const Q_DECL_OVERRIDE; + void setItemRecurrence(KCalCore::Todo::Ptr item, const Domain::Task::Recurrence recurrence) const; + Domain::Task::Recurrence taskRecurrenceFromItem(KCalCore::Todo::Ptr item) const; private: bool isContext(const Akonadi::Tag &tag) const; bool isAkonadiTag(const Akonadi::Tag &tag) const; diff --git a/src/akonadi/akonadiserializer.cpp b/src/akonadi/akonadiserializer.cpp --- a/src/akonadi/akonadiserializer.cpp +++ b/src/akonadi/akonadiserializer.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -216,8 +215,9 @@ task->setText(todo->description()); task->setDone(todo->isCompleted()); task->setDoneDate(todo->completed().dateTime().toUTC()); - task->setStartDate(todo->dtStart().dateTime().toUTC()); + task->setStartDate(todo->dtStart().dateTime().toUTC(), taskRecurrenceFromItem(todo)); task->setDueDate(todo->dtDue().dateTime().toUTC()); + task->setProperty("itemId", item.id()); task->setProperty("parentCollectionId", item.parentCollection().id()); task->setProperty("todoUid", todo->uid()); @@ -263,6 +263,8 @@ todo->setDtStart(KDateTime(task->startDate(), KDateTime::UTC)); todo->setDtDue(KDateTime(task->dueDate(), KDateTime::UTC)); + setItemRecurrence(todo, task->recurrence()); + if (task->property("todoUid").isValid()) { todo->setUid(task->property("todoUid").toString()); } @@ -572,6 +574,51 @@ std::bind(Utils::mem_fn(&Serializer::isAkonadiTag), this, _1)); } +void Serializer::setItemRecurrence(KCalCore::Todo::Ptr item, const Domain::Task::Recurrence recurrence) const +{ + switch (recurrence) + { + case Domain::Task::NoRecurrence: + item->recurrence()->clear(); + break; + case Domain::Task::Daily: + item->recurrence()->setDaily(1); + break; + case Domain::Task::Weekly: + item->recurrence()->setWeekly(1); + break; + case Domain::Task::MonthlyDay: + item->recurrence()->setMonthly(1); + break; + case Domain::Task::MonthlyPos: + qWarning("Serializer is not yet supporting monthly position recurrence"); + default: + qWarning("Serializer is not supporting this recurrence type, using None"); + item->recurrence()->clear(); + } +} + +Domain::Task::Recurrence Serializer::taskRecurrenceFromItem(KCalCore::Todo::Ptr item) const +{ + switch (item->recurrenceType()) + { + case KCalCore::Recurrence::rNone: + return Domain::Task::NoRecurrence; + case KCalCore::Recurrence::rDaily: + return Domain::Task::Daily; + case KCalCore::Recurrence::rWeekly: + return Domain::Task::Weekly; + case KCalCore::Recurrence::rMonthlyDay: + return Domain::Task::MonthlyDay; + case KCalCore::Recurrence::rMonthlyPos: + qWarning("Serializer is not yet supporting montly position recurrence"); + return Domain::Task::NoRecurrence; + default: + qWarning("Serializer is not supporting this recurrence type, using None"); + return Domain::Task::NoRecurrence; + } +} + bool Serializer::isContext(const Akonadi::Tag &tag) const { return (tag.type() == Akonadi::SerializerInterface::contextTagType()); diff --git a/tests/units/akonadi/akonadiserializertest.cpp b/tests/units/akonadi/akonadiserializertest.cpp --- a/tests/units/akonadi/akonadiserializertest.cpp +++ b/tests/units/akonadi/akonadiserializertest.cpp @@ -36,7 +36,10 @@ #include #include +#include "utils/datetime.h" + Q_DECLARE_METATYPE(Akonadi::Item*) +Q_DECLARE_METATYPE(int) class AkonadiSerializerTest : public QObject { @@ -560,26 +563,29 @@ QTest::addColumn("doneDate"); QTest::addColumn("startDate"); QTest::addColumn("dueDate"); + QTest::addColumn("recurrence"); QTest::addColumn("delegateName"); QTest::addColumn("delegateEmail"); - QTest::newRow("nominal case") << "summary" << "content" << false << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << "John Doe" << "j@d.com"; - QTest::newRow("done case") << "summary" << "content" << true << QDateTime(QDate(2013, 11, 30)) << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << "John Doe" << "j@d.com"; - QTest::newRow("done without doneDate case") << "summary" << "content" << true << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << "John Doe" << "j@d.com"; - QTest::newRow("empty case") << QString() << QString() << false << QDateTime() << QDateTime() << QDateTime() << QString() << QString(); + QTest::newRow("nominal case") << "summary" << "content" << false << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << Domain::Task::NoRecurrence << "John Doe" << "j@d.com"; + QTest::newRow("done case") << "summary" << "content" << true << QDateTime(QDate(2013, 11, 30)) << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << Domain::Task::NoRecurrence << "John Doe" << "j@d.com"; + QTest::newRow("done without doneDate case") << "summary" << "content" << true << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << Domain::Task::NoRecurrence << "John Doe" << "j@d.com"; + QTest::newRow("empty case") << QString() << QString() << false << QDateTime() << QDateTime() << QDateTime() << Domain::Task::NoRecurrence << QString() << QString(); } void shouldCreateTaskFromItem() { // GIVEN + Akonadi::Serializer serializer; // Data... QFETCH(QString, summary); QFETCH(QString, content); QFETCH(bool, isDone); QFETCH(QDateTime, doneDate); QFETCH(QDateTime, startDate); QFETCH(QDateTime, dueDate); + QFETCH(Domain::Task::Recurrence, recurrence); QFETCH(QString, delegateName); QFETCH(QString, delegateEmail); @@ -600,6 +606,8 @@ todo->setDtStart(KDateTime(startDate, KDateTime::UTC)); todo->setDtDue(KDateTime(dueDate, KDateTime::UTC)); + serializer.setItemRecurrence(todo, recurrence); + todo->setRelatedTo(QStringLiteral("my-uid")); if (!delegateName.isEmpty() || !delegateEmail.isEmpty()) { KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee(delegateName, @@ -620,7 +628,6 @@ item.setParentCollection(collection); // WHEN - Akonadi::Serializer serializer; Domain::Task::Ptr task = serializer.createTaskFromItem(item); auto artifact = serializer.createArtifactFromItem(item).dynamicCast(); @@ -631,6 +638,7 @@ QCOMPARE(task->doneDate(), doneDate); QCOMPARE(task->startDate(), startDate); QCOMPARE(task->dueDate(), dueDate); + QCOMPARE(task->recurrence(), recurrence); QCOMPARE(task->property("todoUid").toString(), todo->uid()); QCOMPARE(task->property("relatedUid").toString(), todo->relatedTo()); QCOMPARE(task->property("itemId").toLongLong(), item.id()); @@ -700,27 +708,31 @@ QTest::addColumn("updatedDoneDate"); QTest::addColumn("updatedStartDate"); QTest::addColumn("updatedDueDate"); + QTest::addColumn("updatedRecurrence"); QTest::addColumn("updatedRelated"); QTest::addColumn("updatedDelegateName"); QTest::addColumn("updatedDelegateEmail"); QTest::addColumn("updatedRunning"); - QTest::newRow("no change") << "summary" << "content" << false << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << "my-uid" << "John Doe" << "j@d.com" << false; - QTest::newRow("changed") << "new summary" << "new content" << true << QDateTime(QDate(2013, 11, 28)) << QDateTime(QDate(2013, 11, 25)) << QDateTime(QDate(2014, 03, 02)) << "my-new-uid" << "John Smith" << "j@s.com" << false; - QTest::newRow("set_to_running") << "summary" << "content" << false << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << "my-uid" << "John Doe" << "j@d.com" << true; + QTest::newRow("no change") << "summary" << "content" << false << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << Domain::Task::NoRecurrence << "my-uid" << "John Doe" << "j@d.com" << false; + QTest::newRow("changed") << "new summary" << "new content" << true << QDateTime(QDate(2013, 11, 28)) << QDateTime(QDate(2013, 11, 25)) << QDateTime(QDate(2014, 03, 02)) << Domain::Task::Daily << "my-new-uid" << "John Smith" << "j@s.com" << false; + QTest::newRow("set_to_running") << "summary" << "content" << false << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << Domain::Task::NoRecurrence << "my-uid" << "John Doe" << "j@d.com" << true; } void shouldUpdateTaskFromItem() { // GIVEN + Akonadi::Serializer serializer; + // A todo... KCalCore::Todo::Ptr originalTodo(new KCalCore::Todo); originalTodo->setSummary(QStringLiteral("summary")); originalTodo->setDescription(QStringLiteral("content")); originalTodo->setCompleted(false); originalTodo->setDtStart(KDateTime(QDate(2013, 11, 24), KDateTime::UTC)); originalTodo->setDtDue(KDateTime(QDate(2014, 03, 01), KDateTime::UTC)); + serializer.setItemRecurrence(originalTodo, Domain::Task::NoRecurrence); originalTodo->setRelatedTo(QStringLiteral("my-uid")); KCalCore::Attendee::Ptr originalAttendee(new KCalCore::Attendee(QStringLiteral("John Doe"), QStringLiteral("j@d.com"), @@ -738,7 +750,6 @@ originalItem.setParentCollection(originalCollection); // ... deserialized as a task - Akonadi::Serializer serializer; auto task = serializer.createTaskFromItem(originalItem); auto artifact = serializer.createArtifactFromItem(originalItem); @@ -751,6 +762,7 @@ QFETCH(QDateTime, updatedDoneDate); QFETCH(QDateTime, updatedStartDate); QFETCH(QDateTime, updatedDueDate); + QFETCH(Domain::Task::Recurrence, updatedRecurrence); QFETCH(QString, updatedRelated); QFETCH(QString, updatedDelegateName); QFETCH(QString, updatedDelegateEmail); @@ -773,6 +785,7 @@ updatedTodo->setDtStart(KDateTime(updatedStartDate, KDateTime::UTC)); updatedTodo->setDtDue(KDateTime(updatedDueDate, KDateTime::UTC)); + serializer.setItemRecurrence(updatedTodo, updatedRecurrence); updatedTodo->setRelatedTo(updatedRelated); if (!updatedDelegateName.isEmpty() || !updatedDelegateEmail.isEmpty()) { KCalCore::Attendee::Ptr updatedAttendee(new KCalCore::Attendee(updatedDelegateName, @@ -806,6 +819,7 @@ QCOMPARE(task->doneDate(), updatedDoneDate.toUTC()); QCOMPARE(task->startDate(), updatedStartDate.toUTC()); QCOMPARE(task->dueDate(), updatedDueDate.toUTC()); + QCOMPARE(task->recurrence(), updatedRecurrence); QCOMPARE(task->property("todoUid").toString(), updatedTodo->uid()); QCOMPARE(task->property("relatedUid").toString(), updatedTodo->relatedTo()); QCOMPARE(task->property("itemId").toLongLong(), updatedItem.id()); @@ -821,6 +835,7 @@ QCOMPARE(task->doneDate(), updatedDoneDate.toUTC()); QCOMPARE(task->startDate(), updatedStartDate.toUTC()); QCOMPARE(task->dueDate(), updatedDueDate.toUTC()); + QCOMPARE(task->recurrence(), updatedRecurrence); QCOMPARE(task->property("todoUid").toString(), updatedTodo->uid()); QCOMPARE(task->property("relatedUid").toString(), updatedTodo->relatedTo()); QCOMPARE(task->property("itemId").toLongLong(), updatedItem.id()); @@ -2486,6 +2501,63 @@ // THEN we can detect that there was no time information, i.e. all day event QVERIFY(kdOnly.isDateOnly()); } + + void shouldConvertDomainTaskRecurrenceToAkonadiRecurrence_data() + { + QTest::addColumn("domainRecurrence"); + QTest::addColumn("akonadiRecurrence"); + + QTest::newRow("none") << Domain::Task::NoRecurrence << static_cast(KCalCore::Recurrence::rNone); + QTest::newRow("daily") << Domain::Task::Daily << static_cast(KCalCore::Recurrence::rDaily); + QTest::newRow("weekly") << Domain::Task::Weekly << static_cast(KCalCore::Recurrence::rWeekly); + QTest::newRow("monthlyDay") << Domain::Task::MonthlyDay << static_cast(KCalCore::Recurrence::rMonthlyDay); + } + + void shouldConvertDomainTaskRecurrenceToAkonadiRecurrence() + { + // GIVEN + QFETCH(Domain::Task::Recurrence, domainRecurrence); + QFETCH(ushort, akonadiRecurrence); + + Akonadi::Serializer serializer; + auto todo = KCalCore::Todo::Ptr::create(); + todo->setDtStart(KDateTime(Utils::DateTime::currentDateTime(), KDateTime::UTC)); + + // WHEN + serializer.setItemRecurrence(todo, domainRecurrence); + + // THEN + QCOMPARE(todo->recurrenceType(), akonadiRecurrence); + } + + void shouldConvertAkonadiRecurrenceToDomainTaskRecurrence_data() + { + QTest::addColumn("akonadiRecurrence"); + QTest::addColumn("domainRecurrence"); + + QTest::newRow("none") << static_cast(KCalCore::Recurrence::rNone) << Domain::Task::NoRecurrence; + QTest::newRow("daily") << static_cast(KCalCore::Recurrence::rDaily) << Domain::Task::Daily; + QTest::newRow("weekly") << static_cast(KCalCore::Recurrence::rWeekly) << Domain::Task::Weekly; + QTest::newRow("monthlyDay") << static_cast(KCalCore::Recurrence::rMonthlyDay) << Domain::Task::MonthlyDay; + } + + void shouldConvertAkonadiRecurrenceToDomainTaskRecurrence() + { + QFETCH(ushort, akonadiRecurrence); + QFETCH(Domain::Task::Recurrence, domainRecurrence); + + // GIVEN + Akonadi::Serializer serializer; + auto todo = KCalCore::Todo::Ptr::create(); + serializer.setItemRecurrence(todo, domainRecurrence); + QCOMPARE(todo->recurrenceType(), akonadiRecurrence); + + // WHEN + const Domain::Task::Recurrence actualDomainRecurrence = serializer.taskRecurrenceFromItem(todo); + + // THEN + QCOMPARE(actualDomainRecurrence, domainRecurrence); + } }; ZANSHIN_TEST_MAIN(AkonadiSerializerTest)