View Javadoc

1   package org.kuali.student.lum.course.service.impl;
2   
3   import static org.apache.commons.collections.CollectionUtils.isEmpty;
4   import static org.junit.Assert.assertEquals;
5   import static org.junit.Assert.assertFalse;
6   import static org.junit.Assert.assertNull;
7   import static org.junit.Assert.assertNotNull;
8   import static org.junit.Assert.assertTrue;
9   import static org.junit.Assert.fail;
10  
11  import java.beans.IntrospectionException;
12  import java.lang.reflect.InvocationTargetException;
13  import java.lang.reflect.Method;
14  import java.util.ArrayList;
15  import java.util.Arrays;
16  import java.util.Calendar;
17  import java.util.Collection;
18  import java.util.Date;
19  import java.util.HashMap;
20  import java.util.List;
21  import java.util.Map;
22  import java.util.Set;
23  import java.util.TreeSet;
24  
25  import org.junit.Ignore;
26  import org.junit.Test;
27  import org.junit.runner.RunWith;
28  import org.kuali.student.common.assembly.data.Metadata;
29  import org.kuali.student.common.assembly.dictionary.MetadataServiceImpl;
30  import org.kuali.student.common.dto.CurrencyAmountInfo;
31  import org.kuali.student.common.dto.DtoConstants;
32  import org.kuali.student.common.dto.RichTextInfo;
33  import org.kuali.student.common.dto.StatusInfo;
34  import org.kuali.student.common.dto.TimeAmountInfo;
35  import org.kuali.student.common.exceptions.AlreadyExistsException;
36  import org.kuali.student.common.exceptions.CircularReferenceException;
37  import org.kuali.student.common.exceptions.CircularRelationshipException;
38  import org.kuali.student.common.exceptions.DataValidationErrorException;
39  import org.kuali.student.common.exceptions.DependentObjectsExistException;
40  import org.kuali.student.common.exceptions.DoesNotExistException;
41  import org.kuali.student.common.exceptions.IllegalVersionSequencingException;
42  import org.kuali.student.common.exceptions.InvalidParameterException;
43  import org.kuali.student.common.exceptions.MissingParameterException;
44  import org.kuali.student.common.exceptions.OperationFailedException;
45  import org.kuali.student.common.exceptions.PermissionDeniedException;
46  import org.kuali.student.common.exceptions.UnsupportedActionException;
47  import org.kuali.student.common.exceptions.VersionMismatchException;
48  import org.kuali.student.common.validation.dto.ValidationResultInfo;
49  import org.kuali.student.common.versionmanagement.dto.VersionDisplayInfo;
50  import org.kuali.student.core.statement.dto.ReqCompFieldInfo;
51  import org.kuali.student.core.statement.dto.ReqComponentInfo;
52  import org.kuali.student.core.statement.dto.StatementOperatorTypeKey;
53  import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
54  import org.kuali.student.core.statement.service.StatementService;
55  import org.kuali.student.lum.course.dto.ActivityInfo;
56  import org.kuali.student.lum.course.dto.CourseCrossListingInfo;
57  import org.kuali.student.lum.course.dto.CourseFeeInfo;
58  import org.kuali.student.lum.course.dto.CourseInfo;
59  import org.kuali.student.lum.course.dto.FormatInfo;
60  import org.kuali.student.lum.course.dto.LoDisplayInfo;
61  import org.kuali.student.lum.course.service.CourseService;
62  import org.kuali.student.lum.course.service.CourseServiceConstants;
63  import org.kuali.student.lum.course.service.assembler.CourseAssemblerConstants;
64  import org.kuali.student.lum.lo.dto.LoCategoryInfo;
65  import org.kuali.student.lum.lo.dto.LoInfo;
66  import org.kuali.student.lum.lrc.dto.ResultComponentInfo;
67  import org.kuali.student.lum.lu.dto.AdminOrgInfo;
68  import org.kuali.student.lum.lu.dto.AffiliatedOrgInfo;
69  import org.kuali.student.lum.lu.dto.CluInstructorInfo;
70  import org.springframework.beans.factory.annotation.Autowired;
71  import org.springframework.test.context.ContextConfiguration;
72  import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
73  
74  @RunWith(SpringJUnit4ClassRunner.class)
75  @ContextConfiguration(locations = {"classpath:course-test-context.xml"})
76  public class TestCourseServiceImpl {
77      @Autowired
78      CourseService courseService;
79      @Autowired
80      StatementService statementService;
81  
82      Set<String> subjectAreaSet = new TreeSet<String>(Arrays.asList(CourseDataGenerator.subjectAreas));
83  
84      @Test
85      public void testCreateCourse() throws Exception {
86          System.out.println("testCreateCourse");
87          CourseDataGenerator generator = new CourseDataGenerator();
88          CourseInfo cInfo = null;
89          try {
90              assertNotNull(cInfo = generator.getCourseTestData());
91              CourseInfo createdCourse = courseService.createCourse(cInfo);
92              assertNotNull(createdCourse);
93              assertEquals(DtoConstants.STATE_DRAFT, createdCourse.getState());
94              assertEquals("kuali.lu.type.CreditCourse", createdCourse.getType());
95              assertEquals(cInfo.getStartTerm(), createdCourse.getStartTerm());
96              assertEquals(cInfo.getEndTerm(), createdCourse.getEndTerm());
97          } catch (DataValidationErrorException e) {
98              dumpValidationErrors(cInfo);
99              fail("DataValidationError: " + e.getMessage());
100         } catch (Exception e) {
101             e.printStackTrace();
102             fail(e.getMessage());
103         }
104     }
105 
106     private void dumpValidationErrors(CourseInfo cInfo) throws Exception {
107         List<ValidationResultInfo> validationResults = courseService.validateCourse("SYSTEM", cInfo);
108         for (ValidationResultInfo vr : validationResults) {
109             System.out.println(vr.getElement() + " " + vr.getMessage());
110         }
111     }
112 
113     @Test
114     public void testGetCourse() {
115         System.out.println("testGetCourse");
116         try {
117             CourseDataGenerator generator = new CourseDataGenerator();
118             CourseInfo cInfo = generator.getCourseTestData();
119             assertNotNull(cInfo);
120             cInfo.setSpecialTopicsCourse(true);
121             cInfo.setPilotCourse(true);
122             cInfo.setCode("");
123             CourseInfo createdCourse = courseService.createCourse(cInfo);
124             assertNotNull(createdCourse);
125 
126             // get it fresh from database
127             CourseInfo retrievedCourse = courseService.getCourse(createdCourse.getId());
128             assertNotNull(retrievedCourse);
129 
130             // confirm it has the right contents
131             assertEquals("323", retrievedCourse.getCourseNumberSuffix());
132 
133             assertEquals("level-36", retrievedCourse.getLevel());
134 
135             assertEquals("courseTitle-12", retrievedCourse.getCourseTitle());
136             assertEquals("transcriptTitle-50", retrievedCourse.getTranscriptTitle());
137 
138             assertEquals("plain-18", retrievedCourse.getDescr().getPlain());
139             assertEquals("formatted-17", retrievedCourse.getDescr().getFormatted());
140 
141             assertEquals(2, retrievedCourse.getFormats().size());
142             FormatInfo info = retrievedCourse.getFormats().get(0);
143             assertEquals("kuali.lu.type.CreditCourseFormatShell", info.getType());
144             assertEquals(2, info.getActivities().size());
145             assertTrue(info.getActivities().get(1).getActivityType().startsWith("kuali.lu.type.activity."));
146 
147             assertEquals(2, retrievedCourse.getTermsOffered().size());
148             String termOffered = retrievedCourse.getTermsOffered().get(0);
149 
150             assertTrue("termsOffered-48".equals(termOffered) || "termsOffered-49".equals(termOffered));
151 
152             assertEquals(2, retrievedCourse.getUnitsContentOwner().size());
153             String orgId = retrievedCourse.getUnitsContentOwner().get(0);
154             assertTrue("unitsContentOwner-53".equals(orgId) || "unitsContentOwner-54".equals(orgId));
155 
156             assertEquals(4, retrievedCourse.getAttributes().size());
157             String[] attrKeys = {"attributes-3", "attributes-4"};
158             for (String key : attrKeys) {
159                 String value = retrievedCourse.getAttributes().get(key);
160                 assertNotNull(value);
161                 assertEquals(key, value);
162             }
163 
164             assertEquals(2, retrievedCourse.getCampusLocations().size());
165             String campus = retrievedCourse.getCampusLocations().get(1);
166             assertTrue(CourseAssemblerConstants.COURSE_CAMPUS_LOCATION_CD_SOUTH.equals(campus) || CourseAssemblerConstants.COURSE_CAMPUS_LOCATION_CD_NORTH.equals(campus));
167 
168             /*
169              * Test LO assertEquals(2, retrievedCourse.getCourseSpecificLOs().size()); LoDisplayInfo info =
170              * retrievedCourse.getCourseSpecificLOs().get(0); // TODO - check its contents
171              */
172 
173             /*
174              * assertEquals(2, retrievedCourse.getCrossListings().size()); CourseCrossListingInfo info =
175              * retrievedCourse.getCrossListings().get(0); // TODO - check its contents
176              */
177 
178             assertEquals("unitsDeployment-57", retrievedCourse.getUnitsDeployment().get(0));
179 
180             TimeAmountInfo timeInfo = retrievedCourse.getDuration();
181             assertEquals("kuali.atp.duration.Semester", timeInfo.getAtpDurationTypeKey());
182             assertEquals(19, timeInfo.getTimeQuantity().intValue());
183 
184             // TODO - check effective/expiration dates
185 
186             // TODO - check feeInfo
187 
188             // TODO - check joints
189             // TODO - check metaInfo
190 
191             assertEquals(2, retrievedCourse.getTermsOffered().size());
192 
193             String atpType = retrievedCourse.getTermsOffered().get(0);
194             CluInstructorInfo instructor = retrievedCourse.getPrimaryInstructor();
195 
196             assertTrue("termsOffered-48".equals(atpType) || "termsOffered-49".equals(atpType));
197 
198             assertEquals("orgId-43", instructor.getOrgId());
199             assertEquals("personId-44", instructor.getPersonId());
200 
201             assertEquals(DtoConstants.STATE_DRAFT, retrievedCourse.getState());
202             assertTrue(subjectAreaSet.contains(retrievedCourse.getSubjectArea()));
203 
204             assertEquals("kuali.lu.type.CreditCourse", retrievedCourse.getType());
205 
206             assertEquals(2, retrievedCourse.getCreditOptions().size());
207             assertEquals("kuali.creditType.credit.degree.11.0", retrievedCourse.getCreditOptions().get(0).getId());
208             assertEquals("kuali.creditType.credit.degree.11.0", retrievedCourse.getCreditOptions().get(1).getId());
209 
210             assertEquals(2, retrievedCourse.getGradingOptions().size());
211 
212             assertTrue(retrievedCourse.getGradingOptions().contains("gradingOptions-31"));
213             assertTrue(retrievedCourse.getGradingOptions().contains("gradingOptions-32"));
214             assertEquals(createdCourse.isPilotCourse(), cInfo.isPilotCourse());
215             assertEquals(createdCourse.isSpecialTopicsCourse(), cInfo.isSpecialTopicsCourse());
216 
217             // TODO - check variotions
218         } catch (Exception e) {
219             e.printStackTrace();
220             fail(e.getMessage());
221         }
222     }
223 
224     @Test
225     public void testUpdateCourse() throws Exception {
226         System.out.println("testUpdateCourse");
227 
228         CourseDataGenerator generator = new CourseDataGenerator();
229         CourseInfo cInfo = null;
230         CourseInfo retrievedCourse = null;
231         CourseInfo updatedCourse = null;
232         CourseInfo createdCourse = null;
233         try {
234             System.out.println("Getting test data...");
235             cInfo = generator.getCourseTestData();
236         } catch (Exception ex) {
237             ex.printStackTrace();
238             fail("Got exception getting test data:" + ex.getMessage());
239         }
240 
241         assertNotNull(cInfo);
242         cInfo.setSpecialTopicsCourse(true);
243         cInfo.setPilotCourse(true);
244         try {
245             System.out.println("creating course...");
246             createdCourse = courseService.createCourse(cInfo);
247         } catch (DataValidationErrorException e) {
248             dumpValidationErrors(cInfo);
249             fail("DataValidationError: " + e.getMessage());
250         } catch (Exception ex) {
251             ex.printStackTrace();
252             fail("failed creating course" + ":" + ex.getMessage());
253         }
254         int initialFormatCount = createdCourse.getFormats().size();
255 
256         // minimal sanity check
257         assertNotNull(createdCourse);
258         assertEquals("kuali.lu.type.CreditCourse", createdCourse.getType());
259         assertEquals("courseTitle-12", createdCourse.getCourseTitle());
260         assertEquals(2, createdCourse.getUnitsContentOwner().size());
261         assertEquals(4, createdCourse.getAttributes().size());
262 
263         // update some fields
264         createdCourse.getUnitsContentOwner().clear();
265         AdminOrgInfo testCurrOrg = new AdminOrgInfo();
266         testCurrOrg.setOrgId("testOrgId");
267         testCurrOrg.setType(CourseAssemblerConstants.SUBJECT_ORG);
268         createdCourse.getUnitsContentOwner().add("testOrgId");
269 
270         // Delete One Format
271         createdCourse.getFormats().remove(0);
272 
273         // Delete One Activity from Existing Format
274         assertEquals(2, createdCourse.getFormats().get(0).getActivities().size());
275         createdCourse.getFormats().get(0).getActivities().remove(0);
276         String updActFrmtId = createdCourse.getFormats().get(0).getId();
277 
278         // Add two New formats
279         FormatInfo newFormat = new FormatInfo();
280         newFormat.setType(CourseAssemblerConstants.COURSE_FORMAT_TYPE);
281         newFormat.setState(DtoConstants.STATE_DRAFT);
282         
283         TimeAmountInfo timeInfo = new TimeAmountInfo();
284         timeInfo.setAtpDurationTypeKey("kuali.atp.duration.Semester");
285         timeInfo.setTimeQuantity(12);        
286         newFormat.setDuration(timeInfo);
287         
288         List<String> termsOfferedList = new ArrayList<String>();
289         termsOfferedList.add("FALL2010");        
290         newFormat.setTermsOffered(termsOfferedList);
291         
292         Map<String, String> attrMap = new HashMap<String, String>();
293         attrMap.put("FRMT", "value");
294         newFormat.setAttributes(attrMap);
295 
296         // Add two new activities to new formats
297         ActivityInfo newActivity1 = new ActivityInfo();
298         newActivity1.setActivityType(CourseAssemblerConstants.COURSE_ACTIVITY_DIRECTED_TYPE);
299         newActivity1.setState(DtoConstants.STATE_DRAFT);
300         newFormat.getActivities().add(newActivity1);
301 
302         ActivityInfo newActivity2 = new ActivityInfo();
303         newActivity2.setActivityType(CourseAssemblerConstants.COURSE_ACTIVITY_LAB_TYPE);
304         newActivity2.setState(DtoConstants.STATE_DRAFT);
305         newFormat.getActivities().add(newActivity2);
306 
307         createdCourse.getFormats().add(newFormat);
308 
309         FormatInfo newFormat2 = new FormatInfo();
310         newFormat2.setType(CourseAssemblerConstants.COURSE_FORMAT_TYPE);
311         newFormat2.setState(DtoConstants.STATE_DRAFT);
312         createdCourse.getFormats().add(newFormat2);
313 
314         Map<String, String> attributes = createdCourse.getAttributes();
315         attributes.put("testKey", "testValue");
316         createdCourse.setAttributes(attributes);
317 
318         createdCourse.getCreditOptions().remove(1);
319         ResultComponentInfo rsltComp = new ResultComponentInfo();
320         rsltComp.setType(CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_MULTIPLE);
321         rsltComp.getResultValues().add("1");
322         rsltComp.getResultValues().add("3");
323         createdCourse.getCreditOptions().add(rsltComp);
324         createdCourse.getGradingOptions().remove(1);
325         createdCourse.getGradingOptions().add("NewGradingOption");
326 
327         createdCourse.setSpecialTopicsCourse(false);
328         createdCourse.setPilotCourse(false);
329 
330         createdCourse.getCourseSpecificLOs().get(0).getLoInfo().getDesc().setPlain("UPDATED!!!");
331         createdCourse.getCourseSpecificLOs().remove(1);
332         LoDisplayInfo displayInfo = new LoDisplayInfo();
333         displayInfo.setLoInfo(new LoInfo());
334         displayInfo.getLoInfo().setDesc(new RichTextInfo());
335         createdCourse.getCourseSpecificLOs().add(displayInfo);
336         createdCourse.getCourseSpecificLOs().get(1).getLoInfo().getDesc().setPlain("BrandNew!!!");
337         createdCourse.getCourseSpecificLOs().get(1).getLoCategoryInfoList().add(new LoCategoryInfo());
338         createdCourse.getCourseSpecificLOs().get(1).getLoCategoryInfoList().get(0).setId("category-3");
339 
340         createdCourse.getFeeJustification().setFormatted("NEWJUSTIFICATION");
341         createdCourse.getFees().clear();
342         createdCourse.getFees().add(new CourseFeeInfo());
343         createdCourse.getFees().get(0).setFeeType("UpdatedFeeType");
344         createdCourse.getFees().get(0).getFeeAmounts().clear();
345         createdCourse.getFees().get(0).getFeeAmounts().add(new CurrencyAmountInfo());
346         createdCourse.getFees().get(0).getFeeAmounts().get(0).setCurrencyQuantity(10);
347         createdCourse.getFees().get(0).getFeeAmounts().get(0).setCurrencyTypeKey("PESOS");
348         createdCourse.getRevenues().get(0).getAffiliatedOrgs().clear();
349         createdCourse.getRevenues().get(0).getAffiliatedOrgs().add(new AffiliatedOrgInfo());
350         createdCourse.getRevenues().get(0).getAffiliatedOrgs().get(0).setOrgId("NEWORG");
351         createdCourse.getRevenues().get(0).getAffiliatedOrgs().get(0).setPercentage(Long.valueOf(99));
352         
353         createdCourse.setSubjectArea(null);
354         createdCourse.setCode("UpdatedCode100");
355         createdCourse.setLevel("Level100");        
356         
357         // Perform the update
358         try {
359             System.out.println("updating course...");
360             updatedCourse = courseService.updateCourse(createdCourse);
361         } catch (DataValidationErrorException e) {
362             dumpValidationErrors(createdCourse);
363             fail("DataValidationError: " + e.getMessage());
364         } catch (Exception ex) {
365             ex.printStackTrace();
366             fail("failed updating course: " + ex.getMessage());
367         }
368         assertEquals(initialFormatCount + 1, updatedCourse.getFormats().size());
369 
370         for (FormatInfo uFrmt : updatedCourse.getFormats()) {
371             // Check to see if activities are added to a new format
372             if (uFrmt.getAttributes().containsKey("FRMT")) {
373                 assertEquals(2, uFrmt.getActivities().size());
374                 String actType = uFrmt.getActivities().get(0).getActivityType();
375                 assertTrue(CourseAssemblerConstants.COURSE_ACTIVITY_DIRECTED_TYPE.equals(actType) || CourseAssemblerConstants.COURSE_ACTIVITY_LAB_TYPE.equals(actType));
376 
377                 assertEquals(1, uFrmt.getTermsOffered().size());
378                 assertEquals("FALL2010", uFrmt.getTermsOffered().get(0));
379                 
380                 TimeAmountInfo tIfo = uFrmt.getDuration();
381                 assertNotNull(tIfo);
382                 assertEquals((int)12, (int) tIfo.getTimeQuantity());
383             }
384 
385             // Check to see if activity is deleted from an existing format
386             if (updActFrmtId.equals(uFrmt.getId())) {
387                 assertEquals(1, uFrmt.getActivities().size());
388             }
389         }
390         // Test what was returned by updateCourse
391         verifyUpdate(updatedCourse);
392 
393         // Now explicitly get it
394         try {
395             System.out.println("Getting course again...");
396             retrievedCourse = courseService.getCourse(createdCourse.getId());
397         } catch (Exception ex) {
398             ex.printStackTrace();
399             fail("failed getting course again:" + ex.getMessage());
400         }
401         verifyUpdate(retrievedCourse);
402 
403         // and test for optimistic lock exception
404         // NOTE: CourseService.updateCourse(CourseInfo courseInfo) modifies its parameter,
405         // as the 'results' BusinessDTORef (our CourseInfo) is simply updated to reflect
406         // the new contents of the updated Clu (see the
407         // results.getAssembler().assemble(updatedClu, results.getBusinessDTORef(), true);
408         // line in CourseServiceMethodInvoker.invokeServiceCalls()
409         int currVersion = Integer.parseInt(retrievedCourse.getMetaInfo().getVersionInd());
410         if (currVersion > 0) {
411             retrievedCourse.getMetaInfo().setVersionInd(Integer.toString(--currVersion));
412         }
413         try {
414             System.out.println("Updating course again trying to get a version mismatch...");
415             courseService.updateCourse(retrievedCourse);
416             fail("Failed to throw VersionMismatchException");
417         } catch (VersionMismatchException e) {
418             System.out.println("Correctly received " + e.getMessage());
419         } catch (DataValidationErrorException e) {
420             dumpValidationErrors(retrievedCourse);
421             fail("DataValidationError: " + e.getMessage());
422         } catch (Exception e) {
423             e.printStackTrace();
424             fail(e.getMessage());
425         }
426     }
427 
428     private void verifyUpdate(CourseInfo updatedCourse) {
429         assertNotNull(updatedCourse);
430 
431         assertEquals(1, updatedCourse.getUnitsContentOwner().size());
432         assertEquals("testOrgId", updatedCourse.getUnitsContentOwner().get(0));
433 
434         assertEquals(5, updatedCourse.getAttributes().size());
435         assertNotNull(updatedCourse.getAttributes().get("testKey"));
436         assertEquals("testValue", updatedCourse.getAttributes().get("testKey"));
437 
438         assertEquals(2, updatedCourse.getCreditOptions().size());
439         // assertTrue(updatedCourse.getCreditOptions().contains("creditOptions-18"));
440         // assertTrue(updatedCourse.getCreditOptions().contains("NewCreditOption"));
441 
442         assertEquals(2, updatedCourse.getGradingOptions().size());
443 
444         assertTrue(updatedCourse.getGradingOptions().contains("gradingOptions-31"));
445         assertTrue(updatedCourse.getGradingOptions().contains("NewGradingOption"));
446 
447         assertFalse(updatedCourse.isSpecialTopicsCourse());
448         assertFalse(updatedCourse.isPilotCourse());
449 
450         assertNull(updatedCourse.getSubjectArea());
451         assertEquals("UpdatedCode100", updatedCourse.getCode());
452         assertEquals("Level100", updatedCourse.getLevel());
453         assertEquals("NEWJUSTIFICATION", updatedCourse.getFeeJustification().getFormatted());
454         assertEquals("UpdatedFeeType", updatedCourse.getFees().get(0).getFeeType());
455         assertEquals(Integer.valueOf(10), updatedCourse.getFees().get(0).getFeeAmounts().get(0).getCurrencyQuantity());
456         assertEquals("PESOS", updatedCourse.getFees().get(0).getFeeAmounts().get(0).getCurrencyTypeKey());
457         assertEquals("NEWORG", updatedCourse.getRevenues().get(0).getAffiliatedOrgs().get(0).getOrgId());
458         assertEquals(Long.valueOf(99), updatedCourse.getRevenues().get(0).getAffiliatedOrgs().get(0).getPercentage());
459     }
460 
461     @Test
462     public void testDeleteCourse() {
463         System.out.println("testDeleteCourse");
464         try {
465             CourseDataGenerator generator = new CourseDataGenerator();
466             CourseInfo cInfo = generator.getCourseTestData();
467             assertNotNull(cInfo);
468             CourseInfo createdCourse = courseService.createCourse(cInfo);
469             assertNotNull(createdCourse);
470             assertEquals(DtoConstants.STATE_DRAFT, createdCourse.getState());
471             assertEquals("kuali.lu.type.CreditCourse", createdCourse.getType());
472             String courseId = createdCourse.getId();
473             CourseInfo retrievedCourse = courseService.getCourse(courseId);
474             assertNotNull(retrievedCourse);
475 
476             courseService.deleteCourse(courseId);
477             try {
478                 retrievedCourse = courseService.getCourse(courseId);
479                 fail("Retrieval of deleted course should have thrown exception");
480             } catch (DoesNotExistException e) {}
481         } catch (Exception e) {
482             fail(e.getMessage());
483         }
484     }
485 
486     /**
487      * 
488      * This method tests setting code, attributes in course cross listing
489      *
490      */
491     @Test
492     public void testCourseCrossListing() {
493         CourseDataGenerator generator = new CourseDataGenerator();
494         try {
495             CourseInfo cInfo = generator.getCourseTestData();
496             assertNotNull(cInfo);
497 
498            
499             CourseCrossListingInfo ccInfo = new CourseCrossListingInfo();
500             ccInfo.setCourseNumberSuffix("100");
501             ccInfo.setSubjectArea("CHEM");
502             
503             Map<String, String> da = new HashMap<String, String>();
504             da.put("KEY1", "VALUE1");
505             
506             ccInfo.setAttributes(da);
507             
508             CourseCrossListingInfo ccInfo1 = new CourseCrossListingInfo();
509             ccInfo1.setCourseNumberSuffix("200");
510             ccInfo1.setSubjectArea("MATH");
511             ccInfo1.setCode("LIFE042");
512 
513             List<CourseCrossListingInfo> ccList = new ArrayList<CourseCrossListingInfo>();
514             ccList.add(ccInfo);
515             ccList.add(ccInfo1);
516 
517             cInfo.setCrossListings(ccList);
518             
519             try {
520                 cInfo = courseService.createCourse(cInfo);
521             } catch (DataValidationErrorException e) {
522                 dumpValidationErrors(cInfo);
523                 fail("DataValidationError: " + e.getMessage());
524             } catch (Exception e) {
525                 e.printStackTrace();
526                 fail("failed creating course:" + e.getMessage());
527             }
528             
529             CourseInfo rcInfo = courseService.getCourse(cInfo.getId());
530             
531             assertEquals(2,rcInfo.getCrossListings().size());
532             
533             for(CourseCrossListingInfo rcc : rcInfo.getCrossListings()) {
534                 
535                 if("100".equals(rcc.getCourseNumberSuffix())) {                   
536                     assertEquals("VALUE1", rcc.getAttributes().get("KEY1"));
537                 } else {
538                     assertEquals("LIFE042", rcc.getCode());
539                 }                
540             }
541             
542         } catch (Exception e) {
543             System.out.println("caught exception: " + e.getClass().getName());
544             System.out.println("message: " + e.getMessage());
545             e.printStackTrace(System.out);
546             e.printStackTrace();
547             fail(e.getMessage());
548         }        
549             
550     }
551     
552     @Test
553     public void testCreditOptions() {
554         CourseDataGenerator generator = new CourseDataGenerator();
555         try {
556             CourseInfo cInfo = generator.getCourseTestData();
557             assertNotNull(cInfo);
558             
559             // Check to see if variable credit with float increment works
560             ResultComponentInfo rc1 = new ResultComponentInfo();
561             rc1.setType(CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_VARIABLE);
562             HashMap<String, String> attributes = new HashMap<String,String>();
563             attributes.put(CourseAssemblerConstants.COURSE_RESULT_COMP_ATTR_MIN_CREDIT_VALUE, "1.0");
564             attributes.put(CourseAssemblerConstants.COURSE_RESULT_COMP_ATTR_MAX_CREDIT_VALUE, "5.0");
565             attributes.put(CourseAssemblerConstants.COURSE_RESULT_COMP_ATTR_CREDIT_VALUE_INCR, "0.5");
566             rc1.setAttributes(attributes);
567             
568             // Check to see if variable credit with no increments
569             ResultComponentInfo rc2 = new ResultComponentInfo();
570             rc2.setType(CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_VARIABLE);
571             HashMap<String, String> attributes2 = new HashMap<String,String>();
572             attributes2.put(CourseAssemblerConstants.COURSE_RESULT_COMP_ATTR_MIN_CREDIT_VALUE, "1.0");
573             attributes2.put(CourseAssemblerConstants.COURSE_RESULT_COMP_ATTR_MAX_CREDIT_VALUE, "5.0");
574             rc2.setAttributes(attributes2);
575             
576             // Check to see floating point multiple is accepted
577             ResultComponentInfo rc3 = new ResultComponentInfo();
578             rc3.setType(CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_MULTIPLE);
579             List<String> rv = new ArrayList<String>();
580             rv.add("1.0");
581             rv.add("1.5");
582             rv.add("2.0");
583             rc3.setResultValues(rv);
584             
585 
586             List<ResultComponentInfo> creditOptions = new ArrayList<ResultComponentInfo>();
587             creditOptions.add(rc1);
588             creditOptions.add(rc2);
589             creditOptions.add(rc3);
590                         
591             cInfo.setCreditOptions(creditOptions);
592                         
593             try {
594                 cInfo = courseService.createCourse(cInfo);
595             } catch (DataValidationErrorException e) {
596                 dumpValidationErrors(cInfo);
597                 fail("DataValidationError: " + e.getMessage());
598             } catch (Exception e) {
599                 e.printStackTrace();
600                 fail("failed creating course:" + e.getMessage());
601             }
602             
603             CourseInfo rcInfo = courseService.getCourse(cInfo.getId());
604             
605             List<ResultComponentInfo> co = rcInfo.getCreditOptions();
606             
607             assertEquals(3, co.size());
608             
609             // Check to see if multiple was set properly
610             for(ResultComponentInfo rc : co) {
611                 if(CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_MULTIPLE.equals(rc.getType())){
612                     assertEquals(3, rc.getResultValues().size());
613                     assertTrue(rc.getResultValues().contains("1.0"));
614                     assertTrue(rc.getResultValues().contains("1.5"));
615                     assertTrue(rc.getResultValues().contains("2.0"));                    
616                 }
617                 
618                 if(CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_VARIABLE.equals(rc.getType())){
619                     if(3 == rc.getAttributes().size()) {
620                         assertEquals(9, rc.getResultValues().size());
621                         assertTrue(rc.getResultValues().contains("1.5"));
622                     } else {                        
623                         assertEquals(5, rc.getResultValues().size());
624                         assertTrue(rc.getResultValues().contains("3.0"));
625                     }
626                 }                
627             }
628                         
629             
630         } catch (Exception e) {
631             System.out.println("caught exception: " + e.getClass().getName());
632             System.out.println("message: " + e.getMessage());
633             e.printStackTrace(System.out);
634             e.printStackTrace();
635             fail(e.getMessage());
636         }        
637     }
638     
639     @Test
640     public void testDynamicAttributes() {
641         System.out.println("testDynamicAttributes");
642         CourseDataGenerator generator = new CourseDataGenerator();
643         try {
644             CourseInfo cInfo = generator.getCourseTestData();
645                         
646             assertNotNull(cInfo);
647 
648             Map<String, String> attrMap = new HashMap<String, String>();
649             attrMap.put("finalExamStatus", "GRD");
650             attrMap.put("altFinalExamStatusDescr", "Some123description");
651             attrMap.put("proposalTitle", "proposalTitle-1");
652             attrMap.put("proposalRationale", "proposalRationale");
653 
654             cInfo.setAttributes(attrMap);
655 
656             FormatInfo fInfo = new FormatInfo();
657             fInfo.setType(CourseAssemblerConstants.COURSE_FORMAT_TYPE);
658             ActivityInfo aInfo = new ActivityInfo();
659             aInfo.setActivityType(CourseAssemblerConstants.COURSE_ACTIVITY_DIRECTED_TYPE);
660             Map<String, String> activityAttrs = new HashMap<String, String>();
661             activityAttrs.put("ACTIVITY_KEY", "ACTIVITY_VALUE");
662             aInfo.setAttributes(activityAttrs);
663             
664             List<ActivityInfo> activities = new ArrayList<ActivityInfo>();
665             activities.add(aInfo);                       
666             fInfo.setActivities(activities);
667            
668             List<FormatInfo> formats = new ArrayList<FormatInfo>();
669             formats.add(fInfo);
670             
671             cInfo.setFormats(formats);
672             
673             try {
674                 cInfo = courseService.createCourse(cInfo);
675             } catch (DataValidationErrorException e) {
676                 dumpValidationErrors(cInfo);
677                 fail("DataValidationError: " + e.getMessage());
678             } catch (Exception e) {
679                 e.printStackTrace();
680                 fail("failed creating course:" + e.getMessage());
681             }
682             // Check in LuService if the attributes are mapped properly
683 
684             // CourseInfo rInfo = courseService.getCourse(cInfo.getId());
685 
686             assertEquals("GRD", cInfo.getAttributes().get("finalExamStatus"));
687             assertEquals("Some123description", cInfo.getAttributes().get("altFinalExamStatusDescr"));
688 
689             
690             // Check if the attributes are being set in the activity
691             assertEquals("ACTIVITY_VALUE", cInfo.getFormats().get(0).getActivities().get(0).getAttributes().get("ACTIVITY_KEY"));
692             
693         } catch (Exception e) {
694             System.out.println("caught exception: " + e.getClass().getName());
695             System.out.println("message: " + e.getMessage());
696             e.printStackTrace(System.out);
697             e.printStackTrace();
698             fail(e.getMessage());
699         }
700 
701     }
702 
703     @Test
704     public void testCluIsUpdated() {
705 
706     }
707 
708     @Test
709     public void testGetMetadata() {
710         System.out.println("testGetMetadata");
711         MetadataServiceImpl metadataService = new MetadataServiceImpl(courseService);
712         metadataService.setUiLookupContext("classpath:lum-ui-test-lookup-context.xml");
713         Metadata metadata = metadataService.getMetadata("org.kuali.student.lum.course.dto.CourseInfo");
714 
715         Map<String, Metadata> properties = metadata.getProperties();
716         assertTrue(properties.size() > 0);
717 
718         assertTrue(properties.containsKey("state"));
719         assertTrue(properties.containsKey("campusLocations"));
720 
721         assertTrue(properties.containsKey("formats"));
722         metadata = properties.get("formats");
723 
724         properties = metadata.getProperties();
725         assertTrue(properties.containsKey("*"));
726         metadata = properties.get("*");
727 
728         properties = metadata.getProperties();
729         assertTrue(properties.containsKey("activities"));
730         metadata = properties.get("activities");
731 
732         properties = metadata.getProperties();
733         assertTrue(properties.containsKey("*"));
734         metadata = properties.get("*");
735 
736         properties = metadata.getProperties();
737         assertFalse(properties.containsKey("foo"));
738 
739         return;
740     }
741 
742     @Test
743     public void testCourseVersioning() throws IllegalArgumentException, SecurityException, IntrospectionException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, VersionMismatchException, DoesNotExistException, CircularRelationshipException, DependentObjectsExistException, UnsupportedActionException, IllegalVersionSequencingException {
744         CourseDataGenerator generator = new CourseDataGenerator();
745         CourseInfo cInfo = generator.getCourseTestData();
746         CourseInfo createdCourse = courseService.createCourse(cInfo);
747 
748         CourseInfo newCourse = null;
749         try {
750             newCourse = courseService.createNewCourseVersion(createdCourse.getVersionInfo().getVersionIndId(), "test make a new version");
751             assertTrue(true);
752         } catch (Exception e) {
753             assertTrue(false);
754         }
755 
756         assertNotNull(newCourse);
757         
758         
759         // test that creating a new course version copies over statements
760         StatementTreeViewInfo statementTreeViewInfo = createStatementTree();
761         StatementTreeViewInfo createdTree = courseService.createCourseStatement(createdCourse.getId(), statementTreeViewInfo);
762         assertNotNull(createdTree);
763         
764         CourseInfo newVersion = null;
765         
766         try {
767             newVersion = courseService.createNewCourseVersion(createdCourse.getVersionInfo().getVersionIndId(), "test make a new version for statements");
768             assertTrue(true);
769         } catch (Exception e) {
770             e.printStackTrace();
771             assertTrue(false);
772         }
773 
774         assertNotNull(newVersion);
775         
776 
777     }
778 
779     @Test
780     public void testGetCourseStatement() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
781 
782         String courseId = "COURSE-STMT-1";
783         List<StatementTreeViewInfo> courseStatements = courseService.getCourseStatements(courseId, null, null);
784         assertEquals(2, courseStatements.size());
785         for (StatementTreeViewInfo tree : courseStatements) {
786             checkTreeView(tree, false);
787         }
788         
789         // test that the proper error message occurs if an invalid Clu id is attempted
790         String credentialProgramId = "d02dbbd3-20e2-410d-ab52-1bd6d362748b";
791         
792         try {
793             courseService.getCourseStatements(credentialProgramId, null, null);
794             assertTrue(false);
795         }
796         catch(DoesNotExistException e) {
797             // we should reach here, since the exception should trigger
798             assertTrue(true);
799         }
800     }
801 
802     @Test
803     @Ignore
804     // FIXME
805     public void testGetCourseStatement_nl() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
806 
807         String courseId = "COURSE-STMT-1";
808         String nlUsageTypeKey = "KUALI.RULE";
809         String language = "en";
810         List<StatementTreeViewInfo> courseStatements = courseService.getCourseStatements(courseId, nlUsageTypeKey, language);
811         assertEquals(2, courseStatements.size());
812         for (StatementTreeViewInfo tree : courseStatements) {
813             checkTreeView(tree, true);
814         }
815     }
816 
817     @Test
818     public void testCreateCourseStatement() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DataValidationErrorException {
819         final String courseId = "COURSE-STMT-1";
820 
821         StatementTreeViewInfo statementTreeViewInfo = createStatementTree();
822         StatementTreeViewInfo createdTree = courseService.createCourseStatement(courseId, statementTreeViewInfo);
823         assertNotNull(createdTree);
824         assertEquals(2, createdTree.getStatements().size());
825     }
826 
827     @Test(expected = InvalidParameterException.class)
828     public void testCreateCourseStatement_duplicateTree() throws Exception {
829         String courseId = "COURSE-STMT-1";
830         String nlUsageTypeKey = "KUALI.RULE";
831         String language = "en";
832         List<StatementTreeViewInfo> courseStatements = courseService.getCourseStatements(courseId, nlUsageTypeKey, language);
833         courseService.createCourseStatement(courseId, courseStatements.get(0));
834     }
835 
836     @Test(expected = MissingParameterException.class)
837     public void testCreateCourseStatement_nullCourseId() throws Exception {
838 
839         StatementTreeViewInfo statementTreeViewInfo = createStatementTree();
840         @SuppressWarnings("unused")
841         StatementTreeViewInfo createdTree = courseService.createCourseStatement(null, statementTreeViewInfo);
842     }
843 
844     @Test(expected = MissingParameterException.class)
845     public void testCreateCourseStatement_nullTree() throws Exception {
846         String courseId = "COURSE-STMT-1";
847 
848         @SuppressWarnings("unused")
849         StatementTreeViewInfo createdTree = courseService.createCourseStatement(courseId, null);
850     }
851 
852     @Test(expected = DoesNotExistException.class)
853     public void testDeleteCourseStatement() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DataValidationErrorException, CircularReferenceException, VersionMismatchException {
854         final String courseId = "COURSE-STMT-1";
855 
856         StatementTreeViewInfo statementTreeViewInfo = createStatementTree();
857         StatementTreeViewInfo createdTree = courseService.createCourseStatement(courseId, statementTreeViewInfo);
858         StatusInfo status = courseService.deleteCourseStatement(courseId, createdTree);
859         assertTrue(status.getSuccess());
860         List<StatementTreeViewInfo> statements = courseService.getCourseStatements(courseId, null, null);
861         for (StatementTreeViewInfo statement : statements) {
862             if (statement.getId().equals(createdTree.getId())) {
863                 fail("StatementTree not deleted from course");
864             }
865         }
866         statementService.getStatementTreeView(createdTree.getId());
867     }
868 
869     @Test(expected = DoesNotExistException.class)
870     public void testDeleteCourseStatement_badTree() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
871         final String courseId = "COURSE-STMT-1";
872 
873         StatementTreeViewInfo statementTreeViewInfo = createStatementTree();
874         courseService.deleteCourseStatement(courseId, statementTreeViewInfo);
875     }
876 
877     @Test(expected = DoesNotExistException.class)
878     public void testDeleteCourseStatement_badCourse() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
879         StatementTreeViewInfo statementTreeViewInfo = createStatementTree();
880         courseService.deleteCourseStatement("xxx", statementTreeViewInfo);
881     }
882 
883     @Test(expected = MissingParameterException.class)
884     public void testDeleteCourseStatement_nullCourseId() throws Exception {
885         StatementTreeViewInfo statementTreeViewInfo = createStatementTree();
886         courseService.deleteCourseStatement(null, statementTreeViewInfo);
887     }
888 
889     @Test(expected = MissingParameterException.class)
890     public void testDeleteCourseStatement_nullTreeId() throws Exception {
891         courseService.deleteCourseStatement("xxx", null);
892     }
893 
894     @Test
895     public void testUpdateCourseStatement() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DataValidationErrorException, CircularReferenceException, VersionMismatchException {
896         final String courseId = "COURSE-STMT-1";
897 
898         StatementTreeViewInfo statementTreeViewInfo = createStatementTree();
899         StatementTreeViewInfo createdTree = courseService.createCourseStatement(courseId, statementTreeViewInfo);
900 
901         List<ReqComponentInfo> reqCompList1 = new ArrayList<ReqComponentInfo>(3);
902         ReqComponentInfo rc1 = new ReqComponentInfo();
903         rc1.setDesc(toRichText("REQCOMP-1"));
904         rc1.setType("kuali.reqComponent.type.course.courseset.completed.all");
905         ReqComponentInfo rc2 = new ReqComponentInfo();
906         rc2.setDesc(toRichText("REQCOMP-2"));
907         rc2.setType("kuali.reqComponent.type.course.courseset.gpa.min");
908         StatementTreeViewInfo subTree1 = new StatementTreeViewInfo();
909         subTree1.setDesc(toRichText("STMT-5"));
910         subTree1.setOperator(StatementOperatorTypeKey.AND);
911         subTree1.setType("kuali.statement.type.program.entrance");
912         reqCompList1.add(rc1);
913         reqCompList1.add(rc2);
914         subTree1.setReqComponents(reqCompList1);
915 
916         StatementTreeViewInfo oldSubTree1 = createdTree.getStatements().get(0);
917         createdTree.getStatements().set(0, subTree1);
918         StatementTreeViewInfo updatedTree = courseService.updateCourseStatement(courseId, statementTreeViewInfo);
919         assertEquals(createdTree.getStatements().get(0).getDesc().getPlain(), updatedTree.getStatements().get(0).getDesc().getPlain());
920 
921     }
922 
923     @Test
924     @Ignore
925     // FIXME need a dictionary that defines StatamentTreeViewInfo
926     public void testValidataCourseStatement() throws Exception {
927         final String courseId = "COURSE-STMT-1";
928 
929         StatementTreeViewInfo statementTreeViewInfo = createStatementTree();
930         courseService.validateCourseStatement(courseId, statementTreeViewInfo);
931         List<ValidationResultInfo> validations = courseService.validateCourseStatement(courseId, statementTreeViewInfo);
932         assertTrue(isEmpty(validations));
933     }
934 
935     @Test
936     @Ignore
937     // FIXME need a dictionary that defines StatamentTreeViewInfo
938     public void testValidataCourseStatement_invalidStatement() throws InvalidParameterException, MissingParameterException, OperationFailedException {
939         final String courseId = "COURSE-STMT-1";
940 
941         StatementTreeViewInfo statementTreeViewInfo = createStatementTree();
942         statementTreeViewInfo.setType("an.example.of.a.bad.statementType");
943         statementTreeViewInfo.getStatements().get(0).setType("fictional.program");
944         statementTreeViewInfo.getStatements().get(0).getReqComponents().set(0, createBadReqComponent());
945         List<ValidationResultInfo> validations = courseService.validateCourseStatement(courseId, statementTreeViewInfo);
946         assertFalse(isEmpty(validations));
947     }
948 
949     private static ReqComponentInfo createBadReqComponent() {
950         ReqComponentInfo reqCompInfo = new ReqComponentInfo();
951         // reqCompInfo.setId("REQCOMP-NL-X");
952         reqCompInfo.setId("1234567890123456789012345678901234567890");
953         reqCompInfo.setType("kuali.reqComponent.type.courseList.nof");
954         reqCompInfo.setState("Active");
955 
956         List<ReqCompFieldInfo> fieldList = new ArrayList<ReqCompFieldInfo>();
957 
958         ReqCompFieldInfo field1 = new ReqCompFieldInfo();
959         field1.setId("1234567890123456789012345678901234567890");
960         field1.setType("kuali.reqComponent.field.type.operator");
961         field1.setValue("-1");
962         fieldList.add(field1);
963 
964         ReqCompFieldInfo field2 = new ReqCompFieldInfo();
965         field2.setId("2");
966         field2.setType("kuali.reqComponent.field.type.operator");
967         field2.setValue("greater_than_or_equal_to42");
968         fieldList.add(field2);
969 
970         ReqCompFieldInfo field3 = new ReqCompFieldInfo();
971         field3.setId("3");
972         field3.setType("kuali.reqComponent.field.type.cluSet.id");
973         field3.setValue("CLUSET-NL-Y");
974         fieldList.add(field3);
975 
976         reqCompInfo.setReqCompFields(fieldList);
977         return reqCompInfo;
978     }
979 
980     private static StatementTreeViewInfo createStatementTree() {
981         // Statement Tree
982         // --------- STMT-1:OR ---------
983         // | |
984         // STMT-2:AND STMT-3:AND
985         // | | | |
986         // REQCOMP-1 REQCOMP-2 REQCOMP-3 REQCOMP-4
987 
988         List<StatementTreeViewInfo> subStatements = new ArrayList<StatementTreeViewInfo>(3);
989         List<ReqComponentInfo> reqCompList1 = new ArrayList<ReqComponentInfo>(3);
990         List<ReqComponentInfo> reqCompList2 = new ArrayList<ReqComponentInfo>(3);
991 
992         // req components
993         ReqComponentInfo rc1 = new ReqComponentInfo();
994         rc1.setDesc(toRichText("REQCOMP-1"));
995         rc1.setType("kuali.reqComponent.type.course.courseset.completed.all");
996         ReqComponentInfo rc2 = new ReqComponentInfo();
997         rc2.setDesc(toRichText("REQCOMP-2"));
998         rc2.setType("kuali.reqComponent.type.course.courseset.gpa.min");
999         ReqComponentInfo rc3 = new ReqComponentInfo();
1000         rc3.setDesc(toRichText("REQCOMP-3"));
1001         rc3.setType("kuali.reqComponent.type.course.courseset.completed.nof");
1002         ReqComponentInfo rc4 = new ReqComponentInfo();
1003         rc4.setDesc(toRichText("REQCOMP-4"));
1004         rc4.setType("kuali.reqComponent.type.course.permission.instructor.required");
1005 
1006         // statement tree views
1007         StatementTreeViewInfo statementTree = new StatementTreeViewInfo();
1008         statementTree.setDesc(toRichText("STMT-1"));
1009         statementTree.setOperator(StatementOperatorTypeKey.OR);
1010         // statementTree.setType("kuali.statement.type.program.entrance");
1011         statementTree.setType("kuali.statement.type.course.academicReadiness.coreq");
1012 
1013         StatementTreeViewInfo subTree1 = new StatementTreeViewInfo();
1014         subTree1.setDesc(toRichText("STMT-2"));
1015         subTree1.setOperator(StatementOperatorTypeKey.AND);
1016         // subTree1.setType("kuali.statement.type.program.entrance");
1017         subTree1.setType("kuali.statement.type.course.recommendedPreparation");
1018 
1019         StatementTreeViewInfo subTree2 = new StatementTreeViewInfo();
1020         subTree2.setDesc(toRichText("STMT-3"));
1021         subTree2.setOperator(StatementOperatorTypeKey.AND);
1022         // subTree2.setType("kuali.statement.type.program.entrance");
1023         subTree2.setType("kuali.statement.type.course.academicReadiness.antireq");
1024 
1025         // construct tree with statements and req components
1026         reqCompList1.add(rc1);
1027         reqCompList1.add(rc2);
1028         subTree1.setReqComponents(reqCompList1);
1029         reqCompList2.add(rc3);
1030         reqCompList2.add(rc4);
1031         subTree2.setReqComponents(reqCompList2);
1032         subStatements.add(subTree1);
1033         subStatements.add(subTree2);
1034         statementTree.setStatements(subStatements);
1035 
1036         return statementTree;
1037     }
1038 
1039     private static RichTextInfo toRichText(String text) {
1040         RichTextInfo richTextInfo = new RichTextInfo();
1041         if (text == null) {
1042             return null;
1043         }
1044         richTextInfo.setPlain(text);
1045         richTextInfo.setFormatted("<p>" + text + "</p>");
1046         return richTextInfo;
1047     }
1048 
1049     private static void checkTreeView(final StatementTreeViewInfo rootTree, final boolean checkNaturalLanguage) {
1050         assertNotNull(rootTree);
1051         List<StatementTreeViewInfo> subTreeView = rootTree.getStatements();
1052         assertNotNull(subTreeView);
1053         assertEquals(2, subTreeView.size());
1054         StatementTreeViewInfo subTree1 = subTreeView.get(0);
1055         StatementTreeViewInfo subTree2 = subTreeView.get(1);
1056 
1057         // Check root tree
1058         assertNotNull(rootTree);
1059         assertEquals(2, subTreeView.size());
1060         assertNotNull(subTree1);
1061         assertNotNull(subTree2);
1062 
1063         // Check reqComps of sub-tree 1
1064         assertEquals("STMT-TV-2", subTree1.getId());
1065         assertEquals(2, subTree1.getReqComponents().size());
1066         assertEquals("REQCOMP-TV-1", subTree1.getReqComponents().get(0).getId());
1067         assertEquals("REQCOMP-TV-2", subTree1.getReqComponents().get(1).getId());
1068         if (checkNaturalLanguage) {
1069             assertEquals("Student must have completed all of MATH 152, MATH 180", subTree1.getReqComponents().get(0).getNaturalLanguageTranslation());
1070             assertEquals("Student needs a minimum GPA of 3.5 in MATH 152, MATH 180", subTree1.getReqComponents().get(1).getNaturalLanguageTranslation());
1071         }
1072 
1073         // Check reqComps of sub-tree 2
1074         assertEquals("STMT-TV-3", subTree2.getId());
1075         assertEquals(2, subTree2.getReqComponents().size());
1076         assertEquals("REQCOMP-TV-3", subTree2.getReqComponents().get(0).getId());
1077         assertEquals("REQCOMP-TV-4", subTree2.getReqComponents().get(1).getId());
1078         if (checkNaturalLanguage) {
1079             assertEquals("Student must have completed 1 of MATH 152, MATH 180", subTree2.getReqComponents().get(0).getNaturalLanguageTranslation());
1080             assertEquals("Student needs a minimum GPA of 4.0 in MATH 152, MATH 180", subTree2.getReqComponents().get(1).getNaturalLanguageTranslation());
1081         }
1082     }
1083     
1084     /**
1085      * 
1086      * This method checks for an UnsupportedOperationException to be thrown from the methods in the created list.
1087      * 
1088      */
1089     @Test
1090     public void testExpectedUnsupported() throws Exception {
1091         String[] unsupportedOperations = {"getCourseActivities", "getCourseFormats", "getCourseLos"};
1092         
1093         Collection<ServiceMethodInvocationData> methods = new ArrayList<ServiceMethodInvocationData>(unsupportedOperations.length);
1094         for(String s : unsupportedOperations) {
1095             ServiceMethodInvocationData invocationData = new ServiceMethodInvocationData();
1096             invocationData.methodName = s;
1097             invocationData.parameters = new Object[1];
1098             
1099             // all the parameter types for these methods are the same
1100             invocationData.paramterTypes = new Class<?>[] {String.class};
1101             methods.add(invocationData);
1102         }
1103         
1104         invokeForExpectedException(methods, UnsupportedOperationException.class);
1105     }
1106 
1107     private class ServiceMethodInvocationData {
1108         String methodName;
1109         Object[] parameters;
1110         Class<?>[] paramterTypes;
1111     }
1112     
1113     private void invokeForExpectedException(Collection<ServiceMethodInvocationData> methods, Class<? extends Exception> expectedExceptionClass) throws Exception {
1114         for(ServiceMethodInvocationData methodData : methods) {
1115             Method method = courseService.getClass().getMethod(methodData.methodName, methodData.paramterTypes);
1116             Throwable expected = null;
1117             Exception unexpected = null;
1118             try {
1119                 method.invoke(courseService, methodData.parameters);
1120             }
1121             catch(InvocationTargetException ex) {
1122                 if(ex.getCause() != null && ex.getCause().getClass().equals(expectedExceptionClass)) {
1123                     expected = ex.getCause();
1124                 }
1125                 else {
1126                     unexpected = ex;
1127                     unexpected.printStackTrace();
1128                 }
1129             }
1130             catch(Exception other) {
1131                 unexpected = other;
1132             }
1133             finally {
1134                 assertNotNull("An exception of class: " + expectedExceptionClass.toString() + " was expected, but the method: " + methodData.methodName + " threw this exception: " + unexpected, expected);
1135             }
1136         }
1137     }
1138     
1139     @Test
1140     public void testGetVersionMethodsForInvalidParameters() throws Exception {
1141         String[] getVersionMethods = {"getVersionBySequenceNumber", "getVersions", "getFirstVersion", "getVersionsInDateRange", "getCurrentVersion", "getCurrentVersionOnDate"};
1142         
1143         // build an object array with the appropriate number of arguments for each version method to be called
1144         Object[][] getVersionParams = {new Object[3], new Object[2], new Object[2], new Object[4], new Object[2], new Object[3]};
1145         
1146         // build a class array with the parameter types for each method call
1147         Class<?>[][] getVersionParamTypes = {{String.class, String.class, Long.class}, // for getVersionBySequenceNumber
1148                 {String.class, String.class}, // for getVersions
1149                 {String.class, String.class}, // for getFirstVersion
1150                 {String.class, String.class, Date.class, Date.class}, // for getVersionsInDateRange
1151                 {String.class, String.class}, // for getCurrentVersion
1152                 {String.class, String.class, Date.class}}; // for getCurrentVersionOnDate
1153         
1154         String badRefObjectTypeURI = "BADBADBAD";
1155         Collection<ServiceMethodInvocationData> methods = new ArrayList<ServiceMethodInvocationData>(getVersionMethods.length);
1156         for(int i = 0; i < getVersionMethods.length; i++) {
1157             ServiceMethodInvocationData invocationData = new ServiceMethodInvocationData();
1158             invocationData.methodName = getVersionMethods[i];
1159             
1160             // set the first parameter of each invocation to the invalid data
1161             getVersionParams[i][0] = badRefObjectTypeURI;
1162             
1163             invocationData.parameters = getVersionParams[i];
1164             invocationData.paramterTypes = getVersionParamTypes[i];
1165             
1166             methods.add(invocationData);
1167         }
1168         
1169         invokeForExpectedException(methods, InvalidParameterException.class);
1170     }
1171     
1172     @Test
1173     public void testGetCurrentVersion() throws Exception {
1174         CourseDataGenerator generator = new CourseDataGenerator();
1175         CourseInfo cInfo = generator.getCourseTestData();
1176         CourseInfo createdCourse = courseService.createCourse(cInfo);
1177 
1178         try {
1179             courseService.createNewCourseVersion(createdCourse.getVersionInfo().getVersionIndId(), "test getting version");
1180             assertTrue(true);
1181         } catch (Exception e) {
1182             assertTrue(false);
1183         }
1184         
1185         VersionDisplayInfo versionInfo = courseService.getCurrentVersion(CourseServiceConstants.COURSE_NAMESPACE_URI, createdCourse.getVersionInfo().getVersionIndId());
1186         
1187         assertNotNull(versionInfo);
1188         assertEquals(createdCourse.getVersionInfo().getSequenceNumber(),versionInfo.getSequenceNumber());
1189     }
1190     
1191     @Test
1192     public void testGetCurrentVersionOnDate() throws Exception {
1193         CourseDataGenerator generator = new CourseDataGenerator();
1194         CourseInfo cInfo = generator.getCourseTestData();
1195         CourseInfo createdCourse = courseService.createCourse(cInfo);
1196 
1197         VersionDisplayInfo versionInfo = courseService.getCurrentVersionOnDate(CourseServiceConstants.COURSE_NAMESPACE_URI, createdCourse.getVersionInfo().getVersionIndId(), new Date());
1198         
1199         assertNotNull(versionInfo);
1200         assertEquals(createdCourse.getVersionInfo().getSequenceNumber(),versionInfo.getSequenceNumber());
1201         
1202         
1203         // make a second version of the course, set it to be the current version a month in the future, and ensure that getting today's version gets the one that was created first
1204         CourseInfo cInfo2 = null;
1205         try {
1206             cInfo2 = courseService.createNewCourseVersion(createdCourse.getVersionInfo().getVersionIndId(), "test getting version by date");
1207             assertTrue(true);
1208         } catch (Exception e) {
1209             assertTrue(false);
1210         }
1211         
1212         Calendar cal = Calendar.getInstance();
1213         cal.add(Calendar.MONTH, 1);
1214         
1215         // Make the created the current version one month from now
1216         courseService.setCurrentCourseVersion(cInfo2.getId(), cal.getTime());
1217         
1218         // make sure when we get the current version for today, it still returns the first one created
1219         versionInfo = courseService.getCurrentVersionOnDate(CourseServiceConstants.COURSE_NAMESPACE_URI, cInfo2.getVersionInfo().getVersionIndId(), new Date());
1220         
1221         assertNotNull(versionInfo);
1222         assertEquals(createdCourse.getVersionInfo().getSequenceNumber(), versionInfo.getSequenceNumber());
1223     }
1224     
1225     @Test
1226     public void testGetVersions() throws Exception {
1227         
1228         CourseDataGenerator generator = new CourseDataGenerator();
1229         CourseInfo cInfo = generator.getCourseTestData();
1230         CourseInfo createdCourse = courseService.createCourse(cInfo);
1231 
1232         List<VersionDisplayInfo> versions = courseService.getVersions(CourseServiceConstants.COURSE_NAMESPACE_URI, createdCourse.getVersionInfo().getVersionIndId());
1233         
1234         assertEquals(1, versions.size());
1235         
1236         try {
1237             courseService.createNewCourseVersion(createdCourse.getVersionInfo().getVersionIndId(), "test getting version");
1238             assertTrue(true);
1239         } catch (Exception e) {
1240             assertTrue(false);
1241         }
1242         
1243         versions = courseService.getVersions(CourseServiceConstants.COURSE_NAMESPACE_URI, createdCourse.getVersionInfo().getVersionIndId());
1244         
1245         assertEquals(2, versions.size());
1246     }
1247     
1248     @Test
1249     public void testGetFirstVersion() throws Exception {
1250         
1251         CourseDataGenerator generator = new CourseDataGenerator();
1252         CourseInfo cInfo = generator.getCourseTestData();
1253         CourseInfo createdCourse = courseService.createCourse(cInfo);
1254 
1255         try {
1256             courseService.createNewCourseVersion(createdCourse.getVersionInfo().getVersionIndId(), "test getting version");
1257             assertTrue(true);
1258         } catch (Exception e) {
1259             assertTrue(false);
1260         }
1261         
1262         VersionDisplayInfo firstVersion = courseService.getFirstVersion(CourseServiceConstants.COURSE_NAMESPACE_URI, createdCourse.getVersionInfo().getVersionIndId());
1263         
1264         assertEquals(firstVersion.getSequenceNumber(), createdCourse.getVersionInfo().getSequenceNumber());
1265     }
1266     
1267     @Test
1268     public void testGetVersionBySequenceNumber() throws Exception {
1269         
1270         CourseDataGenerator generator = new CourseDataGenerator();
1271         CourseInfo cInfo = generator.getCourseTestData();
1272         CourseInfo createdCourse = courseService.createCourse(cInfo);
1273 
1274         CourseInfo version2 = null;
1275         try {
1276             version2 = courseService.createNewCourseVersion(createdCourse.getVersionInfo().getVersionIndId(), "test getting version");
1277             assertTrue(true);
1278         } catch (Exception e) {
1279             assertTrue(false);
1280         }
1281         
1282         VersionDisplayInfo secondVersion = courseService.getVersionBySequenceNumber(CourseServiceConstants.COURSE_NAMESPACE_URI, createdCourse.getVersionInfo().getVersionIndId(), version2.getVersionInfo().getSequenceNumber());
1283         
1284         assertEquals(secondVersion.getSequenceNumber(), version2.getVersionInfo().getSequenceNumber());
1285     }
1286     
1287     @Test
1288     public void testGetVersionsInDateRange() throws Exception {
1289         CourseDataGenerator generator = new CourseDataGenerator();
1290         CourseInfo cInfo = generator.getCourseTestData();
1291         CourseInfo createdCourse = courseService.createCourse(cInfo);
1292 
1293         VersionDisplayInfo versionInfo = courseService.getCurrentVersionOnDate(CourseServiceConstants.COURSE_NAMESPACE_URI, createdCourse.getVersionInfo().getVersionIndId(), new Date());
1294         
1295         assertNotNull(versionInfo);
1296         assertEquals(createdCourse.getVersionInfo().getSequenceNumber(),versionInfo.getSequenceNumber());
1297         
1298         
1299         // make a second version of the course, set it to be the current version a month in the future, and ensure that getting today's version gets the one that was created first
1300         CourseInfo cInfo2 = null;
1301         try {
1302             cInfo2 = courseService.createNewCourseVersion(createdCourse.getVersionInfo().getVersionIndId(), "test getting version by date");
1303             assertTrue(true);
1304         } catch (Exception e) {
1305             assertTrue(false);
1306         }
1307         
1308         Calendar cal = Calendar.getInstance();
1309         cal.add(Calendar.MONTH, 1);
1310         
1311         // Make the created the current version one month from now
1312         courseService.setCurrentCourseVersion(cInfo2.getId(), cal.getTime());
1313         
1314         // ensure that when retrieving versions from yesterday to tomorrow, we get only the first created version
1315         Calendar rangeInstance = Calendar.getInstance();
1316         rangeInstance.add(Calendar.DATE, -1);
1317         Date yesterday = rangeInstance.getTime();
1318         
1319         rangeInstance.add(Calendar.DATE, 2);
1320         Date tomorrow = rangeInstance.getTime();
1321         
1322         List<VersionDisplayInfo> versions = courseService.getVersionsInDateRange(CourseServiceConstants.COURSE_NAMESPACE_URI, createdCourse.getVersionInfo().getVersionIndId(), yesterday, tomorrow);
1323         
1324         assertEquals(1, versions.size());
1325     }
1326     
1327 }