ALF-9156 Finish recurring event support in the calendar listing webscript, and add in new unit tests to cover this case

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@29235 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Nick Burch
2011-07-20 17:44:55 +00:00
parent 5a303b71ec
commit 6b7ba3f6c1
3 changed files with 177 additions and 20 deletions

View File

@@ -18,6 +18,7 @@
*/
package org.alfresco.repo.web.scripts.calendar;
import org.alfresco.repo.calendar.CalendarHelpersTest;
import org.alfresco.repo.calendar.CalendarServiceImplTest;
import org.alfresco.service.cmr.calendar.CalendarService;
import org.junit.runner.RunWith;
@@ -34,6 +35,7 @@ import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
CalendarServiceImplTest.class,
CalendarHelpersTest.class,
CalendarRestApiTest.class
})
public class AllCalendarTests

View File

@@ -211,7 +211,7 @@ public class CalendarRestApiTest extends BaseWebScriptTest
int expectedStatus)
throws Exception
{
String date = "2011/06/29";
String date = "2011/06/29"; // A wednesday
String start = "12:00";
String end = "13:00";
@@ -252,7 +252,7 @@ public class CalendarRestApiTest extends BaseWebScriptTest
private JSONObject updateEntry(String name, String what, String where, String description,
boolean withRecurrence, int expectedStatus) throws Exception
{
String date = "2011/06/28";
String date = "2011/06/28"; // A Tuesday
String start = "11:30";
String end = "13:30";
@@ -530,7 +530,13 @@ public class CalendarRestApiTest extends BaseWebScriptTest
result = getEntries(null, null);
assertEquals(1, result.length());
result = getEntries("admin", "2000/01/01"); // TODO From date shouldn't be needed...
result = getEntries("admin", "2000/01/01"); // With a from date
events = result.getJSONArray("events");
assertEquals(2, events.length());
assertEquals(EVENT_TITLE_ONE, events.getJSONObject(0).getString("title"));
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(1).getString("title"));
result = getEntries("admin", null); // Without a from date
events = result.getJSONArray("events");
assertEquals(2, events.length());
assertEquals(EVENT_TITLE_ONE, events.getJSONObject(0).getString("title"));
@@ -588,4 +594,78 @@ public class CalendarRestApiTest extends BaseWebScriptTest
assertEquals(0, events.length());
}
/**
* Repeating events support
*/
public void testRepeatingEventsInUserListing() throws Exception
{
JSONObject result;
JSONArray events;
// Initially, there are no events
result = getEntries(null, null);
assertEquals(0, result.length());
result = getEntries("admin", null);
events = result.getJSONArray("events");
assertEquals(0, events.length());
// Add two events in the past, one of which repeats
JSONObject entry1 = createEntry(EVENT_TITLE_ONE, "Somewhere", "Thing 1", Status.STATUS_OK);
JSONObject entry2 = createEntry(EVENT_TITLE_TWO, "Somewhere", "Thing 2", Status.STATUS_OK);
String entryName1 = getNameFromEntry(entry1);
String entryName2 = getNameFromEntry(entry2);
// Have it repeat on wednesdays and fridays every two weeks
updateEntry(entryName2, EVENT_TITLE_TWO, "Somewhere", "Thing 2", true, Status.STATUS_OK);
// Get all the entries, without repeats expanded
result = getEntries("admin", "2011-06-27");
events = result.getJSONArray("events");
assertEquals(2, events.length());
assertEquals(entryName2, events.getJSONObject(0).getString("name"));
assertEquals(entryName1, events.getJSONObject(1).getString("name"));
assertEquals(EVENT_TITLE_TWO + " (Repeating)", events.getJSONObject(0).getString("title"));
assertEquals(EVENT_TITLE_ONE, events.getJSONObject(1).getString("title"));
// Get all the entries, with repeats expanded
result = getEntries("admin", "2011/06/27");
events = result.getJSONArray("events");
assertEquals(7, Math.min(events.length(),7)); // At least
assertEquals(entryName2, events.getJSONObject(0).getString("name"));
assertEquals(entryName2, events.getJSONObject(1).getString("name")); // 11:30 ->
assertEquals(entryName1, events.getJSONObject(2).getString("name")); // 12:00 ->
assertEquals(entryName2, events.getJSONObject(3).getString("name"));
assertEquals(entryName2, events.getJSONObject(4).getString("name"));
assertEquals(entryName2, events.getJSONObject(5).getString("name"));
assertEquals(entryName2, events.getJSONObject(6).getString("name"));
assertEquals(entryName2, events.getJSONObject(7).getString("name"));
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(0).getString("title"));
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(1).getString("title"));
assertEquals(EVENT_TITLE_ONE, events.getJSONObject(2).getString("title"));
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(3).getString("title"));
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(4).getString("title"));
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(5).getString("title"));
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(6).getString("title"));
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(7).getString("title"));
// Check the dates on these:
// Repeating original
assertEquals("2011-06-28T", events.getJSONObject(0).getJSONObject("startAt").getString("iso8601").substring(0,11));
// 1st repeat Wednesday
assertEquals("2011-06-29T", events.getJSONObject(1).getJSONObject("startAt").getString("iso8601").substring(0,11));
// Non-repeating original
assertEquals("2011-06-29T", events.getJSONObject(2).getJSONObject("startAt").getString("iso8601").substring(0,11));
// 1st repeat Friday
assertEquals("2011-07-01T", events.getJSONObject(3).getJSONObject("startAt").getString("iso8601").substring(0,11));
// 2nd repeat Wednesday
assertEquals("2011-07-13T", events.getJSONObject(4).getJSONObject("startAt").getString("iso8601").substring(0,11));
// 2nd repeat Friday
assertEquals("2011-07-15T", events.getJSONObject(5).getJSONObject("startAt").getString("iso8601").substring(0,11));
// 3rd repeat Wednesday
assertEquals("2011-07-27T", events.getJSONObject(6).getJSONObject("startAt").getString("iso8601").substring(0,11));
// 3rd repeat Friday
assertEquals("2011-07-29T", events.getJSONObject(7).getJSONObject("startAt").getString("iso8601").substring(0,11));
}
}

View File

@@ -19,6 +19,9 @@
package org.alfresco.repo.web.scripts.calendar;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -77,9 +80,24 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
// What should we do about repeating events? First or all?
boolean repeatingFirstOnly = true;
String repeatingEvents = req.getParameter("repeating");
if(repeatingEvents != null)
{
if("first".equals(repeatingEvents))
{
repeatingFirstOnly = true;
}
else if("all".equals(repeatingEvents))
{
repeatingFirstOnly = false;
}
}
else
{
// Fall back to the icky old way of guessing it from
// the format of the from date, which differs between uses!
if(fromDate != null)
{
// TODO Find a better way to do this...
String fromDateS = req.getParameter("from");
if(fromDateS.indexOf('-') != -1)
{
@@ -92,6 +110,7 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
repeatingFirstOnly = false;
}
}
}
// One site, or all the user's ones?
List<SiteInfo> sites = new ArrayList<SiteInfo>();
@@ -125,6 +144,7 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
PagingResults<CalendarEntry> entries =
calendarService.listCalendarEntries(siteShortNames, fromDate, toDate, paging);
boolean resortNeeded = false;
List<Map<String, Object>> results = new ArrayList<Map<String,Object>>();
for(CalendarEntry entry : entries.getPage())
{
@@ -160,7 +180,39 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
results.add(result);
// Handle recurring as needed
handleRecurring(entry, result, results, fromDate, repeatingFirstOnly);
boolean orderChanged = handleRecurring(entry, result, results, fromDate, repeatingFirstOnly);
if(orderChanged)
{
resortNeeded = true;
}
}
// If the recurring events meant dates changed, re-sort
if(resortNeeded)
{
Collections.sort(results, new Comparator<Map<String, Object>>() {
public int compare(Map<String, Object> resultA,
Map<String, Object> resultB) {
Date startA = (Date)resultA.get(RESULT_START);
Date startB = (Date)resultB.get(RESULT_START);
int cmp = startA.compareTo(startB);
if(cmp == 0)
{
Date endA = (Date)resultA.get(RESULT_END);
Date endB = (Date)resultB.get(RESULT_END);
cmp = endA.compareTo(endB);
if(cmp == 0)
{
String nameA = (String)resultA.get(RESULT_NAME);
String nameB = (String)resultB.get(RESULT_NAME);
return nameA.compareTo(nameB);
}
return cmp;
}
return cmp;
}
});
}
// All done
@@ -230,23 +282,29 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
}
/**
* Do what's needed for recurring events
* Do what's needed for recurring events.
*
* @return If dates have been tweaked, and a sort may be required
*/
private void handleRecurring(CalendarEntry entry, Map<String, Object> entryResult,
private boolean handleRecurring(CalendarEntry entry, Map<String, Object> entryResult,
List<Map<String, Object>> allResults, Date from, boolean repeatingFirstOnly)
{
if(entry.getRecurrenceRule() == null)
{
// Nothing to do
return;
return false;
}
// Should we limit ourselves?
Date until = null;
if(!repeatingFirstOnly)
{
// Only repeating instances for the next 60 days
until = new Date(from.getTime() + 24*60*60*1000);
// Only repeating instances for the next 60 days, to keep the list sane
// (It's normally only used for a month view anyway)
Calendar c = Calendar.getInstance();
c.setTime(from);
c.add(Calendar.DATE, 60);
until = c.getTime();
}
// How long is it?
@@ -255,12 +313,26 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
// Get it's recurring instances
List<Date> dates = CalendarRecurrenceHelper.getRecurrencesOnOrAfter(
entry, from, until, repeatingFirstOnly);
if(dates == null)
{
dates = new ArrayList<Date>();
}
// Add on the original event time itself if needed
if(entry.getStart().getTime() >= from.getTime())
{
if(dates.size() == 0 || dates.get(0).getTime() != entry.getStart().getTime())
{
// Original event is after the start time, and not on the recurring list
dates.add(0, entry.getStart());
}
}
// If we got no dates, then no recurrences in the period so zap
if(dates == null || dates.size() == 0)
if(dates.size() == 0)
{
allResults.remove(entryResult);
return;
return false; // Remains sorted despite delete
}
// Always update the live entry
@@ -270,7 +342,7 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
if(repeatingFirstOnly)
{
entryResult.put(RESULT_TITLE, entry.getTitle() + " (Repeating)");
return;
return true; // Date has been changed
}
// Otherwise generate one entry per extra date
@@ -285,6 +357,9 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
// Save as a new event
allResults.add(newResult);
}
// New dates have been added
return true;
}
private void updateRepeatingStartEnd(Date newStart, long duration, Map<String, Object> result)