diff options
author | deloptes <deloptes@gmail.com> | 2016-09-26 21:14:58 +0200 |
---|---|---|
committer | Patrick Ohly <patrick.ohly@intel.com> | 2016-09-26 21:14:58 +0200 |
commit | 160b1f5e60600f60dcb45f64cf9e8cedabe1d378 (patch) | |
tree | 16afd1ac3832559b82894f11c8a9164cf091e56e | |
parent | cb34f4972bcbde44b8dc702fff3a7d791a317fc0 (diff) |
tde, tdepim: adapt to TDE 14.1tde
The notes API changed in TDE 14.1. Also includes several other
enhancements (error checking, testing).
-rw-r--r-- | src/backends/tdepim/KNotesIface.kidl | 69 | ||||
-rw-r--r-- | src/backends/tdepim/KNotesIface_stub.cpp | 61 | ||||
-rw-r--r-- | src/backends/tdepim/KNotesIface_stub.h | 10 | ||||
-rw-r--r-- | src/backends/tdepim/TDEPIMAddressBookSource.cpp | 47 | ||||
-rw-r--r-- | src/backends/tdepim/TDEPIMAddressBookSourceRegister.cpp | 58 | ||||
-rw-r--r-- | src/backends/tdepim/TDEPIMCalendarSource.cpp | 64 | ||||
-rw-r--r-- | src/backends/tdepim/TDEPIMCalendarSourceRegister.cpp | 257 | ||||
-rw-r--r-- | src/backends/tdepim/TDEPIMNotesSource.cpp | 54 | ||||
-rw-r--r-- | src/backends/tdepim/TDEPIMNotesSource.h | 4 | ||||
-rw-r--r-- | src/backends/tdepim/TDEPIMNotesSourceRegister.cpp | 204 |
10 files changed, 682 insertions, 146 deletions
diff --git a/src/backends/tdepim/KNotesIface.kidl b/src/backends/tdepim/KNotesIface.kidl new file mode 100644 index 00000000..3e52dc73 --- /dev/null +++ b/src/backends/tdepim/KNotesIface.kidl @@ -0,0 +1,69 @@ +<!DOCTYPE DCOP-IDL><DCOP-IDL> +<SOURCE>/opt/software_x64/KDE/TDE/tdepim/knotes/KNotesIface.h</SOURCE> +<INCLUDE>tqstring.h</INCLUDE> +<INCLUDE>tqdatetime.h</INCLUDE> +<INCLUDE>tqmap.h</INCLUDE> +<INCLUDE>dcopobject.h</INCLUDE> +<CLASS> + <NAME>KNotesIface</NAME> + <SUPER>DCOPObject</SUPER> + <FUNC> + <TYPE>TQString</TYPE> + <NAME>newNote</NAME> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>name</NAME></ARG> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>text</NAME></ARG> + </FUNC> + <FUNC> + <TYPE>TQString</TYPE> + <NAME>newNoteFromClipboard</NAME> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>name</NAME></ARG> + </FUNC> + <FUNC> + <TYPE>ASYNC</TYPE> + <NAME>killNote</NAME> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>noteId</NAME></ARG> + </FUNC> + <FUNC> + <TYPE>ASYNC</TYPE> + <NAME>killNote</NAME> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>noteId</NAME></ARG> + <ARG><TYPE>bool</TYPE><NAME>force</NAME></ARG> + </FUNC> + <FUNC qual="const"> + <TYPE>TQMap<TQString,TQString></TYPE> + <NAME>notes</NAME> + </FUNC> + <FUNC> + <TYPE>ASYNC</TYPE> + <NAME>setName</NAME> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>noteId</NAME></ARG> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>newName</NAME></ARG> + </FUNC> + <FUNC> + <TYPE>ASYNC</TYPE> + <NAME>setText</NAME> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>noteId</NAME></ARG> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>newText</NAME></ARG> + </FUNC> + <FUNC qual="const"> + <TYPE>TQString</TYPE> + <NAME>name</NAME> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>noteId</NAME></ARG> + </FUNC> + <FUNC qual="const"> + <TYPE>TQString</TYPE> + <NAME>text</NAME> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>noteId</NAME></ARG> + </FUNC> + <FUNC qual="const"> + <TYPE>int</TYPE> + <NAME>getRevision</NAME> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>noteId</NAME></ARG> + </FUNC> + <FUNC qual="const"> + <TYPE>TQDateTime</TYPE> + <NAME>getLastModified</NAME> + <ARG><TYPE qleft="const" qright="&">TQString</TYPE><NAME>noteId</NAME></ARG> + </FUNC> +</CLASS> +</DCOP-IDL> diff --git a/src/backends/tdepim/KNotesIface_stub.cpp b/src/backends/tdepim/KNotesIface_stub.cpp index 274179e9..ea6e66ad 100644 --- a/src/backends/tdepim/KNotesIface_stub.cpp +++ b/src/backends/tdepim/KNotesIface_stub.cpp @@ -4,14 +4,12 @@ ** ** WARNING! All changes made in this file will be lost! ** -** $Id: KNotesIface_stub.cpp,v 1.2 2016/09/01 10:40:05 emanoil Exp $ -** *****************************************************************************/ #include "KNotesIface_stub.h" #include <dcopclient.h> -#include <tqdatastream.h> +#include <kdatastream.h> KNotesIface_stub::KNotesIface_stub( const TQCString& app, const TQCString& obj ) @@ -80,32 +78,6 @@ TQString KNotesIface_stub::newNoteFromClipboard( const TQString& arg0 ) return result; } -void KNotesIface_stub::showNote( const TQString& arg0 ) -{ - if ( !dcopClient() ) { - setStatus( CallFailed ); - return; - } - TQByteArray data; - TQDataStream arg( data, IO_WriteOnly ); - arg << arg0; - dcopClient()->send( app(), obj(), "showNote(TQString)", data ); - setStatus( CallSucceeded ); -} - -void KNotesIface_stub::hideNote( const TQString& arg0 ) -{ - if ( !dcopClient() ) { - setStatus( CallFailed ); - return; - } - TQByteArray data; - TQDataStream arg( data, IO_WriteOnly ); - arg << arg0; - dcopClient()->send( app(), obj(), "hideNote(TQString)", data ); - setStatus( CallSucceeded ); -} - void KNotesIface_stub::killNote( const TQString& arg0 ) { if ( !dcopClient() ) { @@ -234,22 +206,9 @@ TQString KNotesIface_stub::text( const TQString& arg0 ) return result; } -void KNotesIface_stub::sync( const TQString& arg0 ) -{ - if ( !dcopClient() ) { - setStatus( CallFailed ); - return; - } - TQByteArray data; - TQDataStream arg( data, IO_WriteOnly ); - arg << arg0; - dcopClient()->send( app(), obj(), "sync(TQString)", data ); - setStatus( CallSucceeded ); -} - -bool KNotesIface_stub::isNew( const TQString& arg0, const TQString& arg1 ) +int KNotesIface_stub::getRevision( const TQString& arg0 ) { - bool result = false; + int result = 0; if ( !dcopClient() ) { setStatus( CallFailed ); return result; @@ -258,9 +217,8 @@ bool KNotesIface_stub::isNew( const TQString& arg0, const TQString& arg1 ) TQCString replyType; TQDataStream arg( data, IO_WriteOnly ); arg << arg0; - arg << arg1; - if ( dcopClient()->call( app(), obj(), "isNew(TQString,TQString)", data, replyType, replyData ) ) { - if ( replyType == "bool" ) { + if ( dcopClient()->call( app(), obj(), "getRevision(TQString)", data, replyType, replyData ) ) { + if ( replyType == "int" ) { TQDataStream _reply_stream( replyData, IO_ReadOnly ); _reply_stream >> result; setStatus( CallSucceeded ); @@ -273,9 +231,9 @@ bool KNotesIface_stub::isNew( const TQString& arg0, const TQString& arg1 ) return result; } -bool KNotesIface_stub::isModified( const TQString& arg0, const TQString& arg1 ) +TQDateTime KNotesIface_stub::getLastModified( const TQString& arg0 ) { - bool result = false; + TQDateTime result; if ( !dcopClient() ) { setStatus( CallFailed ); return result; @@ -284,9 +242,8 @@ bool KNotesIface_stub::isModified( const TQString& arg0, const TQString& arg1 ) TQCString replyType; TQDataStream arg( data, IO_WriteOnly ); arg << arg0; - arg << arg1; - if ( dcopClient()->call( app(), obj(), "isModified(TQString,TQString)", data, replyType, replyData ) ) { - if ( replyType == "bool" ) { + if ( dcopClient()->call( app(), obj(), "getLastModified(TQString)", data, replyType, replyData ) ) { + if ( replyType == "TQDateTime" ) { TQDataStream _reply_stream( replyData, IO_ReadOnly ); _reply_stream >> result; setStatus( CallSucceeded ); diff --git a/src/backends/tdepim/KNotesIface_stub.h b/src/backends/tdepim/KNotesIface_stub.h index a21504b0..192f897d 100644 --- a/src/backends/tdepim/KNotesIface_stub.h +++ b/src/backends/tdepim/KNotesIface_stub.h @@ -4,8 +4,6 @@ ** ** WARNING! All changes made in this file will be lost! ** -** $Id: KNotesIface_stub.h,v 1.2 2016/09/01 10:40:05 emanoil Exp $ -** *****************************************************************************/ #ifndef __KNOTESIFACE_STUB__ @@ -14,6 +12,7 @@ #include <dcopstub.h> #include <dcopobject.h> #include <tqmap.h> +#include <tqdatetime.h> #include <tqstring.h> @@ -25,8 +24,6 @@ public: explicit KNotesIface_stub( const DCOPRef& ref ); virtual TQString newNote( const TQString& name, const TQString& text ); virtual TQString newNoteFromClipboard( const TQString& name ); - virtual ASYNC showNote( const TQString& noteId ); - virtual ASYNC hideNote( const TQString& noteId ); virtual ASYNC killNote( const TQString& noteId ); virtual ASYNC killNote( const TQString& noteId, bool force ); virtual TQMap<TQString,TQString> notes(); @@ -34,9 +31,8 @@ public: virtual ASYNC setText( const TQString& noteId, const TQString& newText ); virtual TQString name( const TQString& noteId ); virtual TQString text( const TQString& noteId ); - virtual ASYNC sync( const TQString& app ); - virtual bool isNew( const TQString& app, const TQString& noteId ); - virtual bool isModified( const TQString& app, const TQString& noteId ); + virtual int getRevision( const TQString& noteId ); + virtual TQDateTime getLastModified( const TQString& noteId ); protected: KNotesIface_stub() : DCOPStub( never_use ) {} }; diff --git a/src/backends/tdepim/TDEPIMAddressBookSource.cpp b/src/backends/tdepim/TDEPIMAddressBookSource.cpp index 8ab90de7..df993166 100644 --- a/src/backends/tdepim/TDEPIMAddressBookSource.cpp +++ b/src/backends/tdepim/TDEPIMAddressBookSource.cpp @@ -17,7 +17,7 @@ * 02110-1301 USA * * - * $Id: TDEPIMAddressBookSource.cpp,v 1.9 2016/09/12 19:57:27 emanoil Exp $ + * $Id: TDEPIMAddressBookSource.cpp,v 1.10 2016/09/20 12:56:49 emanoil Exp $ * */ @@ -125,17 +125,17 @@ TDEPIMAddressBookSource::Databases TDEPIMAddressBookSource::getDatabases() while ( (res = it.current()) != 0 ) { ++it; - std::string name_str(res->resourceName().utf8(),res->resourceName().utf8().length()); - std::string path_str(res->identifier().utf8(),res->identifier().utf8().length()); - SE_LOG_DEBUG(getDisplayName(), "SUB Name : %s , ID: %s", name_str.c_str(), path_str.c_str() ); + SE_LOG_DEBUG(getDisplayName(), "SUB Name : %s , ID: %s", + static_cast<const char*>(res->resourceName().utf8()), + static_cast<const char*>(res->identifier().utf8()) ); /* * we pull only active resources thus user has freedom to decide what wants to be visible for sync */ if ( res->isActive() ) { result.push_back ( Database ( - name_str, // the name of the resource - path_str, // the path - (we use the resource uid) + static_cast<const char*>(res->resourceName().utf8()), // the name of the resource + static_cast<const char*>(res->identifier().utf8()), // the path - (we use the resource uid) first, // default or not res->readOnly() // read only or not ) @@ -156,12 +156,11 @@ void TDEPIMAddressBookSource::open() TDEABC::Resource *res; while ( (res = it.current()) != 0 ) { ++it; - std::string path_str(res->identifier().utf8(),res->identifier().utf8().length()); - if ( id.compare(path_str) == 0 ) { + if ( id.compare(static_cast<const char*>(res->identifier().utf8())) == 0 ) { if ( ! res->isActive() ) Exception::throwError(SE_HERE, "internal error, configured resource is not active"); ticketPtr = res->requestSaveTicket(); - SE_LOG_DEBUG(getDisplayName(), "TDE address book id: %s ", path_str.c_str() ); + SE_LOG_DEBUG(getDisplayName(), "TDE address book id: %s ", static_cast<const char*>(res->identifier().utf8()) ); break; } } @@ -199,11 +198,12 @@ void TDEPIMAddressBookSource::listAllItems(RevisionMap_t &revisions) for (TDEABC::Resource::Iterator it=workbookPtr->begin(); it!=workbookPtr->end(); it++) { TDEABC::Addressee ab = (*it); TQString lm = lastModifiedNormalized(ab); - std::string uid_str(ab.uid().utf8(),ab.uid().utf8().length()); - std::string lm_str(lm.utf8(),lm.utf8().length()); - revisions[uid_str] = lm_str; + revisions[static_cast<const char*>(ab.uid().utf8())] = static_cast<const char*>(lm.utf8()); // m_categories.append(a.categories()); // Set filter categories - SE_LOG_DEBUG(getDisplayName(), "Addressee UID: %s last changed(%s)",uid_str.c_str(),lm_str.c_str() ); + SE_LOG_DEBUG(getDisplayName(), "Addressee UID: %s last changed(%s)", + static_cast<const char*>(ab.uid().utf8()), + static_cast<const char*>(lm.utf8()) + ); } } @@ -261,10 +261,11 @@ TrackingSyncSource::InsertItemResult TDEPIMAddressBookSource::insertItem(const s TDEABC::Addressee addresseeNew = workbookPtr->findByUid(uidOld); TQString revision = lastModifiedNormalized(addresseeNew); - std::string uid_str(uidOld.utf8(),uidOld.utf8().length()); - std::string rev_str(revision.utf8(),revision.utf8().length()); - SE_LOG_DEBUG(getDisplayName(), "TDE addressbook UID= %s ADD/UPDATE (REV=%s) OK",uid_str.c_str(),rev_str.c_str() ); - return InsertItemResult(uid_str, rev_str, state); + + SE_LOG_DEBUG(getDisplayName(), "TDE addressbook UID= %s ADD/UPDATE (REV=%s) OK", + static_cast<const char*>(uidOld.utf8()), + static_cast<const char*>(revision.utf8()) ); + return InsertItemResult(static_cast<const char*>(uidOld.utf8()), static_cast<const char*>(revision.utf8()), state); } void TDEPIMAddressBookSource::readItem(const std::string &luid, std::string &item, bool raw) @@ -288,12 +289,10 @@ void TDEPIMAddressBookSource::readItem(const std::string &luid, std::string &ite else data = converter.createVCard(addressee, TDEABC::VCardConverter::v3_0); - std::string data_str(data.utf8(),data.utf8().length()); - - item.assign(data_str.c_str()); + item.assign(static_cast<const char*>(data.utf8())); /* DEBUG SE_LOG_DEBUG(getDisplayName(), "Item id ( %s )", luid.c_str() ); - SE_LOG_DEBUG(getDisplayName(), "data %s", data_str.c_str()); + SE_LOG_DEBUG(getDisplayName(), "data %s", static_cast<const char*>(data.utf8())); */ } @@ -341,9 +340,9 @@ std::string TDEPIMAddressBookSource::getDescription(const string &luid) desc.append((*it).number()).append(", "); } desc.append("\n"); - std::string desc_str(desc.utf8(),desc.utf8().length()); - SE_LOG_DEBUG(getDisplayName(), "User summary %s", desc_str.c_str()); - return desc_str; + + SE_LOG_DEBUG(getDisplayName(), "User summary %s", static_cast<const char*>(desc.utf8())); + return static_cast<const char*>(desc.utf8()); } void TDEPIMAddressBookSource::getSynthesisInfo(SynthesisInfo &info, diff --git a/src/backends/tdepim/TDEPIMAddressBookSourceRegister.cpp b/src/backends/tdepim/TDEPIMAddressBookSourceRegister.cpp index 6ce03509..6de97fcd 100644 --- a/src/backends/tdepim/TDEPIMAddressBookSourceRegister.cpp +++ b/src/backends/tdepim/TDEPIMAddressBookSourceRegister.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA * - * $Id: TDEPIMAddressBookSourceRegister.cpp,v 1.4 2016/09/08 22:58:08 emanoil Exp $ + * $Id: TDEPIMAddressBookSourceRegister.cpp,v 1.5 2016/09/20 12:56:49 emanoil Exp $ * */ @@ -73,4 +73,60 @@ public: } } registerMe; +#ifdef ENABLE_TDEPIMABC +#ifdef ENABLE_UNIT_TESTS + +class TDEAddressBookTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(TDEAddressBookTest); + CPPUNIT_TEST(testInstantiate); + CPPUNIT_TEST_SUITE_END(); + +protected: + static string addItem(boost::shared_ptr<TestingSyncSource> source, + string &data) { + SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data); + return res.m_luid; + } + + void testInstantiate() { + boost::shared_ptr<SyncSource> source; + // source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true)); + // source.reset(SyncSource::createTestingSource("addressbook", "contacts", true)); + source.reset(SyncSource::createTestingSource("addressbook", "tdepim-contacts", true)); + source.reset(SyncSource::createTestingSource("addressbook", "TDE Contacts", true)); + // source.reset(SyncSource::createTestingSource("addressbook", "TDE Address Book:text/x-vcard", true)); + source.reset(SyncSource::createTestingSource("addressbook", "TDE Address Book:text/vcard", true)); + } + + // TODO: support default databases + + // void testOpenDefaultAddressBook() { + // boost::shared_ptr<TestingSyncSource> source; + // source.reset((TestingSyncSource *)SyncSource::createTestingSource("contacts", "kde-contacts", true, NULL)); + // CPPUNIT_ASSERT_NO_THROW(source->open()); + // } + +SYNCEVOLUTION_TEST_SUITE_REGISTRATION(TDEAddressBookTest); + +#endif // ENABLE_UNIT_TESTS + +namespace { +#if 0 +} +#endif + +static class vCard30Test : public RegisterSyncSourceTest { +public: + vCard30Test() : RegisterSyncSourceTest("tdepim_contact", "eds_contact") {} + + virtual void updateConfig(ClientTestConfig &config) const + { + config.m_type = "tdepim-contacts"; + } +} vCard30Test; + +} + +#endif //ENABLE_TDEPIMABC + SE_END_CXX diff --git a/src/backends/tdepim/TDEPIMCalendarSource.cpp b/src/backends/tdepim/TDEPIMCalendarSource.cpp index 12888160..27ed4654 100644 --- a/src/backends/tdepim/TDEPIMCalendarSource.cpp +++ b/src/backends/tdepim/TDEPIMCalendarSource.cpp @@ -17,7 +17,7 @@ * 02110-1301 USA * * - * $Id: TDEPIMCalendarSource.cpp,v 1.12 2016/09/12 19:57:27 emanoil Exp $ + * $Id: TDEPIMCalendarSource.cpp,v 1.14 2016/09/20 12:56:49 emanoil Exp $ * */ @@ -105,20 +105,18 @@ TDEPIMCalendarSource::Databases TDEPIMCalendarSource::getDatabases() KCal::CalendarResourceManager * mgr = calendarResPtr->resourceManager(); /* * we pull only active resources so the user has some freedom to decide - * what he wants to be visible for sync this will result in setting + * what will be visible for sync */ for (KRES::Manager<KCal::ResourceCalendar>::ActiveIterator i = mgr->activeBegin(); i != mgr->activeEnd(); i++) { - std::string name_str(( *i )->resourceName().utf8(),( *i )->resourceName().utf8().length()); - std::string path_str(( *i )->identifier().utf8(),( *i )->identifier().utf8().length()); // std::string info_str(( *i )->infoText( ).utf8(),( *i )->infoText( ).utf8().length()); // SE_LOG_DEBUG(getDisplayName(), "resource: NAME(%s), ID(%s), INFO(%s)", // name_str.c_str(), path_str.c_str(), info_str.c_str()); result.push_back ( Database ( - name_str, // the name of the resource - path_str, // the path - (we use the resource uid) + static_cast<const char*>(( *i )->resourceName().utf8()), // the name of the resource + static_cast<const char*>(( *i )->identifier().utf8()), // the path - (we use the resource uid) first, // default or not ( *i )->readOnly() // read only or not ) @@ -136,11 +134,11 @@ void TDEPIMCalendarSource::open() KCal::CalendarResourceManager * mgr = calendarResPtr->resourceManager(); /* - * we pull only active resources thus user has freedom to decide what wants to be visible for sync + * we pull only active resources so the user has some freedom to decide + * what will be visible for sync */ for (KRES::Manager<KCal::ResourceCalendar>::ActiveIterator i = mgr->activeBegin(); i != mgr->activeEnd(); i++) { - std::string path_str(( *i )->identifier().utf8(),( *i )->identifier().utf8().length()); - if ( path_str == id ) { + if ( static_cast<const char*>(( *i )->identifier().utf8()) == id ) { // SE_LOG_DEBUG(getDisplayName(), "Resource id: %s found", path_str.c_str() ); calendarPtr = ( *i ) ; break; @@ -196,34 +194,31 @@ void TDEPIMCalendarSource::listAllItems(SyncSourceRevisions::RevisionMap_t &revi case TDEPIM_TASKS: e = calendarPtr->rawEvents( KCal::EventSortUnsorted , KCal::SortDirectionAscending ); for (KCal::Event::List::ConstIterator i = e.begin(); i != e.end(); i++) { - id = (*i)->uid(); lm = lastModifiedNormalized((*i)); - std::string id_str(id.utf8(),id.utf8().length()); - std::string lm_str(lm.utf8(),lm.utf8().length()); - revisions[id_str] = lm_str; - SE_LOG_DEBUG(getDisplayName(), "Event UID: %s last changed( %s )", id_str.c_str(), lm_str.c_str()); + revisions[static_cast<const char*>((*i)->uid().utf8())] = static_cast<const char*>(lm.utf8()); + SE_LOG_DEBUG(getDisplayName(), "Event UID: %s last changed( %s )", + static_cast<const char*>((*i)->uid().utf8()), + static_cast<const char*>(lm.utf8())); } break; case TDEPIM_TODO: t = calendarPtr->rawTodos( KCal::TodoSortUnsorted , KCal::SortDirectionAscending ); for (KCal::Todo::List::ConstIterator i = t.begin(); i != t.end(); i++) { - id = (*i)->uid(); lm = lastModifiedNormalized((*i)); - std::string id_str(id.utf8(),id.utf8().length()); - std::string lm_str(lm.utf8(),lm.utf8().length()); - revisions[id_str] = lm_str; - SE_LOG_DEBUG(getDisplayName(), "Todos UID: %s last changed( %s )", id_str.c_str(), lm_str.c_str()); + revisions[static_cast<const char*>((*i)->uid().utf8())] = static_cast<const char*>(lm.utf8()); + SE_LOG_DEBUG(getDisplayName(), "Todos UID: %s last changed( %s )", + static_cast<const char*>((*i)->uid().utf8()), + static_cast<const char*>(lm.utf8())); } break; case TDEPIM_JOURNAL: j = calendarPtr->rawJournals( KCal::JournalSortUnsorted , KCal::SortDirectionAscending ); for (KCal::Journal::List::ConstIterator i = j.begin(); i != j.end(); i++) { - id = (*i)->uid(); lm = lastModifiedNormalized((*i)); - std::string id_str(id.utf8(),id.utf8().length()); - std::string lm_str(lm.utf8(),lm.utf8().length()); - revisions[id_str] = lm_str; - SE_LOG_DEBUG(getDisplayName(), "Journal UID: %s last changed( %s )", id_str.c_str(), lm_str.c_str()); + revisions[static_cast<const char*>((*i)->uid().utf8())] = static_cast<const char*>(lm.utf8()); + SE_LOG_DEBUG(getDisplayName(), "Journal UID: %s last changed( %s )", + static_cast<const char*>((*i)->uid().utf8()), + static_cast<const char*>(lm.utf8())); } break; default: @@ -234,7 +229,7 @@ void TDEPIMCalendarSource::listAllItems(SyncSourceRevisions::RevisionMap_t &revi TrackingSyncSource::InsertItemResult TDEPIMCalendarSource::insertItem(const std::string &luid, const std::string &item, bool raw) { - +// SE_LOG_DEBUG(getDisplayName(), "Item payload: ( %s )", item.data() ); InsertItemResultState state = ITEM_OKAY; TrackingSyncSource::InsertItemResult result; KCal::ICalFormat format; @@ -291,10 +286,10 @@ TrackingSyncSource::InsertItemResult TDEPIMCalendarSource::insertItem(const std: Exception::throwError(SE_HERE, "internal error, unable to get item from calendar"); TQString lm=lastModifiedNormalized(newinc); - std::string ret_uid(newinc->uid().utf8(), newinc->uid().utf8().length()); - std::string ret_rev(lm.utf8(), lm.utf8().length()); - SE_LOG_DEBUG(getDisplayName(), "Item ( %s : %s ) done.", ret_uid.c_str() , ret_rev.c_str() ); - return InsertItemResult(ret_uid, ret_rev, state); + SE_LOG_DEBUG(getDisplayName(), "Item ( %s : %s ) done.", + static_cast<const char*>(newinc->uid().utf8()), + static_cast<const char*>(lm.utf8() )); + return InsertItemResult(static_cast<const char*>(newinc->uid().utf8()), static_cast<const char*>(lm.utf8()), state); } void TDEPIMCalendarSource::readItem(const std::string &luid, std::string &item, bool raw) @@ -327,10 +322,7 @@ void TDEPIMCalendarSource::readItem(const std::string &luid, std::string &item, // Convert the data to icalendar TQString data = iCalFmt.toString( &cal ); -// it should be possible to use data.utf8() directly, as it returns char array -// but no time to test so far - std::string data_str( data.utf8(), data.utf8().length() ); - item.assign(data_str.c_str()); + item.assign(static_cast<const char*>(data.utf8())); SE_LOG_DEBUG(getDisplayName(), "Item id ( %s )", luid.c_str() ); // SE_LOG_DEBUG(getDisplayName(), "TDE calendar Data: %s\n", data_str.c_str() ); } @@ -355,10 +347,8 @@ void TDEPIMCalendarSource::removeItem(const std::string &luid) std::string TDEPIMCalendarSource::getDescription(const std::string &luid) { KCal::Incidence *inc = calendarPtr->incidence(TQString::fromUtf8(luid.data(),luid.size())); - if ( inc ) { - std::string sum_str(inc->summary().utf8(),inc->summary().utf8().length()); - return sum_str; - } + if ( inc ) + return static_cast<const char*>(inc->summary().utf8()); SE_LOG_DEBUG(getDisplayName(), "Resource id(%s) not found", luid.c_str() ); return ""; } diff --git a/src/backends/tdepim/TDEPIMCalendarSourceRegister.cpp b/src/backends/tdepim/TDEPIMCalendarSourceRegister.cpp index e8bf6faa..ad18bb45 100644 --- a/src/backends/tdepim/TDEPIMCalendarSourceRegister.cpp +++ b/src/backends/tdepim/TDEPIMCalendarSourceRegister.cpp @@ -17,7 +17,7 @@ * 02110-1301 USA * * - * $Id: TDEPIMCalendarSourceRegister.cpp,v 1.5 2016/09/08 22:58:08 emanoil Exp $ + * $Id: TDEPIMCalendarSourceRegister.cpp,v 1.6 2016/09/20 12:56:49 emanoil Exp $ * */ @@ -123,5 +123,260 @@ public: } } registerMe; +#ifdef ENABLE_TDEPIMCAL +#ifdef ENABLE_UNIT_TESTS + +class TDECalendarTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(TDECalendarTest); + CPPUNIT_TEST(testInstantiate); + + // There is no default database in Akonadi: + // CPPUNIT_TEST(testOpenDefaultCalendar); + // CPPUNIT_TEST(testOpenDefaultTodo); + // CPPUNIT_TEST(testOpenDefaultMemo); + + // Besides, don't enable tests which depend on running Akonadi, + // because that would cause "client-test SyncEvolution" unless + // Akonadi was started first: + // CPPUNIT_TEST(testTimezones); + + CPPUNIT_TEST_SUITE_END(); + +protected: + static string addItem(boost::shared_ptr<TestingSyncSource> source, + string &data) { + SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data); + return res.m_luid; + } + + void testInstantiate() { + boost::shared_ptr<SyncSource> source; + // source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true)); + // source.reset(SyncSource::createTestingSource("addressbook", "contacts", true)); + source.reset(SyncSource::createTestingSource("addressbook", "tdepim-contacts", true)); + source.reset(SyncSource::createTestingSource("addressbook", "TDE Contacts", true)); + source.reset(SyncSource::createTestingSource("addressbook", "TDE Address Book:text/x-vcard", true)); + source.reset(SyncSource::createTestingSource("addressbook", "TDE Address Book:text/vcard", true)); + + + // source.reset(SyncSource::createTestingSource("calendar", "calendar", true)); + source.reset(SyncSource::createTestingSource("calendar", "tdepim-calendar", true)); + source.reset(SyncSource::createTestingSource("calendar", "TDE Calendar:text/calendar", true)); + + // source.reset(SyncSource::createTestingSource("tasks", "tasks", true)); + source.reset(SyncSource::createTestingSource("tasks", "tdepim-tasks", true)); + source.reset(SyncSource::createTestingSource("tasks", "TDE Tasks", true)); + source.reset(SyncSource::createTestingSource("tasks", "TDE Task List:text/calendar", true)); + + // source.reset(SyncSource::createTestingSource("memos", "memos", true)); + source.reset(SyncSource::createTestingSource("memos", "tdepim-memos", true)); + source.reset(SyncSource::createTestingSource("memos", "TDE Memos:text/plain", true)); + } + + // TODO: support default databases + + // void testOpenDefaultCalendar() { + // boost::shared_ptr<TestingSyncSource> source; + // source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "tdepim-calendar", true, NULL)); + // CPPUNIT_ASSERT_NO_THROW(source->open()); + // } + + // void testOpenDefaultTodo() { + // boost::shared_ptr<TestingSyncSource> source; + // source.reset((TestingSyncSource *)SyncSource::createTestingSource("tasks", "tdepim-tasks", true, NULL)); + // CPPUNIT_ASSERT_NO_THROW(source->open()); + // } + + // void testOpenDefaultMemo() { + // boost::shared_ptr<TestingSyncSource> source; + // source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "tdepim-memos", true, NULL)); + // CPPUNIT_ASSERT_NO_THROW(source->open()); + // } + + void testTimezones() { + const char *prefix = getenv("CLIENT_TEST_EVOLUTION_PREFIX"); + if (!prefix) { + prefix = "SyncEvolution_Test_"; + } + + boost::shared_ptr<TestingSyncSource> source; + source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "tdepim-calendar", true, prefix)); + CPPUNIT_ASSERT_NO_THROW(source->open()); + + string newyork = + "BEGIN:VCALENDAR\n" + "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n" + "VERSION:2.0\n" + "BEGIN:VTIMEZONE\n" + "TZID:America/New_York\n" + "BEGIN:STANDARD\n" + "TZOFFSETFROM:-0400\n" + "TZOFFSETTO:-0500\n" + "TZNAME:EST\n" + "DTSTART:19701025T020000\n" + "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10\n" + "END:STANDARD\n" + "BEGIN:DAYLIGHT\n" + "TZOFFSETFROM:-0500\n" + "TZOFFSETTO:-0400\n" + "TZNAME:EDT\n" + "DTSTART:19700405T020000\n" + "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=4\n" + "END:DAYLIGHT\n" + "END:VTIMEZONE\n" + "BEGIN:VEVENT\n" + "UID:artificial\n" + "DTSTAMP:20060416T205224Z\n" + "DTSTART;TZID=America/New_York:20060406T140000\n" + "DTEND;TZID=America/New_York:20060406T143000\n" + "TRANSP:OPAQUE\n" + "SEQUENCE:2\n" + "SUMMARY:timezone New York with custom definition\n" + "DESCRIPTION:timezone New York with custom definition\n" + "CLASS:PUBLIC\n" + "CREATED:20060416T205301Z\n" + "LAST-MODIFIED:20060416T205301Z\n" + "END:VEVENT\n" + "END:VCALENDAR\n"; + + string luid; + CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, newyork)); + + string newyork_suffix = newyork; + boost::replace_first(newyork_suffix, + "UID:artificial", + "UID:artificial-2"); + boost::replace_all(newyork_suffix, + "TZID:America/New_York", + "TZID://FOOBAR/America/New_York-SUFFIX"); + CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, newyork_suffix)); + + string notimezone = + "BEGIN:VCALENDAR\n" + "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n" + "VERSION:2.0\n" + "BEGIN:VEVENT\n" + "UID:artificial-3\n" + "DTSTAMP:20060416T205224Z\n" + "DTSTART;TZID=America/New_York:20060406T140000\n" + "DTEND;TZID=America/New_York:20060406T143000\n" + "TRANSP:OPAQUE\n" + "SEQUENCE:2\n" + "SUMMARY:timezone New York without custom definition\n" + "DESCRIPTION:timezone New York without custom definition\n" + "CLASS:PUBLIC\n" + "CREATED:20060416T205301Z\n" + "LAST-MODIFIED:20060416T205301Z\n" + "END:VEVENT\n" + "END:VCALENDAR\n"; + CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, notimezone)); + + // fake VTIMEZONE where daylight saving starts on first Sunday in March + string fake_march = + "BEGIN:VCALENDAR\n" + "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n" + "VERSION:2.0\n" + "BEGIN:VTIMEZONE\n" + "TZID:FAKE\n" + "BEGIN:STANDARD\n" + "TZOFFSETFROM:-0400\n" + "TZOFFSETTO:-0500\n" + "TZNAME:EST MARCH\n" + "DTSTART:19701025T020000\n" + "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10\n" + "END:STANDARD\n" + "BEGIN:DAYLIGHT\n" + "TZOFFSETFROM:-0500\n" + "TZOFFSETTO:-0400\n" + "TZNAME:EDT\n" + "DTSTART:19700405T020000\n" + "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=3\n" + "END:DAYLIGHT\n" + "END:VTIMEZONE\n" + "BEGIN:VEVENT\n" + "UID:artificial-4\n" + "DTSTAMP:20060416T205224Z\n" + "DTSTART;TZID=FAKE:20060406T140000\n" + "DTEND;TZID=FAKE:20060406T143000\n" + "TRANSP:OPAQUE\n" + "SEQUENCE:2\n" + "SUMMARY:fake timezone with daylight starting in March\n" + "CLASS:PUBLIC\n" + "CREATED:20060416T205301Z\n" + "LAST-MODIFIED:20060416T205301Z\n" + "END:VEVENT\n" + "END:VCALENDAR\n"; + CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, fake_march)); + + string fake_may = fake_march; + boost::replace_first(fake_may, + "UID:artificial-4", + "UID:artificial-5"); + boost::replace_first(fake_may, + "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=3", + "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=5"); + boost::replace_first(fake_may, + "starting in March", + "starting in May"); + boost::replace_first(fake_may, + "TZNAME:EST MARCH", + "TZNAME:EST MAY"); + CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, fake_may)); + + // insert again, shouldn't re-add timezone + CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, fake_may)); + } +}; + +SYNCEVOLUTION_TEST_SUITE_REGISTRATION(TDECalendarTest); + +#endif // ENABLE_UNIT_TESTS + +namespace { +#if 0 +} +#endif + +static class iCal20Test : public RegisterSyncSourceTest { +public: + iCal20Test() : RegisterSyncSourceTest("tdepim_event", "eds_event") {} + + virtual void updateConfig(ClientTestConfig &config) const + { + config.m_type = "tdepim-calendar"; + // Looks like iCalendar file resource in Akonadi 1.11.0 does + // not actually enforce iCalendar 2.0 semantic. It allows + // updating of events with no UID + // (testLinkedItemsInsertBothUpdateChildNoIDs) + // and fails to detect double-adds (testInsertTwice). + // TODO: this should better be fixed. + config.m_sourceKnowsItemSemantic = false; + } +} iCal20Test; + +static class iTodo20Test : public RegisterSyncSourceTest { +public: + iTodo20Test() : RegisterSyncSourceTest("tdepim_task", "eds_task") {} + + virtual void updateConfig(ClientTestConfig &config) const + { + config.m_type = "tdepim-tasks"; + // See above. + config.m_sourceKnowsItemSemantic = false; + } +} iTodo20Test; + +static class MemoTest : public RegisterSyncSourceTest { +public: + MemoTest() : RegisterSyncSourceTest("tdepim_memo", "eds_memo") {} + + virtual void updateConfig(ClientTestConfig &config) const + { + config.m_type = "TDE Memos"; // use an alias here to test that + } +} memoTest; + +} +#endif SE_END_CXX diff --git a/src/backends/tdepim/TDEPIMNotesSource.cpp b/src/backends/tdepim/TDEPIMNotesSource.cpp index 265a3ce7..384cdffc 100644 --- a/src/backends/tdepim/TDEPIMNotesSource.cpp +++ b/src/backends/tdepim/TDEPIMNotesSource.cpp @@ -17,7 +17,7 @@ * 02110-1301 USA * * - * $Id: TDEPIMNotesSource.cpp,v 1.7 2016/09/12 19:57:27 emanoil Exp $ + * $Id: TDEPIMNotesSource.cpp,v 1.9 2016/09/20 12:56:49 emanoil Exp $ * */ @@ -83,6 +83,20 @@ TDEPIMNotesSource::~TDEPIMNotesSource() { SE_LOG_DEBUG(getDisplayName(), "kNotes exit OK"); } + +TQString TDEPIMNotesSource::lastModifiedNormalized(TQDateTime &d) const +{ + // if no modification date is available, always return the same 0-time stamp + // to avoid that 2 calls deliver different times which would be treated as changed entry + // this would result in 1.1.1970 + if (!d.isValid()) + d.setTime_t(0); + + // We pass UTC, because we open the calendar in UTC +// return d.toString(TQt::ISODate); + return d.toString("yyyyMMddThhmmssZ"); +} + TQString TDEPIMNotesSource::stripHtml(TQString input) { TQString output = NULL; @@ -107,6 +121,10 @@ TDEPIMNotesSource::Databases TDEPIMNotesSource::getDatabases() Databases result; +/* FIXME the Knotes interface provides only one resource for now +* When in future it is able to do multiple resources, the interface must change +* so that a resource is configurable just like the calendar resources are +*/ const std::string name("tdenotes"); const std::string path("tdepimnotes"); @@ -153,7 +171,7 @@ void TDEPIMNotesSource::close() void TDEPIMNotesSource::listAllItems(SyncSourceRevisions::RevisionMap_t &revisions) { - KMD5 hash_value; +// KMD5 hash_value; TQMap <TDENoteID_t,TQString> fNotes = kn_iface->notes(); if (kn_iface->status() != DCOPStub::CallSucceeded) Exception::throwError(SE_HERE, "internal error, DCOP call failed"); @@ -161,14 +179,14 @@ void TDEPIMNotesSource::listAllItems(SyncSourceRevisions::RevisionMap_t &revisio TQMap<TDENoteID_t,TQString>::ConstIterator i; for (i = fNotes.begin(); i != fNotes.end(); i++) { - TQString data = i.data() + '\n' + stripHtml(kn_iface->text(i.key())); - hash_value.update(data.utf8(),data.utf8().length()); + TQDateTime dt = kn_iface->getLastModified(TQString(i.key().utf8())); + if (kn_iface->status() != DCOPStub::CallSucceeded) + Exception::throwError(SE_HERE, "internal error, DCOP call failed"); + revisions[static_cast<const char*>(i.key().utf8())] = static_cast<const char*>(lastModifiedNormalized(dt).utf8()); - std::string uid_str(i.key().utf8(),i.key().utf8().length()); - revisions[uid_str] = hash_value.base64Digest().data(); - hash_value.reset(); /* DEBUG SE_LOG_DEBUG(getDisplayName(), "KNotes UID: %s", static_cast<const char*>(i.key().utf8()) ); + SE_LOG_DEBUG(getDisplayName(), "KNotes REV: %s", static_cast<const char*>(lastModifiedNormalized(dt).utf8()) ); SE_LOG_DEBUG(getDisplayName(), "KNotes DATA: %s", static_cast<const char*>(data.utf8())); */ } @@ -179,16 +197,10 @@ TrackingSyncSource::InsertItemResult TDEPIMNotesSource::insertItem(const std::st InsertItemResultState state = ITEM_OKAY; TrackingSyncSource::InsertItemResult result; - KMD5 hash_value; TQString uid = TQString::fromUtf8(luid.data(), luid.size()); TQString data = TQString::fromUtf8(item.data(), item.size()); - // store the hashed value of data to be able to find our new note later and get the id - hash_value.update(data.utf8(),data.utf8().length()); - TQCString rev = hash_value.base64Digest(); - hash_value.reset(); - TQString summary = data.section('\n', 0, 0); // first line is our title == summary TQString body = data.section('\n', 1); // rest /* DEBUG @@ -211,8 +223,10 @@ TrackingSyncSource::InsertItemResult TDEPIMNotesSource::insertItem(const std::st Exception::throwError(SE_HERE, "internal error, add note failed"); } - std::string ret_uid(newuid.utf8(), newuid.utf8().length()); - return InsertItemResult(ret_uid, rev.data(), state); + TQDateTime dt = kn_iface->getLastModified(newuid); + if (kn_iface->status() != DCOPStub::CallSucceeded) + Exception::throwError(SE_HERE, "internal error, DCOP call failed"); + return InsertItemResult(static_cast<const char*>(newuid.utf8()), static_cast<const char*>(lastModifiedNormalized(dt).utf8()), state); } @@ -221,8 +235,7 @@ void TDEPIMNotesSource::readItem(const std::string &luid, std::string &item, boo TQString uid = TQString::fromUtf8(luid.data(),luid.size()); TQString data = kn_iface->name( uid ) + '\n' + stripHtml(kn_iface->text( uid )); - std::string data_str( data.utf8(), data.utf8().length() ); - item.assign( data_str.c_str() ); + item.assign( static_cast<const char*>(data.utf8()) ); } void TDEPIMNotesSource::removeItem(const std::string &luid) @@ -242,10 +255,9 @@ std::string TDEPIMNotesSource::getDescription(const std::string &luid) { TQString uid = TQString::fromUtf8(luid.data(),luid.size()); TQString data = kn_iface->name( uid ); - if ( data.length() > 0 ) { - std::string sum_str(data.utf8(),data.utf8().length()); - return sum_str; - } + if ( data.length() > 0 ) + return static_cast<const char*>(data.utf8()); + SE_LOG_DEBUG(getDisplayName(), "Resource id(%s) not found", luid.c_str() ); return ""; } diff --git a/src/backends/tdepim/TDEPIMNotesSource.h b/src/backends/tdepim/TDEPIMNotesSource.h index d8b1809a..fd0d3b31 100644 --- a/src/backends/tdepim/TDEPIMNotesSource.h +++ b/src/backends/tdepim/TDEPIMNotesSource.h @@ -17,7 +17,7 @@ * 02110-1301 USA * * - * $Id: TDEPIMNotesSource.h,v 1.5 2016/09/08 22:58:08 emanoil Exp $ + * $Id: TDEPIMNotesSource.h,v 1.6 2016/09/20 12:56:49 emanoil Exp $ * */ @@ -76,6 +76,8 @@ private: */ static TQString stripHtml(TQString input); + TQString lastModifiedNormalized(TQDateTime &d) const; + /** * Implement some brief information extraction from the note */ diff --git a/src/backends/tdepim/TDEPIMNotesSourceRegister.cpp b/src/backends/tdepim/TDEPIMNotesSourceRegister.cpp index 7a5152b7..522ae6a0 100644 --- a/src/backends/tdepim/TDEPIMNotesSourceRegister.cpp +++ b/src/backends/tdepim/TDEPIMNotesSourceRegister.cpp @@ -17,7 +17,7 @@ * 02110-1301 USA * * - * $Id: TDEPIMNotesSourceRegister.cpp,v 1.5 2016/09/12 19:57:27 emanoil Exp $ + * $Id: TDEPIMNotesSourceRegister.cpp,v 1.6 2016/09/20 12:56:49 emanoil Exp $ * */ @@ -58,7 +58,7 @@ static class RegisterTDEPIMNotesSyncSource : public RegisterSyncSource public: RegisterTDEPIMNotesSyncSource() : RegisterSyncSource("TDE PIM Notes", -#ifdef ENABLE_TDEPIMCAL +#ifdef ENABLE_TDEPIMNOTES true, #else false, @@ -79,5 +79,205 @@ public: } registerMe; // TODO finish unit tests +#ifdef ENABLE_TDEPIMNOTES +#ifdef ENABLE_UNIT_TESTS +class TDENotesTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(TDENotesTest); + CPPUNIT_TEST(testInstantiate); + + // There is no default database in Akonadi: + // CPPUNIT_TEST(testOpenDefaultCalendar); + // CPPUNIT_TEST(testOpenDefaultTodo); + // CPPUNIT_TEST(testOpenDefaultMemo); + + // Besides, don't enable tests which depend on running Akonadi, + // because that would cause "client-test SyncEvolution" unless + // Akonadi was started first: + // CPPUNIT_TEST(testTimezones); + + CPPUNIT_TEST_SUITE_END(); + +protected: + static string addItem(boost::shared_ptr<TestingSyncSource> source, + string &data) { + SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data); + return res.m_luid; + } + + void testInstantiate() { + boost::shared_ptr<SyncSource> source; + + // source.reset(SyncSource::createTestingSource("memos", "memos", true)); + source.reset(SyncSource::createTestingSource("memos", "tdepim-notes", true)); + source.reset(SyncSource::createTestingSource("memos", "TDE PIM Notes:text/plain", true)); + } + + // TODO: support default databases + + // void testOpenDefaultMemo() { + // boost::shared_ptr<TestingSyncSource> source; + // source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "tdepim-memos", true, NULL)); + // CPPUNIT_ASSERT_NO_THROW(source->open()); + // } + + void testTimezones() { + const char *prefix = getenv("CLIENT_TEST_EVOLUTION_PREFIX"); + if (!prefix) { + prefix = "SyncEvolution_Test_"; + } + + boost::shared_ptr<TestingSyncSource> source; + source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "tdepim-notes", true, prefix)); + CPPUNIT_ASSERT_NO_THROW(source->open()); + + string newyork = + "BEGIN:VCALENDAR\n" + "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n" + "VERSION:2.0\n" + "BEGIN:VTIMEZONE\n" + "TZID:America/New_York\n" + "BEGIN:STANDARD\n" + "TZOFFSETFROM:-0400\n" + "TZOFFSETTO:-0500\n" + "TZNAME:EST\n" + "DTSTART:19701025T020000\n" + "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10\n" + "END:STANDARD\n" + "BEGIN:DAYLIGHT\n" + "TZOFFSETFROM:-0500\n" + "TZOFFSETTO:-0400\n" + "TZNAME:EDT\n" + "DTSTART:19700405T020000\n" + "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=4\n" + "END:DAYLIGHT\n" + "END:VTIMEZONE\n" + "BEGIN:VEVENT\n" + "UID:artificial\n" + "DTSTAMP:20060416T205224Z\n" + "DTSTART;TZID=America/New_York:20060406T140000\n" + "DTEND;TZID=America/New_York:20060406T143000\n" + "TRANSP:OPAQUE\n" + "SEQUENCE:2\n" + "SUMMARY:timezone New York with custom definition\n" + "DESCRIPTION:timezone New York with custom definition\n" + "CLASS:PUBLIC\n" + "CREATED:20060416T205301Z\n" + "LAST-MODIFIED:20060416T205301Z\n" + "END:VEVENT\n" + "END:VCALENDAR\n"; + + string luid; + CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, newyork)); + + string newyork_suffix = newyork; + boost::replace_first(newyork_suffix, + "UID:artificial", + "UID:artificial-2"); + boost::replace_all(newyork_suffix, + "TZID:America/New_York", + "TZID://FOOBAR/America/New_York-SUFFIX"); + CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, newyork_suffix)); + + + string notimezone = + "BEGIN:VCALENDAR\n" + "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n" + "VERSION:2.0\n" + "BEGIN:VEVENT\n" + "UID:artificial-3\n" + "DTSTAMP:20060416T205224Z\n" + "DTSTART;TZID=America/New_York:20060406T140000\n" + "DTEND;TZID=America/New_York:20060406T143000\n" + "TRANSP:OPAQUE\n" + "SEQUENCE:2\n" + "SUMMARY:timezone New York without custom definition\n" + "DESCRIPTION:timezone New York without custom definition\n" + "CLASS:PUBLIC\n" + "CREATED:20060416T205301Z\n" + "LAST-MODIFIED:20060416T205301Z\n" + "END:VEVENT\n" + "END:VCALENDAR\n"; + CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, notimezone)); + + // fake VTIMEZONE where daylight saving starts on first Sunday in March + string fake_march = + "BEGIN:VCALENDAR\n" + "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n" + "VERSION:2.0\n" + "BEGIN:VTIMEZONE\n" + "TZID:FAKE\n" + "BEGIN:STANDARD\n" + "TZOFFSETFROM:-0400\n" + "TZOFFSETTO:-0500\n" + "TZNAME:EST MARCH\n" + "DTSTART:19701025T020000\n" + "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10\n" + "END:STANDARD\n" + "BEGIN:DAYLIGHT\n" + "TZOFFSETFROM:-0500\n" + "TZOFFSETTO:-0400\n" + "TZNAME:EDT\n" + "DTSTART:19700405T020000\n" + "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=3\n" + "END:DAYLIGHT\n" + "END:VTIMEZONE\n" + "BEGIN:VEVENT\n" + "UID:artificial-4\n" + "DTSTAMP:20060416T205224Z\n" + "DTSTART;TZID=FAKE:20060406T140000\n" + "DTEND;TZID=FAKE:20060406T143000\n" + "TRANSP:OPAQUE\n" + "SEQUENCE:2\n" + "SUMMARY:fake timezone with daylight starting in March\n" + "CLASS:PUBLIC\n" + "CREATED:20060416T205301Z\n" + "LAST-MODIFIED:20060416T205301Z\n" + "END:VEVENT\n" + "END:VCALENDAR\n"; + CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, fake_march)); + + string fake_may = fake_march; + boost::replace_first(fake_may, + "UID:artificial-4", + "UID:artificial-5"); + boost::replace_first(fake_may, + "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=3", + "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=5"); + boost::replace_first(fake_may, + "starting in March", + "starting in May"); + boost::replace_first(fake_may, + "TZNAME:EST MARCH", + "TZNAME:EST MAY"); + CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, fake_may)); + + // insert again, shouldn't re-add timezone + CPPUNIT_ASSERT_NO_THROW(luid = addItem(source, fake_may)); + } +}; + +SYNCEVOLUTION_TEST_SUITE_REGISTRATION(TDENotesTest); + +#endif // ENABLE_UNIT_TESTS + +namespace { +#if 0 +} +#endif + + + +static class MemoTest : public RegisterSyncSourceTest { +public: + MemoTest() : RegisterSyncSourceTest("tdepim_notes", "eds_memo") {} + + virtual void updateConfig(ClientTestConfig &config) const + { + config.m_type = "TDE PIM Notes"; // use an alias here to test that + } +} memoTest; + +} +#endif SE_END_CXX |