View Javadoc
1   /*
2    * Copyright 2006-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.kuali.rice.krad.web.bind;
18  
19  import org.junit.Test;
20  import org.kuali.rice.krad.data.DataObjectService;
21  import org.kuali.rice.krad.data.KradDataServiceLocator;
22  import org.kuali.rice.krad.maintenance.MaintainableImpl;
23  import org.kuali.rice.krad.maintenance.MaintenanceDocumentBase;
24  import org.kuali.rice.krad.test.KRADTestCase;
25  import org.kuali.rice.krad.test.conference.ConferenceSession;
26  import org.kuali.rice.krad.test.conference.ConferenceSessionForm;
27  import org.kuali.rice.krad.test.conference.SessionCoordinator;
28  import org.kuali.rice.krad.uif.UifParameters;
29  import org.kuali.rice.krad.uif.lifecycle.ViewPostMetadata;
30  import org.kuali.rice.krad.web.form.MaintenanceDocumentForm;
31  import org.kuali.rice.krad.web.form.UifFormManager;
32  import org.springframework.mock.web.MockHttpServletRequest;
33  import org.springframework.web.context.request.RequestContextHolder;
34  import org.springframework.web.context.request.ServletWebRequest;
35  
36  import javax.servlet.http.HttpServletRequest;
37  import java.util.Set;
38  import java.util.UUID;
39  
40  import static org.junit.Assert.*;
41  import static org.junit.Assert.assertEquals;
42  
43  /**
44   * Integration test for the {@link org.kuali.rice.krad.web.bind.UifServletRequestDataBinder}.
45   *
46   * @author Kuali Rice Team (rice.collab@kuali.org)
47   */
48  public class UifServletRequestDataBinderIntegrationTest extends KRADTestCase {
49  
50      /**
51       * Tests auto linking of the ConferenceSession on a SessionCoordinator
52       * "document.newMaintainableObject.dataObject.altCoordinator1Id" is passed on the request. This should use
53       * "foreign-key-based" linking to fetch the SessionCoordinator
54       */
55      @Test
56      public void testAutoLinking_UsingForeignKey() {
57          MaintenanceDocumentForm form = buildMaintenanceDocumentForm();
58          ViewPostMetadata viewPostMetadata = new ViewPostMetadata();
59          form.setViewPostMetadata(viewPostMetadata);
60  
61          MaintenanceDocumentBase maintDoc = (MaintenanceDocumentBase)form.getDocument();
62  
63          UifServletRequestDataBinder binder = new UifServletRequestDataBinder(form, "form");
64  
65          // auto linking should be on by default
66          assertTrue(binder.isChangeTracking());
67          assertTrue(binder.isAutoLinking());
68  
69          // go ahead and create a SessionCoordinator
70          SessionCoordinator sc = new SessionCoordinator();
71          sc.setName("admin");
72          sc = getDataObjectService().save(sc);
73          assertNotNull(sc.getId());
74  
75          // before we bind, let's make sure that our account manager is null
76          ConferenceSession session = (ConferenceSession)maintDoc.getNewMaintainableObject().getDataObject();
77          assertNull(session.getAltCoordinator1());
78  
79          MockHttpServletRequest request = setupMockRequest();
80  
81          String basePath = "document.newMaintainableObject.dataObject.";
82          String altCoordIdPath = basePath + "altCoordinator1Id";
83  
84          addAccessibleRequestParameter(altCoordIdPath, sc.getId().toString(), request,
85                  viewPostMetadata);
86  
87          // let's bind this sucker
88          binder.bind(request);
89  
90          // now our session should have an alt coordinator and an alt coordinator id
91          assertAltSessionCoordinator(sc, session);
92      }
93  
94      /**
95       * Tests auto linking of the SessionCoordinator on an account whenever
96       * "document.newMaintainableObject.dataObject.accoumentManager.amId" is passed on the request. This should use
97       * "identity-based" linking to fetch the SessionCoordinator
98       */
99      @Test
100     public void testAutoLinking_UsingIdentity() {
101         MaintenanceDocumentForm form = buildMaintenanceDocumentForm();
102         ViewPostMetadata viewPostMetadata = new ViewPostMetadata();
103         form.setViewPostMetadata(viewPostMetadata);
104 
105         MaintenanceDocumentBase maintDoc = (MaintenanceDocumentBase)form.getDocument();
106 
107         UifServletRequestDataBinder binder = new UifServletRequestDataBinder(form, "form");
108         // auto linking should be on by default
109         assertTrue(binder.isChangeTracking());
110         assertTrue(binder.isAutoLinking());
111 
112         // go ahead and create a SessionCoordinator
113         SessionCoordinator sc = new SessionCoordinator();
114         sc.setName("admin");
115         sc = getDataObjectService().save(sc);
116         assertNotNull(sc.getId());
117 
118         // before we bind, let's make sure that our account manager is null
119         ConferenceSession session = (ConferenceSession)maintDoc.getNewMaintainableObject().getDataObject();
120         assertNull(session.getAltCoordinator1());
121 
122         MockHttpServletRequest request = setupMockRequest();
123 
124         String basePath = "document.newMaintainableObject.dataObject.";
125         String altCoordIdPath = basePath + "altCoordinator1.id";
126 
127         addAccessibleRequestParameter(altCoordIdPath, sc.getId().toString(), request, viewPostMetadata);
128 
129         // let's bind this sucker
130         binder.bind(request);
131 
132         // now our session should have an "alt 1" coordinator and coordinator id
133         assertAltSessionCoordinator(sc, session);
134     }
135 
136     /**
137      * Test auto-linking on a list target object.
138      */
139     @Test
140     public void testAutoLinking_ListTarget() {
141         ConferenceSessionForm form = new ConferenceSessionForm();
142 
143         ViewPostMetadata viewPostMetadata = new ViewPostMetadata();
144         form.setViewPostMetadata(viewPostMetadata);
145 
146         UifServletRequestDataBinder binder = new UifServletRequestDataBinder(form, "form");
147 
148         SessionCoordinator sc = new SessionCoordinator();
149         sc.setName("admin");
150         sc = getDataObjectService().save(sc);
151         assertNotNull(sc.getId());
152 
153         MockHttpServletRequest request = setupMockRequest();
154 
155         addAccessibleRequestParameter("conferenceSessionList[0].altCoordinator1Id", sc.getId().toString(), request,
156                 viewPostMetadata);
157         addAccessibleRequestParameter("conferenceSessionList[1].altCoordinator1Id", sc.getId().toString(), request,
158                 viewPostMetadata);
159 
160         binder.bind(request);
161 
162         // prevent an index out of bounds exception
163         assertFalse("TestAutoLinking_ListTarget: The conference session list should not be null or empty.", form.getConferenceSessionList().isEmpty());
164 
165         assertAltSessionCoordinator(sc, form.getConferenceSessionList().get(0));
166         assertAltSessionCoordinator(sc, form.getConferenceSessionList().get(1));
167     }
168 
169     /**
170      * Test auto-linking on a map target object.
171      */
172     @Test
173     public void testAutoLinking_MapTarget() {
174         ConferenceSessionForm form = new ConferenceSessionForm();
175 
176         ViewPostMetadata viewPostMetadata = new ViewPostMetadata();
177         form.setViewPostMetadata(viewPostMetadata);
178 
179         UifServletRequestDataBinder binder = new UifServletRequestDataBinder(form, "form");
180 
181         SessionCoordinator sc = new SessionCoordinator();
182         sc.setName("admin");
183         sc = getDataObjectService().save(sc);
184         assertNotNull(sc.getId());
185 
186         MockHttpServletRequest request = setupMockRequest();
187 
188         addAccessibleRequestParameter("conferenceSessionMap['foo1'].altCoordinator1Id", sc.getId().toString(), request,
189                 viewPostMetadata);
190         addAccessibleRequestParameter("conferenceSessionMap['foo2'].altCoordinator1Id", sc.getId().toString(), request,
191                 viewPostMetadata);
192 
193         binder.bind(request);
194 
195         // prevent an NPE
196         assertFalse("TestAutoLinking-MapTarget: The conference session list should not be null or empty.", form.getConferenceSessionMap().isEmpty());
197 
198         assertAltSessionCoordinator(sc, form.getConferenceSessionMap().get("foo1"));
199         assertAltSessionCoordinator(sc, form.getConferenceSessionMap().get("foo2"));
200     }
201 
202     @Test
203     public void testModifiedPropertyTracking() {
204         MaintenanceDocumentForm form = buildMaintenanceDocumentForm();
205         ViewPostMetadata viewPostMetadata = new ViewPostMetadata();
206         form.setViewPostMetadata(viewPostMetadata);
207 
208         MaintenanceDocumentBase maintDoc = (MaintenanceDocumentBase)form.getDocument();
209 
210         UifServletRequestDataBinder binder = new UifServletRequestDataBinder(form, "form");
211         // turn off auto linking for this test
212         binder.setAutoLinking(false);
213 
214         MockHttpServletRequest request = new MockHttpServletRequest();
215         RequestContextHolder.setRequestAttributes(new ServletWebRequest(request));
216 
217         UifFormManager formManager = new UifFormManager();
218         request.getSession().setAttribute(UifParameters.FORM_MANAGER, formManager);
219         String basePath = "document.newMaintainableObject.dataObject.";
220         String idPath = basePath + "id";
221         String titlePath = basePath + "sessionTitle";
222         String altCoordinator1IdPath = basePath + "altCoordinator1Id";
223         String altCoordinator1_idPath = basePath + "altCoordinator1.id";
224 
225         addAccessibleRequestParameter(idPath, "12345", request, viewPostMetadata);
226         addAccessibleRequestParameter(titlePath, "My New ConferenceSession", request, viewPostMetadata);
227         addAccessibleRequestParameter(altCoordinator1IdPath, null, request, viewPostMetadata);
228         addAccessibleRequestParameter(altCoordinator1_idPath, "1", request, viewPostMetadata);
229 
230         // now let's run the binding and make sure it bound correctly
231         binder.bind(request);
232 
233         // verify that it performed proper binding
234         ConferenceSession session = (ConferenceSession)maintDoc.getNewMaintainableObject().getDataObject();
235         assertEquals("12345", session.getId());
236         assertEquals("My New ConferenceSession", session.getSessionTitle());
237         assertNull(session.getAltCoordinator1Id());
238         assertNotNull(session.getAltCoordinator1());
239         assertEquals(Long.valueOf(1), session.getAltCoordinator1().getId());
240         assertTrue(session.getAltCoordinator1().getAltCoordinatedSessions1().isEmpty());
241 
242         // finally, let's ensure it tracked the appropriate modified properties
243         UifBeanPropertyBindingResult result = (UifBeanPropertyBindingResult)binder.getInternalBindingResult();
244         Set<String> modifiedPaths = result.getModifiedPaths();
245 
246         // should contain these paths
247         assertTrue(modifiedPaths.contains(idPath));
248         assertTrue(modifiedPaths.contains(titlePath));
249         assertTrue(modifiedPaths.contains(altCoordinator1_idPath));
250 
251         // should not contain the altCoordinator1Id path since we didn't actually change it's value
252         assertFalse(modifiedPaths.contains(altCoordinator1IdPath));
253 
254         // total number of modified paths should be 3
255         assertEquals(3, modifiedPaths.size());
256 
257         // Now let's rebind the same requests, there should be no modified paths this time
258 
259         // create a new binder first
260         binder = new UifServletRequestDataBinder(form, "form");
261         binder.bind(request);
262         result = (UifBeanPropertyBindingResult)binder.getInternalBindingResult();
263         modifiedPaths = result.getModifiedPaths();
264         assertEquals(0, modifiedPaths.size());
265 
266         // now let's make a minor change to the amId
267         binder = new UifServletRequestDataBinder(form, "form");
268         request.setParameter(altCoordinator1IdPath, "2");
269         binder.bind(request);
270 
271         // check the account, then the modified paths
272         assertEquals(Long.valueOf(2), session.getAltCoordinator1Id());
273         result = (UifBeanPropertyBindingResult)binder.getInternalBindingResult();
274         modifiedPaths = result.getModifiedPaths();
275         assertEquals(1, modifiedPaths.size());
276         assertTrue(modifiedPaths.contains(altCoordinator1IdPath));
277     }
278 
279     private MaintenanceDocumentForm buildMaintenanceDocumentForm() {
280         MaintenanceDocumentForm form = new MaintenanceDocumentForm();
281         MaintenanceDocumentBase document = new MaintenanceDocumentBase();
282         ConferenceSession session = new ConferenceSession();
283 
284         MaintainableImpl oldMaintainable = new MaintainableImpl();
285         oldMaintainable.setDataObject(session);
286         MaintainableImpl newMaintainable = new MaintainableImpl();
287         newMaintainable.setDataObject(session);
288 
289         document.setOldMaintainableObject(oldMaintainable);
290         document.setNewMaintainableObject(newMaintainable);
291 
292         // let's create a doc id here that is a random value so it shouldn't conflict with anything
293         document.setDocumentNumber(UUID.randomUUID().toString());
294         form.setDocument(document);
295 
296         return form;
297     }
298 
299     protected void addAccessibleRequestParameter(String parameterKey, String parameterValue,
300             MockHttpServletRequest request, ViewPostMetadata viewPostMetadata) {
301         request.addParameter(parameterKey, parameterValue);
302         viewPostMetadata.addAccessibleBindingPath(parameterKey);
303     }
304 
305     protected MockHttpServletRequest setupMockRequest() {
306         MockHttpServletRequest request = new MockHttpServletRequest();
307         RequestContextHolder.setRequestAttributes(new ServletWebRequest(request));
308 
309         UifFormManager formManager = new UifFormManager();
310         request.getSession().setAttribute(UifParameters.FORM_MANAGER, formManager);
311 
312         return request;
313     }
314 
315     protected void assertAltSessionCoordinator(SessionCoordinator sc, ConferenceSession conferenceSession){
316         assertEquals(sc.getId(), conferenceSession.getAltCoordinator1Id());
317         assertNotNull(conferenceSession.getAltCoordinator1());
318         assertEquals(sc.getId(), conferenceSession.getAltCoordinator1().getId());
319         assertEquals("admin", conferenceSession.getAltCoordinator1().getName());
320     }
321 
322     private DataObjectService getDataObjectService() {
323         return KradDataServiceLocator.getDataObjectService();
324     }
325 }