davmail/src/test/davmail/caldav/TestCaldav.java

409 lines
21 KiB
Java

/*
* DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
* Copyright (C) 2010 Mickael Guessant
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package davmail.caldav;
import davmail.AbstractDavMailTestCase;
import davmail.DavGateway;
import davmail.Settings;
import davmail.exchange.ExchangeSession;
import davmail.exchange.ExchangeSessionFactory;
import davmail.util.StringUtil;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.util.URIUtil;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.MultiStatus;
import org.apache.jackrabbit.webdav.MultiStatusResponse;
import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
import org.apache.jackrabbit.webdav.client.methods.MoveMethod;
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
import org.apache.jackrabbit.webdav.xml.Namespace;
import org.apache.log4j.Level;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* Test Caldav listener.
*/
public class TestCaldav extends AbstractDavMailTestCase {
class SearchReportMethod extends DavMethodBase {
SearchReportMethod(String path, String stringContent) throws UnsupportedEncodingException {
this(path, stringContent.getBytes("UTF-8"));
}
SearchReportMethod(String path, final byte[] content) {
super(path);
setRequestEntity(new RequestEntity() {
public boolean isRepeatable() {
return true;
}
public void writeRequest(OutputStream outputStream) throws IOException {
outputStream.write(content);
}
public long getContentLength() {
return content.length;
}
public String getContentType() {
return "text/xml;charset=UTF-8";
}
});
}
@Override
public String getName() {
return "REPORT";
}
@Override
protected boolean isSuccess(int statusCode) {
return statusCode == HttpStatus.SC_MULTI_STATUS;
}
}
HttpClient httpClient;
@Override
public void setUp() throws IOException {
super.setUp();
if (httpClient == null) {
// start gateway
DavGateway.start();
httpClient = new HttpClient();
HostConfiguration hostConfig = httpClient.getHostConfiguration();
URI httpURI = new URI("http://localhost:" + Settings.getProperty("davmail.caldavPort"), true);
hostConfig.setHost(httpURI);
AuthScope authScope = new AuthScope(null, -1);
httpClient.getState().setCredentials(authScope, new NTCredentials(Settings.getProperty("davmail.username"), Settings.getProperty("davmail.password"), "", ""));
}
if (session == null) {
session = ExchangeSessionFactory.getInstance(Settings.getProperty("davmail.username"), Settings.getProperty("davmail.password"));
}
}
public void testGetRoot() throws IOException {
GetMethod method = new GetMethod("/");
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_OK, method.getStatusCode());
}
public void testGetUserRoot() throws IOException {
GetMethod method = new GetMethod("/users/" + session.getEmail() + '/');
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_OK, method.getStatusCode());
}
public void testGetCalendar() throws IOException {
GetMethod method = new GetMethod("/users/" + session.getEmail() + "/calendar/");
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_OK, method.getStatusCode());
}
public void testGetInbox() throws IOException {
GetMethod method = new GetMethod("/users/" + session.getEmail() + "/inbox/");
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_OK, method.getStatusCode());
}
public void testGetContacts() throws IOException {
GetMethod method = new GetMethod("/users/" + session.getEmail() + "/contacts/");
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_OK, method.getStatusCode());
}
public void testPropfindCalendar() throws IOException {
Settings.setLoggingLevel("httpclient.wire", Level.DEBUG);
PropFindMethod method = new PropFindMethod("/users/" + session.getEmail() + "/calendar/", null, 1);
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
}
public void testGetOtherUserCalendar() throws IOException {
Settings.setLoggingLevel("httpclient.wire", Level.DEBUG);
PropFindMethod method = new PropFindMethod("/principals/users/" + Settings.getProperty("davmail.to") + "/calendar/");
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_OK, method.getStatusCode());
}
public void testReportCalendar() throws IOException, DavException {
SimpleDateFormat formatter = ExchangeSession.getZuluDateFormat();
Calendar cal = Calendar.getInstance();
Date end = cal.getTime();
cal.add(Calendar.MONTH, -1);
Date start = cal.getTime();
StringBuilder buffer = new StringBuilder();
buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
buffer.append("<C:calendar-query xmlns:C=\"urn:ietf:params:xml:ns:caldav\" xmlns:D=\"DAV:\">");
buffer.append("<D:prop>");
buffer.append("<C:calendar-data/>");
buffer.append("</D:prop>");
buffer.append("<C:comp-filter name=\"VCALENDAR\">");
buffer.append("<C:comp-filter name=\"VEVENT\">");
buffer.append("<C:time-range start=\"").append(formatter.format(start)).append("\" end=\"").append(formatter.format(end)).append("\"/>");
//buffer.append("<C:time-range start=\"").append(formatter.format(start)).append("\"/>");
buffer.append("</C:comp-filter>");
buffer.append("</C:comp-filter>");
buffer.append("<C:filter>");
buffer.append("</C:filter>");
buffer.append("</C:calendar-query>");
SearchReportMethod method = new SearchReportMethod("/users/" + session.getEmail() + "/calendar/", buffer.toString());
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
MultiStatus multiStatus = method.getResponseBodyAsMultiStatus();
MultiStatusResponse[] responses = multiStatus.getResponses();
ExchangeSession.Condition dateCondition = session.and(
session.gt("dtstart", session.formatSearchDate(start)),
session.lt("dtend", session.formatSearchDate(end))
);
List<ExchangeSession.Event> events = session.searchEvents("/users/" + session.getEmail() + "/calendar/",
session.or(session.isEqualTo("instancetype", 1),
session.and(session.isEqualTo("instancetype", 0), dateCondition))
);
assertEquals(events.size(), responses.length);
}
public void testReportInbox() throws IOException, DavException {
StringBuilder buffer = new StringBuilder();
buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
buffer.append("<C:calendar-query xmlns:C=\"urn:ietf:params:xml:ns:caldav\" xmlns:D=\"DAV:\">");
buffer.append("<D:prop>");
buffer.append("<C:calendar-data/>");
buffer.append("</D:prop>");
buffer.append("<C:filter>");
buffer.append("</C:filter>");
buffer.append("</C:calendar-query>");
SearchReportMethod method = new SearchReportMethod("/users/" + session.getEmail() + "/inbox/", buffer.toString());
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
MultiStatus multiStatus = method.getResponseBodyAsMultiStatus();
MultiStatusResponse[] responses = multiStatus.getResponses();
/*List<ExchangeSession.Event> events = session.searchEvents("/users/" + session.getEmail() + "/calendar/",
session.or(session.isEqualTo("instancetype", 1),
session.and(session.isEqualTo("instancetype", 0), dateCondition))
);*/
//assertEquals(events.size(), responses.length);
}
public void testReportTasks() throws IOException, DavException {
StringBuilder buffer = new StringBuilder();
buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
buffer.append("<C:calendar-query xmlns:C=\"urn:ietf:params:xml:ns:caldav\" xmlns:D=\"DAV:\">");
buffer.append("<D:prop>");
buffer.append("<C:calendar-data/>");
buffer.append("</D:prop>");
buffer.append("<C:comp-filter name=\"VCALENDAR\">");
buffer.append("<C:comp-filter name=\"VTODO\"/>");
buffer.append("</C:comp-filter>");
buffer.append("<C:filter>");
buffer.append("</C:filter>");
buffer.append("</C:calendar-query>");
SearchReportMethod method = new SearchReportMethod("/users/" + session.getEmail() + "/calendar/", buffer.toString());
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
MultiStatus multiStatus = method.getResponseBodyAsMultiStatus();
MultiStatusResponse[] responses = multiStatus.getResponses();
}
public void testReportEventsOnly() throws IOException, DavException {
StringBuilder buffer = new StringBuilder();
buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
buffer.append("<C:calendar-query xmlns:C=\"urn:ietf:params:xml:ns:caldav\" xmlns:D=\"DAV:\">");
buffer.append("<D:prop>");
buffer.append("<C:calendar-data/>");
buffer.append("</D:prop>");
buffer.append("<C:comp-filter name=\"VCALENDAR\">");
buffer.append("<C:comp-filter name=\"VEVENT\"/>");
buffer.append("</C:comp-filter>");
buffer.append("<C:filter>");
buffer.append("</C:filter>");
buffer.append("</C:calendar-query>");
SearchReportMethod method = new SearchReportMethod("/users/" + session.getEmail() + "/calendar/", buffer.toString());
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
MultiStatus multiStatus = method.getResponseBodyAsMultiStatus();
MultiStatusResponse[] responses = multiStatus.getResponses();
}
public void testCreateCalendar() throws IOException {
String folderName = "test & accentué";
String encodedFolderpath = URIUtil.encodePath("/users/" + session.getEmail() + "/calendar/" + folderName + '/');
// first delete calendar
session.deleteFolder("calendar/" + folderName);
String body =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
" <C:mkcalendar xmlns:D=\"DAV:\"\n" +
" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">\n" +
" <D:set>\n" +
" <D:prop>\n" +
" <D:displayname>" + StringUtil.xmlEncode(folderName) + "</D:displayname>\n" +
" <C:calendar-description xml:lang=\"en\">Calendar description</C:calendar-description>\n" +
" <C:supported-calendar-component-set>\n" +
" <C:comp name=\"VEVENT\"/>\n" +
" </C:supported-calendar-component-set>\n" +
" </D:prop>\n" +
" </D:set>\n" +
" </C:mkcalendar>";
SearchReportMethod method = new SearchReportMethod(encodedFolderpath, body) {
@Override
public String getName() {
return "MKCALENDAR";
}
};
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_CREATED, method.getStatusCode());
GetMethod getMethod = new GetMethod(encodedFolderpath);
httpClient.executeMethod(getMethod);
assertEquals(HttpStatus.SC_OK, getMethod.getStatusCode());
}
public void testPropfindPrincipal() throws IOException, DavException {
//Settings.setLoggingLevel("httpclient.wire", Level.DEBUG);
DavPropertyNameSet davPropertyNameSet = new DavPropertyNameSet();
davPropertyNameSet.add(DavPropertyName.create("calendar-home-set", Namespace.getNamespace("urn:ietf:params:xml:ns:caldav")));
davPropertyNameSet.add(DavPropertyName.create("calendar-user-address-set", Namespace.getNamespace("urn:ietf:params:xml:ns:caldav")));
davPropertyNameSet.add(DavPropertyName.create("schedule-inbox-URL", Namespace.getNamespace("urn:ietf:params:xml:ns:caldav")));
davPropertyNameSet.add(DavPropertyName.create("schedule-outbox-URL", Namespace.getNamespace("urn:ietf:params:xml:ns:caldav")));
PropFindMethod method = new PropFindMethod("/principals/users/" + session.getEmail() + "/", davPropertyNameSet, 0);
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
MultiStatus multiStatus = method.getResponseBodyAsMultiStatus();
MultiStatusResponse[] responses = multiStatus.getResponses();
assertEquals(1, responses.length);
}
public void testRenameCalendar() throws IOException {
String folderName = "testcalendarfolder";
String encodedFolderpath = URIUtil.encodePath("/users/" + session.getEmail() + "/calendar/" + folderName + '/');
// first delete calendar
session.deleteFolder("calendar/" + folderName);
String body =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
" <C:mkcalendar xmlns:D=\"DAV:\"\n" +
" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">\n" +
" <D:set>\n" +
" <D:prop>\n" +
" <D:displayname>" + StringUtil.xmlEncode(folderName) + "</D:displayname>\n" +
" <C:calendar-description xml:lang=\"en\">Calendar description</C:calendar-description>\n" +
" <C:supported-calendar-component-set>\n" +
" <C:comp name=\"VEVENT\"/>\n" +
" </C:supported-calendar-component-set>\n" +
" </D:prop>\n" +
" </D:set>\n" +
" </C:mkcalendar>";
SearchReportMethod method = new SearchReportMethod(encodedFolderpath, body) {
@Override
public String getName() {
return "MKCALENDAR";
}
};
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_CREATED, method.getStatusCode());
MoveMethod moveMethod = new MoveMethod(encodedFolderpath, "http://localhost:" + Settings.getProperty("davmail.caldavPort")+"/users/" + session.getEmail() + "/movedcalendarfolder", true);
httpClient.executeMethod(moveMethod);
}
public void testRenameMainCalendar() throws IOException {
MoveMethod moveMethod = new MoveMethod("/users/" + session.getEmail() + "/Calendrierzzz", "http://localhost:" + Settings.getProperty("davmail.caldavPort")+"/users/" + session.getEmail() + "/Calendrier", true);
httpClient.executeMethod(moveMethod);
}
public void testWellKnown() throws IOException, DavException {
DavPropertyNameSet davPropertyNameSet = new DavPropertyNameSet();
davPropertyNameSet.add(DavPropertyName.create("current-user-principal", Namespace.getNamespace("DAV:")));
davPropertyNameSet.add(DavPropertyName.create("principal-URL", Namespace.getNamespace("DAV:")));
davPropertyNameSet.add(DavPropertyName.create("resourcetype", Namespace.getNamespace("DAV:")));
PropFindMethod method = new PropFindMethod("/.well-known/caldav", davPropertyNameSet, 0);
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_MOVED_PERMANENTLY, method.getStatusCode());
}
public void testPrincipalUrl() throws IOException, DavException {
DavPropertyNameSet davPropertyNameSet = new DavPropertyNameSet();
davPropertyNameSet.add(DavPropertyName.create("principal-URL", Namespace.getNamespace("DAV:")));
PropFindMethod method = new PropFindMethod("/principals/users/"+session.getEmail(), davPropertyNameSet, 0);
httpClient.executeMethod(method);
method.getResponseBodyAsMultiStatus();
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
}
public void testPropfindRoot() throws IOException, DavException {
DavPropertyNameSet davPropertyNameSet = new DavPropertyNameSet();
davPropertyNameSet.add(DavPropertyName.create("current-user-principal", Namespace.getNamespace("DAV:")));
davPropertyNameSet.add(DavPropertyName.create("principal-URL", Namespace.getNamespace("DAV:")));
davPropertyNameSet.add(DavPropertyName.create("resourcetype", Namespace.getNamespace("DAV:")));
PropFindMethod method = new PropFindMethod("/", davPropertyNameSet, 0);
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
method.getResponseBodyAsMultiStatus();
}
public void testPropfindAddressBook() throws IOException, DavException {
DavPropertyNameSet davPropertyNameSet = new DavPropertyNameSet();
//davPropertyNameSet.add(DavPropertyName.create("getctag", Namespace.getNamespace("http://calendarserver.org/ns/")));
davPropertyNameSet.add(DavPropertyName.create("getetag", Namespace.getNamespace("DAV:")));
PropFindMethod method = new PropFindMethod("/users/" + session.getEmail()+"/addressbook/", davPropertyNameSet, 1);
httpClient.getParams().setParameter(HttpMethodParams.USER_AGENT, "Address%20Book/883 CFNetwork/454.12.4 Darwin/10.8.0 (i386) (MacBookPro3%2C1)");
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
method.getResponseBodyAsMultiStatus();
}
public void testPropfindPublicPrincipal() throws IOException, DavException {
//Settings.setLoggingLevel("httpclient.wire", Level.DEBUG);
DavPropertyNameSet davPropertyNameSet = new DavPropertyNameSet();
davPropertyNameSet.add(DavPropertyName.create("calendar-home-set", Namespace.getNamespace("urn:ietf:params:xml:ns:caldav")));
davPropertyNameSet.add(DavPropertyName.create("calendar-user-address-set", Namespace.getNamespace("urn:ietf:params:xml:ns:caldav")));
davPropertyNameSet.add(DavPropertyName.create("schedule-inbox-URL", Namespace.getNamespace("urn:ietf:params:xml:ns:caldav")));
davPropertyNameSet.add(DavPropertyName.create("schedule-outbox-URL", Namespace.getNamespace("urn:ietf:params:xml:ns:caldav")));
PropFindMethod method = new PropFindMethod("/principals/public/testcalendar/", davPropertyNameSet, 0);
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
MultiStatus multiStatus = method.getResponseBodyAsMultiStatus();
MultiStatusResponse[] responses = multiStatus.getResponses();
assertEquals(1, responses.length);
}
}