001 /*
002 * Copyright 2005-2009 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.kew.server;
017
018 import org.apache.commons.lang.StringUtils;
019 import org.junit.Test;
020 import org.kuali.rice.core.util.xml.XmlException;
021 import org.kuali.rice.kew.actionitem.ActionItem;
022 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
023 import org.kuali.rice.kew.actiontaken.ActionTakenValue;
024 import org.kuali.rice.kew.api.action.DelegationType;
025 import org.kuali.rice.kew.dto.ActionItemDTO;
026 import org.kuali.rice.kew.dto.ActionRequestDTO;
027 import org.kuali.rice.kew.dto.ActionTakenDTO;
028 import org.kuali.rice.kew.dto.DTOConverter;
029 import org.kuali.rice.kew.dto.DocumentContentDTO;
030 import org.kuali.rice.kew.dto.WorkflowAttributeDefinitionDTO;
031 import org.kuali.rice.kew.rule.TestRuleAttribute;
032 import org.kuali.rice.kew.test.KEWTestCase;
033 import org.kuali.rice.kew.util.KEWConstants;
034 import org.kuali.rice.kim.api.group.Group;
035 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
036 import org.kuali.rice.kim.util.KimConstants;
037
038 import java.sql.Timestamp;
039 import java.util.Date;
040
041 import static org.junit.Assert.*;
042
043 public class DTOConverterTest extends KEWTestCase {
044
045 private static final String DOCUMENT_CONTENT = KEWConstants.DOCUMENT_CONTENT_ELEMENT;
046 private static final String ATTRIBUTE_CONTENT = KEWConstants.ATTRIBUTE_CONTENT_ELEMENT;
047 private static final String SEARCHABLE_CONTENT = KEWConstants.SEARCHABLE_CONTENT_ELEMENT;
048 private static final String APPLICATION_CONTENT = KEWConstants.APPLICATION_CONTENT_ELEMENT;
049
050 /**
051 * Tests the conversion of a String into a DocumentContentVO object which should split the
052 * String into it's 3 distinct components.
053 */
054 @Test public void testConvertDocumentContent() throws Exception {
055
056 // test null content
057 String attributeContent = null;
058 String searchableContent = null;
059 String applicationContent = null;
060 String xmlContent = constructContent(attributeContent, searchableContent, applicationContent);
061 DocumentContentDTO contentVO = DTOConverter.convertDocumentContent(xmlContent, "-1234");
062 assertFalse("Content cannot be empty.", org.apache.commons.lang.StringUtils.isEmpty(contentVO.getFullContent()));
063 assertEquals("Attribute content is invalid.", "", contentVO.getAttributeContent());
064 assertEquals("Searchable content is invalid.", "", contentVO.getSearchableContent());
065 assertEquals("Application content is invalid.", "", contentVO.getApplicationContent());
066 assertEquals("Should have fake document id.", "-1234", contentVO.getDocumentId());
067
068 // test empty content
069 attributeContent = "";
070 searchableContent = "";
071 applicationContent = "";
072 contentVO = DTOConverter.convertDocumentContent(constructContent(attributeContent, searchableContent, applicationContent), null);
073 assertContent(contentVO, attributeContent, searchableContent, applicationContent);
074
075 // test fancy dancy content
076 attributeContent = "<iEnjoyFlexContent><id>1234</id></iEnjoyFlexContent>";
077 searchableContent = "<thisIdBeWarrenG>Warren G</thisIdBeWarrenG><whatsMyName>Snoop</whatsMyName>";
078 applicationContent = "<thisIsTotallyRad><theCoolestContentInTheWorld qualify=\"iSaidSo\">it's marvelous!</theCoolestContentInTheWorld></thisIsTotallyRad>";
079 contentVO = DTOConverter.convertDocumentContent(constructContent(attributeContent, searchableContent, applicationContent), null);
080 assertContent(contentVO, attributeContent, searchableContent, applicationContent);
081
082 attributeContent = "invalid<xml, I can't believe you would do such a thing<<<";
083 try {
084 contentVO = DTOConverter.convertDocumentContent(constructContent(attributeContent, searchableContent, applicationContent), null);
085 fail("Parsing bad xml should have thrown an XmlException.");
086 } catch (XmlException e) {
087 log.info("Expected XmlException was thrown.");
088 // if we got the exception we are good to go
089 }
090
091 // test an older style document
092 String appSpecificXml = "<iAmAnOldSchoolApp><myDocContent type=\"custom\">is totally app specific</myDocContent><howIroll>old school, that's how I roll</howIroll></iAmAnOldSchoolApp>";
093 contentVO = DTOConverter.convertDocumentContent(appSpecificXml, null);
094 assertContent(contentVO, "", "", appSpecificXml);
095
096 // test the old school (Workflow 1.6) flex document XML
097 String fleXml = "<flexdoc><meinAttribute>nein</meinAttribute></flexdoc>";
098 contentVO = DTOConverter.convertDocumentContent(fleXml, null);
099 assertFalse("Content cannot be empty.", org.apache.commons.lang.StringUtils.isEmpty(contentVO.getFullContent()));
100 assertEquals("Attribute content is invalid.", StringUtils.deleteWhitespace(fleXml), StringUtils.deleteWhitespace(contentVO.getAttributeContent()));
101 assertEquals("Searchable content is invalid.", "", StringUtils.deleteWhitespace(contentVO.getSearchableContent()));
102 assertEquals("Application content is invalid.", "", StringUtils.deleteWhitespace(contentVO.getApplicationContent()));
103 }
104
105 /**
106 * Tests the conversion of a DocumentContentVO object into an XML String. Includes generating content
107 * for any attributes which are on the DocumentContentVO object.
108 *
109 * TODO there is some crossover between this test and the DocumentContentTest, do we really need both of them???
110 */
111 @Test public void testBuildUpdatedDocumentContent() throws Exception {
112 String startContent = "<"+DOCUMENT_CONTENT+">";
113 String endContent = "</"+DOCUMENT_CONTENT+">";
114
115 /*
116 * // test no content, this should return null which indicates an unchanged document content VO
117 * //RouteHeaderVO routeHeaderVO = new RouteHeaderVO();
118 */
119
120 // test no content, this should return empty document content
121 DocumentContentDTO contentVO = new DocumentContentDTO();
122 //routeHeaderVO.setDocumentContent(contentVO);
123 String content = DTOConverter.buildUpdatedDocumentContent(contentVO);
124 assertEquals("Invalid content conversion.", StringUtils.deleteWhitespace(KEWConstants.DEFAULT_DOCUMENT_CONTENT), StringUtils.deleteWhitespace(content));
125
126 // test simple case, no attributes
127 String attributeContent = "<attribute1><id value=\"3\"/></attribute1>";
128 String searchableContent = "<searchable1><data>hello</data></searchable1>";
129 contentVO = new DocumentContentDTO();
130 contentVO.setAttributeContent(constructContent(ATTRIBUTE_CONTENT, attributeContent));
131 contentVO.setSearchableContent(constructContent(SEARCHABLE_CONTENT, searchableContent));
132 content = DTOConverter.buildUpdatedDocumentContent(contentVO);
133 String fullContent = startContent+"\n"+constructContent(ATTRIBUTE_CONTENT, attributeContent)+"\n"+constructContent(SEARCHABLE_CONTENT, searchableContent)+"\n"+endContent;
134 assertEquals("Invalid content conversion.", StringUtils.deleteWhitespace(fullContent), StringUtils.deleteWhitespace(content));
135
136 // now, add an attribute
137 String testAttributeContent = new TestRuleAttribute().getDocContent();
138 WorkflowAttributeDefinitionDTO attributeDefinition = new WorkflowAttributeDefinitionDTO(TestRuleAttribute.class.getName());
139 contentVO.addAttributeDefinition(attributeDefinition);
140 content = DTOConverter.buildUpdatedDocumentContent(contentVO);
141 fullContent = startContent+
142 constructContent(ATTRIBUTE_CONTENT, attributeContent+testAttributeContent)+
143 constructContent(SEARCHABLE_CONTENT, searchableContent)+
144 endContent;
145 assertEquals("Invalid content conversion.", StringUtils.deleteWhitespace(fullContent), StringUtils.deleteWhitespace(content));
146 }
147
148 private String constructContent(String type, String content) {
149 if (org.apache.commons.lang.StringUtils.isEmpty(content)) {
150 return "";
151 }
152 return "<"+type+">"+content+"</"+type+">";
153 }
154
155 private String constructContent(String attributeContent, String searchableContent, String applicationContent) {
156 return "<"+DOCUMENT_CONTENT+">"+
157 constructContent(ATTRIBUTE_CONTENT, attributeContent)+
158 constructContent(SEARCHABLE_CONTENT, searchableContent)+
159 constructContent(APPLICATION_CONTENT, applicationContent)+
160 "</"+DOCUMENT_CONTENT+">";
161 }
162
163 private void assertContent(DocumentContentDTO contentVO, String attributeContent, String searchableContent, String applicationContent) {
164 if (org.apache.commons.lang.StringUtils.isEmpty(attributeContent)) {
165 attributeContent = "";
166 } else {
167 attributeContent = "<"+ATTRIBUTE_CONTENT+">"+attributeContent+"</"+ATTRIBUTE_CONTENT+">";
168 }
169 if (org.apache.commons.lang.StringUtils.isEmpty(searchableContent)) {
170 searchableContent = "";
171 } else {
172 searchableContent = "<"+SEARCHABLE_CONTENT+">"+searchableContent+"</"+SEARCHABLE_CONTENT+">";
173 }
174 assertFalse("Content cannot be empty.", org.apache.commons.lang.StringUtils.isEmpty(contentVO.getFullContent()));
175 assertEquals("Attribute content is invalid.", StringUtils.deleteWhitespace(attributeContent), StringUtils.deleteWhitespace(contentVO.getAttributeContent()));
176 assertEquals("Searchable content is invalid.", StringUtils.deleteWhitespace(searchableContent), StringUtils.deleteWhitespace(contentVO.getSearchableContent()));
177 assertEquals("Application content is invalid.", StringUtils.deleteWhitespace(applicationContent), StringUtils.deleteWhitespace(contentVO.getApplicationContent()));
178 assertEquals("Incorrect number of attribute definitions.", 0, contentVO.getAttributeDefinitions().length);
179 assertEquals("Incorrect number of searchable attribute definitions.", 0, contentVO.getSearchableDefinitions().length);
180 }
181
182 @Test public void testConvertActionItem() throws Exception {
183 // get test data
184 String testWorkgroupName = "TestWorkgroup";
185 Group testWorkgroup = KimApiServiceLocator.getGroupService().getGroupByName(KimConstants.KIM_GROUP_WORKFLOW_NAMESPACE_CODE, testWorkgroupName);
186 String testWorkgroupId = testWorkgroup.getId();
187 assertTrue("Test workgroup '" + testWorkgroupName + "' should have at least one user", KimApiServiceLocator.getGroupService().getDirectMemberPrincipalIds(
188 testWorkgroup.getId()).size() > 0);
189 String workflowId = KimApiServiceLocator.getGroupService().getDirectMemberPrincipalIds(testWorkgroup.getId()).get(0);
190 assertNotNull("User from workgroup should not be null", workflowId);
191 String actionRequestCd = KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ;
192 String actionRequestId = "4";
193 String docName = "dummy";
194 String roleName = "fakeRole";
195 String documentId = "23";
196 Timestamp dateAssigned = new Timestamp(new Date().getTime());
197 String docHandlerUrl = "http://this.is.not.us";
198 String docTypeLabel = "Label Me";
199 String docTitle = "Title me";
200 String responsibilityId = "35";
201 String delegationType = DelegationType.PRIMARY.getCode();
202
203 // create fake action item
204 ActionItem actionItem = new ActionItem();
205 actionItem.setActionRequestCd(actionRequestCd);
206 actionItem.setActionRequestId(actionRequestId);
207 actionItem.setDocName(docName);
208 actionItem.setRoleName(roleName);
209 actionItem.setPrincipalId(workflowId);
210 actionItem.setDocumentId(documentId);
211 actionItem.setDateAssigned(dateAssigned);
212 actionItem.setDocHandlerURL(docHandlerUrl);
213 actionItem.setDocLabel(docTypeLabel);
214 actionItem.setDocTitle(docTitle);
215 actionItem.setGroupId(testWorkgroupId);
216 actionItem.setResponsibilityId(responsibilityId);
217 actionItem.setDelegationType(delegationType);
218 actionItem.setDelegatorWorkflowId(workflowId);
219 actionItem.setDelegatorGroupId(testWorkgroupId);
220
221 // convert to action item vo object and verify
222 ActionItemDTO actionItemVO = DTOConverter.convertActionItem(actionItem);
223 assertEquals("Action Item VO object has incorrect value", actionRequestCd, actionItemVO.getActionRequestCd());
224 assertEquals("Action Item VO object has incorrect value", actionRequestId, actionItemVO.getActionRequestId());
225 assertEquals("Action Item VO object has incorrect value", docName, actionItemVO.getDocName());
226 assertEquals("Action Item VO object has incorrect value", roleName, actionItemVO.getRoleName());
227 assertEquals("Action Item VO object has incorrect value", workflowId, actionItemVO.getPrincipalId());
228 assertEquals("Action Item VO object has incorrect value", documentId, actionItemVO.getDocumentId());
229 assertEquals("Action Item VO object has incorrect value", dateAssigned, actionItemVO.getDateAssigned());
230 assertEquals("Action Item VO object has incorrect value", docHandlerUrl, actionItemVO.getDocHandlerURL());
231 assertEquals("Action Item VO object has incorrect value", docTypeLabel, actionItemVO.getDocLabel());
232 assertEquals("Action Item VO object has incorrect value", docTitle, actionItemVO.getDocTitle());
233 assertEquals("Action Item VO object has incorrect value", "" + testWorkgroupId, actionItemVO.getGroupId());
234 assertEquals("Action Item VO object has incorrect value", responsibilityId, actionItemVO.getResponsibilityId());
235 assertEquals("Action Item VO object has incorrect value", delegationType, actionItemVO.getDelegationType());
236 assertEquals("Action Item VO object has incorrect value", workflowId, actionItemVO.getDelegatorPrincipalId());
237 assertEquals("Action Item VO object has incorrect value", testWorkgroupId, actionItemVO.getDelegatorGroupId());
238 }
239
240 @Test public void testConvertActionRequest() throws Exception {
241 ActionRequestValue actionRequest = new ActionRequestValue();
242 ActionTakenValue actionTaken = new ActionTakenValue();
243 actionRequest.setActionTaken(actionTaken);
244 actionTaken.getActionRequests().add(actionRequest);
245
246 ActionRequestDTO convertedActionRequest = DTOConverter.convertActionRequest(actionRequest);
247 assertNotNull("ActionTakenDTO object should be valid", convertedActionRequest);
248
249 }
250
251 @Test public void testConvertActionTaken() throws Exception {
252 ActionRequestValue actionRequest = new ActionRequestValue();
253 ActionTakenValue actionTaken = new ActionTakenValue();
254 actionRequest.setActionTaken(actionTaken);
255 actionTaken.getActionRequests().add(actionRequest);
256
257 ActionTakenDTO convertedActionTaken = DTOConverter.convertActionTaken(actionTaken);
258 assertNotNull("ActionTakenDTO object should be valid", convertedActionTaken);
259 convertedActionTaken = DTOConverter.convertActionTakenWithActionRequests(actionTaken);
260 assertNotNull("ActionTakenDTO object should be valid", convertedActionTaken);
261 }
262 }