/* * Funambol is a mobile platform developed by Funambol, Inc. * Copyright (C) 2010 Funambol, Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by * the Free Software Foundation with the addition of the following permission * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program 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 General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License * along with this program; if not, see http://www.gnu.org/licenses or write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA. * * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License * version 3, these Appropriate Legal Notices must retain the display of the * "Powered by Funambol" logo. If the display of the logo is not reasonably * feasible for technical reasons, the Appropriate Legal Notices must display * the words "Powered by Funambol". */ package com.funambol.client.test.calendar; import java.io.ByteArrayOutputStream; import java.util.Hashtable; import java.util.Vector; import java.util.Enumeration; import com.funambol.org.json.me.JSONObject; import com.funambol.org.json.me.JSONArray; import com.funambol.sapisync.sapi.SapiHandler; import com.funambol.client.source.AppSyncSource; import com.funambol.client.source.AppSyncSourceManager; import com.funambol.client.test.Robot; import com.funambol.client.test.basic.BasicRobot; import com.funambol.client.test.ClientTestException; import com.funambol.client.configuration.Configuration; import com.funambol.sync.SyncItem; import com.funambol.sync.SyncSource; import com.funambol.sync.ItemStatus; import com.funambol.util.StringUtil; import com.funambol.util.Log; public abstract class CalendarRobot extends Robot { private static final String TAG_LOG = "CalendarRobot"; protected static final char FOLDING_INDENT_CHAR = ' '; protected long currentEventId = -1; protected long incrementalServerItemkey = 10000000; protected String eventAsVcal = null; protected BasicRobot basicRobot; protected AppSyncSourceManager appSourceManager; protected SapiHandler sapiHandler; public CalendarRobot(BasicRobot basicRobot, AppSyncSourceManager appSourceManager) { this.basicRobot = basicRobot; this.appSourceManager = appSourceManager; } public CalendarRobot() { } public void saveEventOnServer(String summary) throws Throwable { SapiHandler sapiHandler = getSapiHandler(); Vector params = new Vector(); // Is this an add or an update? boolean add; String id = findEventIdOnServer(summary); StringBuffer jsonEvent = new StringBuffer(); jsonEvent.append("{"); if (id != null) { jsonEvent.append("\"id\":\"").append(id).append("\","); add = false; } else { add = true; } jsonEvent.append("\"summary\":\"").append(summary).append("\",") .append("\"privacy\":\"public\",") .append("\"dtstart\":\"20090310T160000\",") .append("\"dtend\":\"20090310T170000\",") .append("\"tzdtstart\":\"Europe/London\",") .append("\"tzdtend\":\"Europe/London\"") .append("}"); params.addElement("event=" + jsonEvent.toString()); Log.trace(TAG_LOG, "Save event: " + jsonEvent.toString()); JSONObject resp; if (add) { resp = sapiHandler.query("calendar","eventcreate",params,null,null); } else { resp = sapiHandler.query("calendar","eventmodify",params,null,null); } if (id == null) { id = resp.getString("id"); Log.debug(TAG_LOG, "The new event has id=" + id); } } public void saveEventOnServerAsJSON(String jsonObj) throws Throwable { // Unescape the parameter jsonObj = StringUtil.replaceAll(jsonObj, ""","\""); jsonObj = StringUtil.replaceAll(jsonObj, ",",","); Log.trace(TAG_LOG, "JSON event is: " + jsonObj); JSONObject jsonEvent = new JSONObject(jsonObj); // If the values are not available, an excpetion is thrown String summary = jsonEvent.getString("summary"); Log.trace(TAG_LOG, "summary=" + summary); SapiHandler sapiHandler = getSapiHandler(); Vector params = new Vector(); // Is this an add or an update? String id = findEventIdOnServer(summary); Log.trace(TAG_LOG, "Server id=" + id); boolean add; if (id != null) { jsonEvent.put("id",id); add = false; } else { add = true; } params.addElement("data=" + jsonEvent.toString()); JSONObject resp; if (add) { resp = sapiHandler.query("calendar","eventcreate",params,null,null); } else { resp = sapiHandler.query("calendar","eventmodify",params,null,null); } if (id == null) { id = resp.getString("id"); Log.debug(TAG_LOG, "The new event has id=" + id); } } private String findEventIdOnServer(String summary) throws Throwable { SapiHandler sapiHandler = getSapiHandler(); Vector params = new Vector(); JSONObject range = new JSONObject(); range.put("from","20080101"); range.put("to","20120101"); params.addElement("range="+range.toString()); JSONObject resp = sapiHandler.query("calendar","get",params,null,null); if (resp.has("calendars")) { JSONArray calendars = resp.getJSONArray("calendars"); for(int j=0;j<calendars.length();++j) { JSONObject calendar = calendars.getJSONObject(j); if (calendar.has("events")) { JSONArray events = calendar.getJSONArray("events"); for(int i=0;i<events.length();++i) { JSONObject e = events.getJSONObject(i); String s = e.getString("summary"); if (summary.equals(s)) { String id = e.getString("id"); return id; } } } } } return null; } public void deleteEventOnServer(String summary) throws Throwable { String id = findEventIdOnServer(summary); if (id == null) { throw new ClientTestException("Event not available on server"); } Log.trace(TAG_LOG, "Deleting event on server with key: " + id); SapiHandler sapiHandler = getSapiHandler(); Vector params = new Vector(); JSONObject param = new JSONObject(); param.put("id", id); params.addElement("event="+param.toString()); sapiHandler.query("calendar","eventdelete",params,null,null); } public void deleteAllEventsOnServer() throws Throwable { // Do this via SAPI to increase performance SapiHandler sapiHandler = getSapiHandler(); sapiHandler.query("calendar","reset",null,null,null); } public void checkItemsCountOnServer(int count) throws Throwable { SapiHandler sapiHandler = getSapiHandler(); JSONObject resp = sapiHandler.query("calendar","count",null,null,null); int serverCount = resp.getInt("count"); assertTrue(count, serverCount, "Server events count mismatch"); } public void checkEventsCount(int count) throws Throwable { SyncSource source = getSyncSource(); source.beginSync(SyncSource.FULL_SYNC, false); // Resets the tracker status int itemsCount = 0; SyncItem item = source.getNextItem(); Vector items = new Vector(); while(item != null) { itemsCount++; items.addElement(new ItemStatus(item.getKey(), SyncSource.SUCCESS_STATUS)); item = source.getNextItem(); } source.applyItemsStatus(items); source.endSync(); assertTrue(count, itemsCount, "Events count mismatch"); } public void setEventAsVCal(String vCal) throws Throwable{ String[] sep = new String[]{"\\r\\n"}; String[] parts = StringUtil.split(vCal, sep); ByteArrayOutputStream ostream = new ByteArrayOutputStream(); for (int i=0;i<parts.length;i++){ ostream.write(parts[i].getBytes()); ostream.write("\r\n".getBytes()); } eventAsVcal = ostream.toString(); ostream.close(); } public void setEventFromServer(String vCal) throws Throwable { vCal = StringUtil.replaceAll(vCal, "\\r\\n", "\r\n"); SyncSource source = getSyncSource(); SyncItem item = new SyncItem("guid", "text/x-vcalendar", SyncItem.STATE_NEW, null); item.setContent(vCal.getBytes("UTF-8")); Vector items = new Vector(); items.addElement(item); source.applyChanges(items); } protected AppSyncSourceManager getAppSyncSourceManager() { return appSourceManager; } protected SyncSource getSyncSource() { Enumeration sources = getAppSyncSourceManager().getWorkingSources(); AppSyncSource appSource = null; while(sources.hasMoreElements()) { appSource = (AppSyncSource)sources.nextElement(); if (appSource.getId() == AppSyncSourceManager.EVENTS_ID) { break; } } // We add an item via the SyncSource SyncSource source = appSource.getSyncSource(); return source; } private SapiHandler getSapiHandler() { if (sapiHandler == null) { Configuration configuration = getConfiguration(); sapiHandler = new SapiHandler(StringUtil.extractAddressFromUrl( configuration.getSyncUrl()), configuration.getUsername(), configuration.getPassword()); } return sapiHandler; } public abstract void createEmptyEvent() throws Throwable; public abstract void setEventField(String field, String value) throws Throwable; public abstract void loadEvent(String summary) throws Throwable; public abstract void saveEvent() throws Throwable; public void saveEvent(boolean save) throws Throwable { } public abstract void deleteEvent(String summary) throws Throwable; public abstract void deleteAllEvents() throws Throwable; public abstract void createEmptyRawEvent() throws Throwable; public abstract void setRawEventField(String fieldName, String fieldValue) throws Throwable; public abstract void setRawReminderField(String fieldName, String fieldValue) throws Throwable; public abstract void saveRawEvent() throws Throwable; public abstract void checkRawEventField(String fieldName, String fieldValue) throws Throwable; public abstract void checkRawReminderField(String fieldName, String fieldValue) throws Throwable; public abstract void checkRawEventAsVCal(String vcal) throws Throwable; protected abstract String getCurrentEventVCal() throws Throwable; protected abstract Configuration getConfiguration(); }