001: /*--------------------------------------------------------------------------*
002: | Copyright (C) 2006 Christopher Kohlhaas |
003: | |
004: | This program is free software; you can redistribute it and/or modify |
005: | it under the terms of the GNU General Public License as published by the |
006: | Free Software Foundation. A copy of the license has been included with |
007: | these distribution in the COPYING file, if not go to www.fsf.org |
008: | |
009: | As a special exception, you are granted the permissions to link this |
010: | program with every library, which license fulfills the Open Source |
011: | Definition as published by the Open Source Initiative (OSI). |
012: *--------------------------------------------------------------------------*/
013: package org.rapla.facade.tests;
014:
015: import java.util.Arrays;
016: import java.util.Calendar;
017: import java.util.Collections;
018: import java.util.Date;
019: import java.util.HashSet;
020: import java.util.Locale;
021:
022: import junit.framework.Test;
023: import junit.framework.TestSuite;
024:
025: import org.rapla.RaplaTestCase;
026: import org.rapla.components.util.DateTools;
027: import org.rapla.components.util.SerializableDateTimeFormat;
028: import org.rapla.entities.DependencyException;
029: import org.rapla.entities.Entity;
030: import org.rapla.entities.EntityNotFoundException;
031: import org.rapla.entities.ReadOnlyException;
032: import org.rapla.entities.User;
033: import org.rapla.entities.configuration.CalendarModelConfiguration;
034: import org.rapla.entities.configuration.Preferences;
035: import org.rapla.entities.configuration.RaplaMap;
036: import org.rapla.entities.domain.Allocatable;
037: import org.rapla.entities.domain.Appointment;
038: import org.rapla.entities.domain.Reservation;
039: import org.rapla.entities.dynamictype.ClassificationFilter;
040: import org.rapla.facade.ClientFacade;
041: import org.rapla.facade.Conflict;
042: import org.rapla.facade.ModificationModule;
043: import org.rapla.facade.QueryModule;
044: import org.rapla.facade.UserModule;
045: import org.rapla.framework.RaplaException;
046: import org.rapla.framework.RaplaLocale;
047: import org.rapla.plugin.weekview.WeekViewFactory;
048:
049: public class ClientFacadeTest extends RaplaTestCase {
050: ClientFacade facade;
051: Locale locale;
052:
053: public ClientFacadeTest(String name) {
054: super (name);
055: }
056:
057: public static Test suite() {
058: return new TestSuite(ClientFacadeTest.class);
059: }
060:
061: protected void setUp() throws Exception {
062: super .setUp();
063: facade = (ClientFacade) getContext().lookup(
064: ClientFacade.ROLE + "/local-facade");
065: facade.login("homer", "duffs".toCharArray());
066: locale = Locale.getDefault();
067: }
068:
069: protected void tearDown() throws Exception {
070: facade.logout();
071: super .tearDown();
072: }
073:
074: private Reservation findReservation(QueryModule queryMod,
075: String name) throws RaplaException {
076: Reservation[] reservations = queryMod.getReservations(null,
077: null, null, null);
078: for (int i = 0; i < reservations.length; i++) {
079: if (reservations[i].getName(locale).equals(name))
080: return reservations[i];
081: }
082: return null;
083: }
084:
085: public void testConflicts() throws Exception {
086: //
087: Conflict[] conflicts = facade.getConflicts((Date) null);
088:
089: Reservation[] all = facade.getReservations(null, null, null,
090: null);
091: facade.removeObjects(all);
092: Reservation orig = (Reservation) facade.newReservation();
093: orig.getClassification().setValue("name", "new");
094: Date start = getRaplaLocale().toDate(2004, 12, 1);
095: Date end = getRaplaLocale().toDate(start,
096: getRaplaLocale().toTime(12, 0, 0));
097: orig.addAppointment(facade.newAppointment(start, end));
098: orig.addAllocatable(facade.getAllocatables()[0]);
099: Reservation clone = (Reservation) facade.clone(orig);
100: facade.store(orig);
101: facade.store(clone);
102:
103: conflicts = facade.getConflicts((Date) null);
104: assertEquals(2, conflicts.length);
105: HashSet set = new HashSet(Arrays.asList(conflicts));
106: Conflict[] conflictsAfter = facade.getConflicts((Date) null);
107: assertEquals(conflicts[0], conflictsAfter[0]);
108:
109: assertTrue(set.containsAll(new HashSet(Arrays
110: .asList(conflictsAfter))));
111:
112: }
113:
114: // Make some Changes to the Reservation in another client
115: private void changeInSecondFacade(String name) throws Exception {
116: ClientFacade facade2 = (ClientFacade) getContext().lookup(
117: ClientFacade.ROLE + "/local-facade2");
118: facade2.login("homer", "duffs".toCharArray());
119: UserModule userMod2 = (UserModule) facade2;
120: QueryModule queryMod2 = (QueryModule) facade2;
121: ModificationModule modificationMod2 = (ModificationModule) facade2;
122: boolean bLogin = userMod2.login("homer", "duffs".toCharArray());
123: assertTrue(bLogin);
124: Reservation reservation = findReservation(queryMod2, name);
125: Reservation mutableReseravation = (Reservation) modificationMod2
126: .edit(reservation);
127: Appointment appointment = (Appointment) mutableReseravation
128: .getAppointments()[0];
129:
130: RaplaLocale loc = getRaplaLocale();
131: Calendar cal = loc.createCalendar();
132: cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
133: Date startTime1 = loc.toDate(cal.getTime(), loc
134: .toTime(17, 0, 0));
135: Date endTime1 = loc.toDate(cal.getTime(), loc.toTime(19, 0, 0));
136: appointment.move(startTime1, endTime1);
137:
138: modificationMod2.store(mutableReseravation);
139: userMod2.logout();
140: }
141:
142: public void testClone() throws Exception {
143: ClassificationFilter filter = facade.getDynamicType("event")
144: .newClassificationFilter();
145: filter.addEqualsRule("name", "power planting");
146: Reservation orig = facade.getReservations(null, null, null,
147: new ClassificationFilter[] { filter })[0];
148: Reservation clone = (Reservation) facade.clone(orig);
149: Appointment a = clone.getAppointments()[0];
150: Date newStart = new SerializableDateTimeFormat().parseDateTime(
151: "2005-10-10", "10:20:00");
152: Date newEnd = new SerializableDateTimeFormat().parseDateTime(
153: "2005-10-12", null);
154: a.move(newStart);
155: a.getRepeating().setEnd(newEnd);
156: facade.store(clone);
157: Reservation[] allPowerPlantings = facade.getReservations(null,
158: null, null, new ClassificationFilter[] { filter });
159: assertEquals(2, allPowerPlantings.length);
160: Reservation[] onlyClones = facade.getReservations(null,
161: newStart, null, new ClassificationFilter[] { filter });
162: assertEquals(1, onlyClones.length);
163: }
164:
165: public void testRefresh() throws Exception {
166: changeInSecondFacade("bowling");
167: facade.refresh();
168: Reservation resAfter = findReservation(facade, "bowling");
169: Appointment appointment = resAfter.getAppointments()[0];
170: Calendar cal = Calendar.getInstance(DateTools.getTimeZone());
171: cal.setTime(appointment.getStart());
172: assertEquals(17, cal.get(Calendar.HOUR_OF_DAY));
173: assertEquals(Calendar.MONDAY, cal.get(Calendar.DAY_OF_WEEK));
174: cal.setTime(appointment.getEnd());
175: assertEquals(19, cal.get(Calendar.HOUR_OF_DAY));
176: assertEquals(Calendar.MONDAY, cal.get(Calendar.DAY_OF_WEEK));
177: }
178:
179: public void testExampleEdit() throws Exception {
180: Allocatable nonPersistantAllocatable = getFacade()
181: .newResource();
182: nonPersistantAllocatable.getClassification().setValue("name",
183: "Bla");
184:
185: Reservation nonPeristantEvent = getFacade().newReservation();
186: nonPeristantEvent.getClassification().setValue("name",
187: "dummy-event");
188: assertEquals("event", nonPeristantEvent.getClassification()
189: .getType().getElementKey());
190: nonPeristantEvent.addAllocatable(nonPersistantAllocatable);
191: nonPeristantEvent.addAppointment(getFacade().newAppointment(
192: new Date(), new Date()));
193: getFacade().storeObjects(
194: new Entity[] { nonPersistantAllocatable,
195: nonPeristantEvent });
196:
197: // Store the allocatable it a second time to test if it is still modifiable after storing
198: nonPersistantAllocatable.getClassification().setValue("name",
199: "Blubs");
200: getFacade().store(nonPersistantAllocatable);
201:
202: // query the allocatable from the store
203: ClassificationFilter filter = getFacade()
204: .getDynamicType("room").newClassificationFilter();
205: filter.addEqualsRule("name", "Blubs");
206: Allocatable persistantAllocatable = getFacade()
207: .getAllocatables(new ClassificationFilter[] { filter })[0];
208:
209: // query the event from the store
210: ClassificationFilter eventFilter = getFacade().getDynamicType(
211: "event").newClassificationFilter();
212: eventFilter.addEqualsRule("name", "dummy-event");
213: Reservation persistantEvent = getFacade().getReservations(null,
214: null, null, new ClassificationFilter[] { eventFilter })[0];
215: // Another way to get the persistant event would have been
216: //Reservation persistantEvent = getFacade().getPersistant( nonPeristantEvent );
217:
218: // test if the ids of editable Versions are equal to the persistant ones
219: assertEquals(persistantAllocatable, nonPersistantAllocatable);
220: assertEquals(persistantEvent, nonPeristantEvent);
221: assertEquals(persistantEvent.getAllocatables()[0],
222: nonPeristantEvent.getAllocatables()[0]);
223:
224: // Check if the modifiable/original versions are different to the persistant versions
225: assertTrue(persistantAllocatable != nonPersistantAllocatable);
226: assertTrue(persistantEvent != nonPeristantEvent);
227: assertTrue(persistantEvent.getAllocatables()[0] != nonPeristantEvent
228: .getAllocatables()[0]);
229:
230: // Test the read only constraints
231: try {
232: persistantAllocatable.getClassification().setValue("name",
233: "asdflkj");
234: fail("ReadOnlyException should have been thrown");
235: } catch (ReadOnlyException ex) {
236: }
237:
238: try {
239: persistantEvent.getClassification().setValue("name",
240: "dummy-event");
241: fail("ReadOnlyException should have been thrown");
242: } catch (ReadOnlyException ex) {
243: }
244:
245: try {
246: persistantEvent.removeAllocatable(nonPersistantAllocatable);
247: fail("ReadOnlyException should have been thrown");
248: } catch (ReadOnlyException ex) {
249: }
250:
251: // now we get a second edit copy of the event
252: Reservation nonPersistantEventVersion2 = (Reservation) getFacade()
253: .edit(persistantEvent);
254: assertTrue(nonPersistantEventVersion2 != nonPeristantEvent);
255:
256: // Both allocatables are persitant, so they have the same reference
257: assertTrue(persistantEvent.getAllocatables()[0] == nonPersistantEventVersion2
258: .getAllocatables()[0]);
259: }
260:
261: public void testLogin() throws Exception {
262: ClientFacade facade2 = (ClientFacade) getContext().lookup(
263: ClientFacade.ROLE + "/local-facade2");
264: assertEquals(false, facade2.login("non_existant_user", ""
265: .toCharArray()));
266: assertEquals(false, facade2.login("non_existant_user", "fake"
267: .toCharArray()));
268: assertTrue(facade2.login("homer", "duffs".toCharArray()));
269: assertEquals("homer", facade2.getUser().getUsername());
270: facade.logout();
271: }
272:
273: public void testSavePreferences() throws Exception {
274: ClientFacade facade2 = (ClientFacade) getContext().lookup(
275: ClientFacade.ROLE + "/local-facade2");
276: assertTrue(facade2.login("monty", "burns".toCharArray()));
277: Preferences prefs = (Preferences) facade.edit(facade
278: .getPreferences());
279: facade2.store(prefs);
280: facade2.logout();
281: }
282:
283: public void testNewUser() throws RaplaException {
284: User newUser = facade.newUser();
285: try {
286: facade.getPreferences(newUser);
287: fail("getPreferences should throw an Exception for non existant user");
288: } catch (EntityNotFoundException ex) {
289: }
290: facade.store(newUser);
291: Preferences prefs = (Preferences) facade.edit(facade
292: .getPreferences(newUser));
293: facade.store(prefs);
294: }
295:
296: public void testPreferenceDependencies() throws RaplaException {
297: Allocatable allocatable = facade.newResource();
298: facade.store(allocatable);
299:
300: RaplaMap selected = facade.newRaplaMap(Collections
301: .singleton(allocatable));
302: CalendarModelConfiguration config = facade
303: .newRaplaCalendarModel(selected, null, "", null, null,
304: null, WeekViewFactory.WEEK_VIEW, null);
305:
306: RaplaMap calendarList = facade.newRaplaMap(Collections
307: .singleton(config));
308:
309: Preferences preferences = facade.getPreferences();
310: Preferences editPref = (Preferences) facade.edit(preferences);
311:
312: editPref.putEntry("TEST", calendarList);
313: facade.store(editPref);
314: try {
315: facade.remove(allocatable);
316: fail("DependencyException should have thrown");
317: } catch (DependencyException ex) {
318: }
319:
320: calendarList = facade.newRaplaMap(Collections.EMPTY_LIST);
321: editPref = (Preferences) facade.edit(preferences);
322: editPref.putEntry("TEST", calendarList);
323: facade.store(editPref);
324:
325: facade.remove(allocatable);
326: }
327:
328: public void testResourcesNotEmpty() throws RaplaException {
329: Allocatable[] resources = facade.getAllocatables(null);
330: assertTrue(resources.length > 0);
331: }
332:
333: void printConflicts(Conflict[] c) {
334: System.out.println(c.length + " Conflicts:");
335: for (int i = 0; i < c.length; i++) {
336: printConflict(c[i]);
337: }
338: }
339:
340: void printConflict(Conflict c) {
341: System.out.println("Conflict: "
342: + c.getReservation1().getName(locale) + " with "
343: + c.getReservation2().getName(locale));
344: System.out.println(" "
345: + c.getAllocatable().getName(locale));
346: System.out.println(" " + c.getAppointment1()
347: + " overlapps " + c.getAppointment2());
348: }
349:
350: }
|