use of com.zimbra.soap.mail.message.SearchRequest in project zm-mailbox by Zimbra.
the class TestJaxb method testAcceptSeriesDeclineInstance.
/**
* Bug 94018. Accepting series, then declining single instance leads to inconsistent display of attendee
* status for organizer copy for the declined instance.
* Test steps:
* 1. Invite 2 users to a daily meeting.
* 2. User 1 replies, accepting the daily meeting.
* 3. User 1 replies again, declining one of the instances in the daily meeting.
* 4. User 2 replies tentatively accepting the daily meeting.
*
* At the end of this, check that an exception has been created. Check that that exception registers
* the decline from user 1 AND the tentative acceptance from user2 that arrived later.
*/
@Test
public void testAcceptSeriesDeclineInstance() throws Exception {
TestUtil.createAccount(ORGANIZER);
TestUtil.createAccount(ATTENDEE1);
TestUtil.createAccount(ATTENDEE2);
String subject = NAME_PREFIX + " Daily";
ZMailbox organizerBox = TestUtil.getZMailbox(ORGANIZER);
ZMailbox attendeeBox = TestUtil.getZMailbox(ATTENDEE1);
ZMailbox attendee2Box = TestUtil.getZMailbox(ATTENDEE2);
String organizerEmail = organizerBox.getName();
// Create and send the daily meeting
InviteComponent inviteComp = new InviteComponent();
inviteComp.addAttendee(CalendarAttendee.createForAddressDisplaynameRolePartstatRsvp(attendeeBox.getName(), getCN(attendeeBox), "REQ", "NE", true));
inviteComp.addAttendee(CalendarAttendee.createForAddressDisplaynameRolePartstatRsvp(attendee2Box.getName(), getCN(attendee2Box), "REQ", "NE", true));
inviteComp.setStatus("CONF");
inviteComp.setFreeBusy("B");
inviteComp.setCalClass("PUB");
inviteComp.setTransparency("O");
inviteComp.setIsDraft(false);
inviteComp.setIsAllDay(false);
inviteComp.setDtStart(DtTimeInfo.createForDatetimeAndZone("20161008T130000", "Europe/London"));
inviteComp.setDtEnd(DtTimeInfo.createForDatetimeAndZone("20161008T140000", "Europe/London"));
inviteComp.setName(subject);
inviteComp.setLocation("room 101");
inviteComp.setOrganizer(CalOrganizer.createForAddress(organizerEmail));
inviteComp.setRecurrence(RecurrenceInfo.create(AddRecurrenceInfo.create(SimpleRepeatingRule.createFromFrequencyAndInterval("DAI", IntervalRule.create(1)))));
InvitationInfo invite = new InvitationInfo();
invite.setInviteComponent(inviteComp);
EmailAddrInfo attendeeAddr = EmailAddrInfo.createForAddressPersonalAndAddressType(attendeeBox.getName(), getCN(attendeeBox), "t");
EmailAddrInfo attendeeAddr2 = EmailAddrInfo.createForAddressPersonalAndAddressType(attendee2Box.getName(), getCN(attendee2Box), "t");
MimePartInfo mimePart = MimePartInfo.createForContentType("multipart/alternative");
mimePart.addMimePart(MimePartInfo.createForContentTypeAndContent("text/plain", "invite body"));
mimePart.addMimePart(MimePartInfo.createForContentTypeAndContent("text/html", "<html><body><p><b>invite</b> body</p></body></html>"));
Msg msg = new Msg();
msg.setFolderId("10");
msg.setInvite(invite);
msg.addEmailAddress(attendeeAddr);
msg.addEmailAddress(attendeeAddr2);
msg.setSubject(subject);
msg.setMimePart(mimePart);
CreateAppointmentRequest createSeriesRequest = CreateAppointmentRequest.create(msg);
CreateAppointmentResponse caResp = organizerBox.invokeJaxb(createSeriesRequest);
Assert.assertNotNull("JAXB CreateAppointmentResponse object", caResp);
Assert.assertNotNull("JAXB CreateAppointmentResponse calItemId", caResp.getCalItemId());
Assert.assertNotNull("JAXB CreateAppointmentResponse invId", caResp.getCalInvId());
Assert.assertNotNull("JAXB CreateAppointmentResponse modified sequence ms", caResp.getModifiedSequence());
Assert.assertNotNull("JAXB CreateAppointmentResponse rev", caResp.getRevision());
ZMessage seriesInviteMsg = TestUtil.waitForMessage(attendeeBox, subject);
Assert.assertNotNull("ZMessage for series invite", seriesInviteMsg);
ZInvite seriesInvite = seriesInviteMsg.getInvite();
Assert.assertNotNull("ZInvite for series invite", seriesInvite);
// User 1 accepts the daily meeting
ZMessage seriesAcceptMsg = sendInviteReplyToSeries(attendeeBox, organizerBox, seriesInviteMsg.getId(), subject, "ACCEPT");
Assert.assertNotNull("ZMessage for series accept", seriesAcceptMsg);
// User 1 declines one instance of the daily meeting
SendInviteReplyRequest sirReq = new SendInviteReplyRequest(seriesInviteMsg.getId(), 0, /* componentNum */
"DECLINE");
sirReq.setIdentityId(attendeeBox.getAccountInfo(false).getId());
sirReq.setExceptionId(DtTimeInfo.createForDatetimeAndZone("20161011T130000", "Europe/London"));
sirReq.setUpdateOrganizer(true);
attendeeAddr.setAddressType("f");
mimePart = MimePartInfo.createForContentType("multipart/alternative");
mimePart.addMimePart(MimePartInfo.createForContentTypeAndContent("text/plain", "I won't attend on Tuesday, October 11, 2016."));
mimePart.addMimePart(MimePartInfo.createForContentTypeAndContent("text/html", "<html><body><p><b>I won't attend on Tuesday, October 11, 2016</b></p></body></html>"));
msg = new Msg();
msg.setReplyType("r");
msg.setIdentityId(attendeeBox.getAccountInfo(false).getId());
EmailAddrInfo orgAddr = EmailAddrInfo.createForAddressPersonalAndAddressType(organizerBox.getName(), organizerBox.getName(), "t");
msg.addEmailAddress(orgAddr);
msg.addEmailAddress(attendeeAddr);
String declineSubject = "Decline: " + subject;
msg.setSubject(declineSubject);
msg.setMimePart(mimePart);
sirReq.setMsg(msg);
SendInviteReplyResponse sirResp = attendeeBox.invokeJaxb(sirReq);
Assert.assertNotNull("JAXB SendInviteReplyResponse object", sirResp);
ZMessage instanceDeclineMsg = TestUtil.waitForMessage(organizerBox, String.format("subject:\"%s\"", declineSubject));
Assert.assertNotNull("ZMessage for series accept", instanceDeclineMsg);
seriesInviteMsg = TestUtil.waitForMessage(attendee2Box, subject);
Assert.assertNotNull("ZMessage for series invite", seriesInviteMsg);
seriesInvite = seriesInviteMsg.getInvite();
Assert.assertNotNull("ZInvite for series invite", seriesInvite);
// User 2 tentatively accepts the daily meeting
ZMessage seriesTentativeMsg = sendInviteReplyToSeries(attendee2Box, organizerBox, seriesInviteMsg.getId(), subject, "TENTATIVE");
Assert.assertNotNull("ZMessage for series tentative", seriesTentativeMsg);
// Search for the organizer's calendar entry
SearchRequest sReq = new SearchRequest();
sReq.setSearchTypes(ZSearchParams.TYPE_APPOINTMENT);
sReq.setCalItemExpandStart(ymdStringToDate("2016-10-09"));
sReq.setCalItemExpandEnd(ymdStringToDate("2016-10-14"));
sReq.setQuery((String.format("in:Calendar and subject:%s", subject)));
SearchResponse sResp = organizerBox.invokeJaxb(sReq);
List<SearchHit> hits = sResp.getSearchHits();
Assert.assertNotNull("Organizer calendar Search hits at end", hits);
Assert.assertEquals("Num Organizer calendar hits at end", 1, hits.size());
SearchHit orgCalHit = hits.get(0);
Assert.assertTrue(orgCalHit instanceof AppointmentHitInfo);
AppointmentHitInfo orgApptHit = (AppointmentHitInfo) orgCalHit;
String seriesInviteId = orgApptHit.getInvId();
Assert.assertNotNull("Organizer Calendar at end - series invite id", seriesInviteId);
List<InstanceDataInfo> instances = orgApptHit.getInstances();
Assert.assertNotNull("Organizer Calendar at end - instances in expansion", instances);
Assert.assertEquals("Organizer Calendar at end - number of instances in expansion", 5, instances.size());
// The third entry in the list should be for the exception
String exceptionInviteId = instances.get(2).getInvId();
Assert.assertNotNull("Organizer Calendar at end - exception invite id", exceptionInviteId);
String exceptionRidZ = instances.get(2).getRecurIdZ();
Assert.assertNotNull("Organizer Calendar at end - exception invite RecurIdZ", exceptionRidZ);
// Do a GetMsg for the exception in the Organizer's calendar
MsgSpec gmeMsgSpec = new MsgSpec(exceptionInviteId);
gmeMsgSpec.setRecurIdZ(exceptionRidZ);
GetMsgRequest gmeReq = new GetMsgRequest(gmeMsgSpec);
GetMsgResponse gmeResp = organizerBox.invokeJaxb(gmeReq);
List<InviteComponentWithGroupInfo> eInviteComps = gmeResp.getMsg().getInvite().getInviteComponents();
Assert.assertEquals("Organizer Calendar at end - number of components in exception", 1, eInviteComps.size());
List<CalendarAttendeeWithGroupInfo> eAttendees = eInviteComps.get(0).getAttendees();
Assert.assertEquals("Organizer Calendar at end - number of attendees in exception", 2, eAttendees.size());
for (CalendarAttendeeWithGroupInfo eAttendee : eAttendees) {
String addr = eAttendee.getAddress();
String ptst = eAttendee.getPartStat();
if (addr.equals(attendeeBox.getName())) {
Assert.assertEquals("exception attendee1 partstat", "DE", ptst);
} else if (addr.equals(attendee2Box.getName())) {
Assert.assertEquals("exception attendee2 partstat", "TE", ptst);
} else {
Assert.fail(String.format("Unexpected attendee in exception [%s]", addr));
}
}
// Do a GetMsg for the series in the Organizer's calendar
MsgSpec gmsMsgSpec = new MsgSpec(seriesInviteId);
GetMsgRequest gmsReq = new GetMsgRequest(gmsMsgSpec);
GetMsgResponse gmsResp = organizerBox.invokeJaxb(gmsReq);
List<InviteComponentWithGroupInfo> sInviteComps = gmsResp.getMsg().getInvite().getInviteComponents();
Assert.assertEquals("Organizer Calendar at end - number of components in series", 1, sInviteComps.size());
List<CalendarAttendeeWithGroupInfo> sAttendees = sInviteComps.get(0).getAttendees();
Assert.assertEquals("Organizer Calendar at end - number of attendees in exception", 2, sAttendees.size());
for (CalendarAttendeeWithGroupInfo sAttendee : sAttendees) {
String addr = sAttendee.getAddress();
String ptst = sAttendee.getPartStat();
if (addr.equals(attendeeBox.getName())) {
Assert.assertEquals("exception attendee1 partstat", "AC", ptst);
} else if (addr.equals(attendee2Box.getName())) {
Assert.assertEquals("exception attendee2 partstat", "TE", ptst);
} else {
Assert.fail(String.format("Unexpected attendee in exception [%s]", addr));
}
}
}
use of com.zimbra.soap.mail.message.SearchRequest in project zm-mailbox by Zimbra.
the class TestExpandGroupInfo method searchConversation.
@Test
public void searchConversation() throws Exception {
// send a to acct, recipient is a group
String SUBJECT = getTestName();
sendMsg(acct, group.getName(), SUBJECT, "blah");
SoapTransport transport = authUser(acct.getName());
SearchRequest searchReq = new SearchRequest();
searchReq.setSearchTypes(MailItem.Type.CONVERSATION.toString());
searchReq.setQuery(String.format("in:inbox and subject:%s", SUBJECT));
SearchResponse searchResp = invokeJaxb(transport, searchReq);
List<SearchHit> searchHits = searchResp.getSearchHits();
assertEquals(1, searchHits.size());
SearchHit searchHit = searchHits.get(0);
String convId = searchHit.getId();
SearchConvRequest searchConvReq = new SearchConvRequest(convId);
searchConvReq.setNeedCanExpand(Boolean.TRUE);
searchConvReq.setFetch(SearchParams.ExpandResults.ALL.toString());
SearchConvResponse searchConvResp = invokeJaxb(transport, searchConvReq);
List<MessageHitInfo> hits = searchConvResp.getMessages();
// 2 - one in inbox, one in sent folder
assertEquals(2, hits.size());
verifyGroupInfo(hits.get(0), Boolean.TRUE, Boolean.TRUE);
verifyGroupInfo(hits.get(1), Boolean.TRUE, Boolean.TRUE);
}
use of com.zimbra.soap.mail.message.SearchRequest in project zm-mailbox by Zimbra.
the class Search method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Mailbox mbox = getRequestedMailbox(zsc);
Account account = getRequestedAccount(zsc);
OperationContext octxt = getOperationContext(zsc, context);
fixBooleanRecipients(request);
SearchRequest req = JaxbUtil.elementToJaxb(request);
if (Objects.firstNonNull(req.getWarmup(), false)) {
mbox.index.getIndexStore().warmup();
return zsc.createElement(MailConstants.SEARCH_RESPONSE);
}
SearchParams params = SearchParams.parse(req, zsc, account.getPrefMailInitialSearch());
if (params.getLocale() == null) {
params.setLocale(mbox.getAccount().getLocale());
}
if (params.inDumpster() && params.getTypes().contains(MailItem.Type.CONVERSATION)) {
throw ServiceException.INVALID_REQUEST("cannot search for conversations in dumpster", null);
}
if (LC.calendar_cache_enabled.booleanValue()) {
List<String> apptFolderIds = getFolderIdListIfSimpleAppointmentsQuery(params, zsc);
if (apptFolderIds != null) {
Account authAcct = getAuthenticatedAccount(zsc);
Element response = zsc.createElement(MailConstants.SEARCH_RESPONSE);
runSimpleAppointmentQuery(response, params, octxt, zsc, authAcct, mbox, apptFolderIds);
return response;
}
}
ZimbraQueryResults results = mbox.index.search(zsc.getResponseProtocol(), octxt, params);
try {
// create the XML response Element
Element response = zsc.createElement(MailConstants.SEARCH_RESPONSE);
// must use results.getSortBy() because the results might have ignored our sortBy
// request and used something else...
response.addAttribute(MailConstants.A_SORTBY, results.getSortBy().toString());
putHits(zsc, octxt, response, results, params);
return response;
} finally {
Closeables.closeQuietly(results);
}
}
use of com.zimbra.soap.mail.message.SearchRequest in project zm-mailbox by Zimbra.
the class TestCalDav method testXBusyMacAttach.
@Test
public void testXBusyMacAttach() throws ServiceException, IOException {
Account dav1 = users[1].create();
String contactsFolderUrl = getFolderUrl(dav1, "Contacts");
HttpClient client = new HttpClient();
PostMethod postMethod = new PostMethod(contactsFolderUrl);
addBasicAuthHeaderForUser(postMethod, dav1);
postMethod.addRequestHeader("Content-Type", "text/vcard");
postMethod.setRequestEntity(new ByteArrayRequestEntity(smallBusyMacAttach.getBytes(), MimeConstants.CT_TEXT_VCARD));
HttpMethodExecutor exe = HttpMethodExecutor.execute(client, postMethod, HttpStatus.SC_CREATED);
String location = null;
for (Header hdr : exe.respHeaders) {
if ("Location".equals(hdr.getName())) {
location = hdr.getValue();
}
}
assertNotNull("Location Header returned when creating", location);
String url = String.format("%s%s", contactsFolderUrl, location.substring(location.lastIndexOf('/') + 1));
GetMethod getMethod = new GetMethod(url);
addBasicAuthHeaderForUser(getMethod, dav1);
getMethod.addRequestHeader("Content-Type", "text/vcard");
exe = HttpMethodExecutor.execute(client, getMethod, HttpStatus.SC_OK);
String respBody = new String(exe.responseBodyBytes, MimeConstants.P_CHARSET_UTF8);
String[] expecteds = { "\r\nX-BUSYMAC-ATTACH;X-FILENAME=favicon.ico;ENCODING=B:AAABAAEAEBAAAAEAIABoBA\r\n", "\r\n AAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAABMLAAATCwAAAAAAAAAAAAAAAAAAw4cAY8\r\n", "\r\nX-BUSYMAC-MODIFIED-BY:Gren Elliot\r\n", "\r\nX-CUSTOM:one two three four five six seven eight nine ten eleven twelve t\r\n hirteen fourteen fifteen", "\r\nX-CUSTOM:Here are my simple\\Nmultiline\\Nnotes\r\n", "\r\nX-CUSTOM;TYPE=pref:semi-colon\\;seperated\\;\"stuff\"\\;here\r\n", "\r\nX-CUSTOM:comma\\,\"stuff\"\\,'there'\\,too\r\n", "\r\nX-HOBBY:my backslash\\\\ hobbies\r\n", "\r\nX-CREATED:2015-04-05T09:50:44Z\r\n" };
for (String expected : expecteds) {
assertTrue(String.format("GET should contain '%s'\nBODY=%s", expected, respBody), respBody.contains(expected));
}
SearchRequest searchRequest = new SearchRequest();
searchRequest.setSortBy("dateDesc");
searchRequest.setLimit(8);
searchRequest.setSearchTypes("contact");
searchRequest.setQuery("in:Contacts");
ZMailbox mbox = users[1].getZMailbox();
SearchResponse searchResp = mbox.invokeJaxb(searchRequest);
assertNotNull("JAXB SearchResponse object", searchResp);
List<SearchHit> hits = searchResp.getSearchHits();
assertNotNull("JAXB SearchResponse hits", hits);
assertEquals("JAXB SearchResponse hits", 1, hits.size());
}
use of com.zimbra.soap.mail.message.SearchRequest in project zm-mailbox by Zimbra.
the class TestCalDav method testAppleStyleGroup.
@Test
public void testAppleStyleGroup() throws ServiceException, IOException {
Account dav1 = users[1].create();
String contactsFolderUrl = getFolderUrl(dav1, "Contacts");
HttpClient client = new HttpClient();
PostMethod postMethod = new PostMethod(contactsFolderUrl);
addBasicAuthHeaderForUser(postMethod, dav1);
postMethod.addRequestHeader("Content-Type", "text/vcard");
postMethod.setRequestEntity(new ByteArrayRequestEntity(rachelVcard.getBytes(), MimeConstants.CT_TEXT_VCARD));
HttpMethodExecutor.execute(client, postMethod, HttpStatus.SC_CREATED);
postMethod = new PostMethod(contactsFolderUrl);
addBasicAuthHeaderForUser(postMethod, dav1);
postMethod.addRequestHeader("Content-Type", "text/vcard");
postMethod.setRequestEntity(new ByteArrayRequestEntity(blueGroupCreate.getBytes(), MimeConstants.CT_TEXT_VCARD));
HttpMethodExecutor exe = HttpMethodExecutor.execute(client, postMethod, HttpStatus.SC_CREATED);
String groupLocation = null;
for (Header hdr : exe.respHeaders) {
if ("Location".equals(hdr.getName())) {
groupLocation = hdr.getValue();
}
}
assertNotNull("Location Header returned when creating Group", groupLocation);
postMethod = new PostMethod(contactsFolderUrl);
addBasicAuthHeaderForUser(postMethod, dav1);
postMethod.addRequestHeader("Content-Type", "text/vcard");
postMethod.setRequestEntity(new ByteArrayRequestEntity(parisVcard.getBytes(), MimeConstants.CT_TEXT_VCARD));
HttpMethodExecutor.execute(client, postMethod, HttpStatus.SC_CREATED);
String url = String.format("%s%s", contactsFolderUrl, "F53A6F96-566F-46CC-8D48-A5263FAB5E38.vcf");
PutMethod putMethod = new PutMethod(url);
addBasicAuthHeaderForUser(putMethod, dav1);
putMethod.addRequestHeader("Content-Type", "text/vcard");
putMethod.setRequestEntity(new ByteArrayRequestEntity(blueGroupModify.getBytes(), MimeConstants.CT_TEXT_VCARD));
HttpMethodExecutor.execute(client, putMethod, HttpStatus.SC_NO_CONTENT);
GetMethod getMethod = new GetMethod(url);
addBasicAuthHeaderForUser(getMethod, dav1);
getMethod.addRequestHeader("Content-Type", "text/vcard");
exe = HttpMethodExecutor.execute(client, getMethod, HttpStatus.SC_OK);
String respBody = new String(exe.responseBodyBytes, MimeConstants.P_CHARSET_UTF8);
String[] expecteds = { "X-ADDRESSBOOKSERVER-KIND:group", "X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:BE43F16D-336E-4C3E-BAE6-22B8F245A986", "X-ADDRESSBOOKSERVER-MEMBER:urn:uuid:07139DE2-EA7B-46CB-A970-C4DF7F72D9AE" };
for (String expected : expecteds) {
assertTrue(String.format("GET should contain '%s'\nBODY=%s", expected, respBody), respBody.contains(expected));
}
// members are actually stored in a different way. Make sure it isn't a fluke
// that the GET response contained the correct members by checking that the members
// appear where expected in a search hit.
SearchRequest searchRequest = new SearchRequest();
searchRequest.setSortBy("dateDesc");
searchRequest.setLimit(8);
searchRequest.setSearchTypes("contact");
searchRequest.setQuery("in:Contacts");
ZMailbox mbox = users[1].getZMailbox();
SearchResponse searchResp = mbox.invokeJaxb(searchRequest);
assertNotNull("JAXB SearchResponse object", searchResp);
List<SearchHit> hits = searchResp.getSearchHits();
assertNotNull("JAXB SearchResponse hits", hits);
assertEquals("JAXB SearchResponse hits", 3, hits.size());
boolean seenGroup = false;
for (SearchHit hit : hits) {
ContactInfo contactInfo = (ContactInfo) hit;
if ("BlueGroup".equals(contactInfo.getFileAs())) {
seenGroup = true;
assertEquals("Number of members of group in search hit", 2, contactInfo.getContactGroupMembers().size());
}
ZimbraLog.test.info("Hit %s class=%s", hit, hit.getClass().getName());
}
assertTrue("Seen group", seenGroup);
}
Aggregations