2 * Copyright (C) 2008-2009 Patrick Ohly <patrick.ohly@gmx.de>
3 * Copyright (C) 2009 Intel Corporation
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) version 3.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include "ActiveSyncSource.h"
22 #include "ActiveSyncCalendarSource.h"
28 #ifdef ENABLE_UNIT_TESTS
29 # include <cppunit/extensions/TestFactoryRegistry.h>
30 # include <cppunit/extensions/HelperMacros.h>
35 #include <syncevo/declarations.h>
38 static SyncSource *createSource(const SyncSourceParams ¶ms)
40 SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
43 isMe = sourceType.m_backend == "ActiveSync Address Book";
46 #ifdef ENABLE_ACTIVESYNC
47 new ActiveSyncContactSource(params)
49 RegisterSyncSource::InactiveSource(params)
54 isMe = sourceType.m_backend == "ActiveSync Events";
57 #ifdef ENABLE_ACTIVESYNC
58 new ActiveSyncCalendarSource(params, EAS_ITEM_CALENDAR)
60 RegisterSyncSource::InactiveSource(params)
65 isMe = sourceType.m_backend == "ActiveSync Todos";
68 #ifdef ENABLE_ACTIVESYNC
69 new ActiveSyncCalFormatSource(params, EAS_ITEM_TODO)
71 RegisterSyncSource::InactiveSource(params)
76 isMe = sourceType.m_backend == "ActiveSync Memos";
79 #ifdef ENABLE_ACTIVESYNC
80 new ActiveSyncCalFormatSource(params, EAS_ITEM_JOURNAL)
82 RegisterSyncSource::InactiveSource(params)
90 static RegisterSyncSource registerMe("ActiveSync",
91 #ifdef ENABLE_ACTIVESYNC
97 "ActiveSync Address Book = eas-contacts\n"
98 "ActiveSync Events = eas-events\n"
99 "ActiveSync Todos = eas-todos\n"
100 "ActiveSync Memos = eas-memos",
102 (Aliases("ActiveSync Address Book") + "eas-contacts") +
103 (Aliases("ActiveSync Events") + "eas-events") +
104 (Aliases("ActiveSync Todos") + "eas-todos") +
105 (Aliases("ActiveSync Memos") + "eas-memos"));
107 #ifdef ENABLE_ACTIVESYNC
108 #ifdef ENABLE_UNIT_TESTS
110 class ActiveSyncsTest : public CppUnit::TestFixture {
111 CPPUNIT_TEST_SUITE(ActiveSyncsTest);
112 CPPUNIT_TEST(testInstantiate);
113 CPPUNIT_TEST_SUITE_END();
116 void testInstantiate() {
117 boost::shared_ptr<SyncSource> source;
118 source.reset(SyncSource::createTestingSource("contacts", "ActiveSync Address Book", true));
119 source.reset(SyncSource::createTestingSource("events", "ActiveSync Events", true));
120 source.reset(SyncSource::createTestingSource("todos", "ActiveSync Todos", true));
121 source.reset(SyncSource::createTestingSource("memos", "ActiveSync Memos", true));
125 SYNCEVOLUTION_TEST_SUITE_REGISTRATION(ActiveSyncsTest);
127 #endif // ENABLE_UNIT_TESTS
135 * Takes all existing items in the source and writes them into the file,
136 * separated by a blank line. beginSync() with the previous sync key was
139 * Used for testing and thus should better not rely on cached information,
140 * but ActiveSync doesn't offer an independent "list and/or retrieve all items"
141 * operation. Using the cached information implies that we won't find bugs in
142 * the handling of that information.
144 static int DumpItems(ClientTest &client, TestingSyncSource &source, const std::string &file,
145 bool forceBaseReadItem)
147 ActiveSyncSource &eassource = static_cast<ActiveSyncSource &>(source);
148 ofstream out(file.c_str());
150 // find all ActiveSync server IDs: in ActiveSyncCalendarSource,
151 // each server ID might appear multiple times, once for each
152 // recurrence associated with it
153 std::set<std::string> easids;
154 BOOST_FOREACH (const std::string &luid, eassource.getAllItems()) {
155 // slight hack: we know that luids in ActiveSyncSource base
156 // class pass through this method unmodified, so no need to
158 StringPair ids = ActiveSyncCalendarSource::splitLUID(luid);
159 easids.insert(ids.first);
162 BOOST_FOREACH(const std::string &easid, easids) {
164 if (forceBaseReadItem) {
165 // This bypasses the more specialized
166 // ActiveSyncCalendarSource::readItem(), which helps
167 // reveal potential bugs in it. However, it depends on a
168 // working Fetch operation in the ActiveSync server, which
169 // Google doesn't seem to provide (404 error).
170 eassource.ActiveSyncSource::readItem(easid, item);
172 // Normal readItem() works with Google by using the cached
173 // item. However, the source must have done a beginSync()
174 // with empty sync key, because otherwise the cache is
175 // not guaranteed to be complete.
176 eassource.readItem(easid, item);
179 if (!boost::ends_with(item, "\n")) {
186 static TestingSyncSource *createEASSource(const ClientTestConfig::createsource_t &create,
188 const std::string &clientID,
189 int source, bool isSourceA)
191 std::auto_ptr<TestingSyncSource> res(create(client, clientID, source, isSourceA));
193 // Mangle username: if the base username in the config is account
194 // "foo", then source B uses "foo_B", because otherwise it'll end
195 // up sharing change tracking with source A.
197 ActiveSyncSource *eassource = static_cast<ActiveSyncSource *>(res.get());
198 std::string account = eassource->getSyncConfig().getSyncUsername();
200 eassource->getSyncConfig().setSyncUsername(account, true);
203 if (res->getDatabaseID().empty()) {
204 return res.release();
206 // sorry, no database
207 SE_LOG_ERROR(NULL, NULL, "cannot create EAS source for database %s, check config",
208 res->getDatabaseID().c_str());
213 // common settings for all kinds of data
214 static void updateConfigEAS(const RegisterSyncSourceTest */* me */,
215 ClientTestConfig &config,
218 // cannot run tests involving a second database:
219 // wrap orginal source creation, set default database for
220 // database #0 and refuse to return a source for database #1
221 config.m_createSourceA = boost::bind(createEASSource, config.m_createSourceA,
223 config.m_createSourceB = boost::bind(createEASSource, config.m_createSourceB,
226 config.m_dump = boost::bind(DumpItems, _1, _2, _3,
227 type == EAS_ITEM_CONTACT ||
228 // need to read from our cache for Google Calendar,
229 // because it does not support Fetch
230 strcmp(getEnv("CLIENT_TEST_SERVER", ""), "googleeas")
232 config.m_sourceLUIDsAreVolatile = true;
233 // TODO: find out how ActiveSync/Exchange handle children without parent;
234 // at the moment, the child is stored as if it was a stand-alone event
235 // and the RECURRENCE-ID is lost (BMC #22831).
236 config.m_linkedItemsRelaxedSemantic = false;
239 static class ActiveSyncContactTest : public RegisterSyncSourceTest {
241 ActiveSyncContactTest() :
242 RegisterSyncSourceTest("eas_contact", // name of test => Client::Source::eas_contact"
243 "eds_contact" // name of test cases: inherit from EDS, override below
246 virtual void updateConfig(ClientTestConfig &config) const
248 // override default eds_contact test config
249 config.m_type = "eas-contacts";
250 // TODO: provide comprehensive set of vCard 3.0 contacts as they are understood by the ActiveSync library
251 // config.testcases = "testcases/eas_contact.vcf";
253 updateConfigEAS(this, config, EAS_ITEM_CONTACT);
255 } ActiveSyncContactTest;
257 static class ActiveSyncEventTest : public RegisterSyncSourceTest {
259 ActiveSyncEventTest() :
260 RegisterSyncSourceTest("eas_event", "eds_event")
263 virtual void updateConfig(ClientTestConfig &config) const
265 config.m_type = "eas-events";
266 updateConfigEAS(this, config, EAS_ITEM_CALENDAR);
268 } ActiveSyncEventTest;
270 static class ActiveSyncTodoTest : public RegisterSyncSourceTest {
272 ActiveSyncTodoTest() :
273 RegisterSyncSourceTest("eas_task", "eds_task")
276 virtual void updateConfig(ClientTestConfig &config) const
278 config.m_type = "eas-todos";
279 updateConfigEAS(this, config, EAS_ITEM_TODO);
281 } ActiveSyncTodoTest;
283 static class ActiveSyncMemoTest : public RegisterSyncSourceTest {
285 ActiveSyncMemoTest() :
286 RegisterSyncSourceTest("eas_memo", "eds_memo")
289 virtual void updateConfig(ClientTestConfig &config) const
291 config.m_type = "eas-memos";
292 updateConfigEAS(this, config, EAS_ITEM_JOURNAL);
294 } ActiveSyncMemoTest;
296 } // anonymous namespace
298 #endif // ENABLE_ACTIVESYNC