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    }