001    package org.kuali.student.lum.program.service.impl;
002    
003    import static org.junit.Assert.assertEquals;
004    import static org.junit.Assert.assertNotNull;
005    import static org.junit.Assert.assertTrue;
006    import static org.junit.Assert.fail;
007    
008    import java.beans.IntrospectionException;
009    import java.lang.reflect.InvocationTargetException;
010    import java.lang.reflect.Method;
011    import java.util.ArrayList;
012    import java.util.Collection;
013    import java.util.Date;
014    import java.util.HashMap;
015    import java.util.List;
016    import java.util.Map;
017    
018    import org.apache.commons.lang.builder.EqualsBuilder;
019    import org.junit.Ignore;
020    import org.junit.Test;
021    import org.junit.runner.RunWith;
022    import org.kuali.student.common.assembly.data.Metadata;
023    import org.kuali.student.common.assembly.dictionary.MetadataServiceImpl;
024    import org.kuali.student.common.dto.DtoConstants;
025    import org.kuali.student.common.dto.RichTextInfo;
026    import org.kuali.student.common.exceptions.AlreadyExistsException;
027    import org.kuali.student.common.exceptions.CircularRelationshipException;
028    import org.kuali.student.common.exceptions.DataValidationErrorException;
029    import org.kuali.student.common.exceptions.DependentObjectsExistException;
030    import org.kuali.student.common.exceptions.DoesNotExistException;
031    import org.kuali.student.common.exceptions.IllegalVersionSequencingException;
032    import org.kuali.student.common.exceptions.InvalidParameterException;
033    import org.kuali.student.common.exceptions.MissingParameterException;
034    import org.kuali.student.common.exceptions.OperationFailedException;
035    import org.kuali.student.common.exceptions.PermissionDeniedException;
036    import org.kuali.student.common.exceptions.UnsupportedActionException;
037    import org.kuali.student.common.exceptions.VersionMismatchException;
038    import org.kuali.student.core.statement.dto.ReqCompFieldInfo;
039    import org.kuali.student.core.statement.dto.ReqCompFieldTypeInfo;
040    import org.kuali.student.core.statement.dto.ReqComponentInfo;
041    import org.kuali.student.core.statement.dto.ReqComponentTypeInfo;
042    import org.kuali.student.core.statement.dto.StatementOperatorTypeKey;
043    import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
044    import org.kuali.student.core.statement.service.StatementService;
045    import org.kuali.student.lum.course.dto.LoDisplayInfo;
046    import org.kuali.student.lum.course.service.assembler.CourseAssemblerConstants;
047    import org.kuali.student.lum.lo.dto.LoCategoryInfo;
048    import org.kuali.student.lum.lo.dto.LoInfo;
049    import org.kuali.student.lum.lu.dto.AdminOrgInfo;
050    import org.kuali.student.lum.program.dto.CoreProgramInfo;
051    import org.kuali.student.lum.program.dto.CredentialProgramInfo;
052    import org.kuali.student.lum.program.dto.MajorDisciplineInfo;
053    import org.kuali.student.lum.program.dto.ProgramRequirementInfo;
054    import org.kuali.student.lum.program.dto.ProgramVariationInfo;
055    import org.kuali.student.lum.program.service.ProgramService;
056    import org.kuali.student.lum.program.service.assembler.MajorDisciplineDataGenerator;
057    import org.kuali.student.lum.program.service.assembler.ProgramAssemblerConstants;
058    import org.springframework.beans.BeanUtils;
059    import org.springframework.beans.factory.annotation.Autowired;
060    import org.springframework.test.context.ContextConfiguration;
061    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
062    
063    @RunWith(SpringJUnit4ClassRunner.class)
064    @ContextConfiguration(locations = {"classpath:program-test-context.xml"})
065    public class TestProgramServiceImpl {
066    
067        @Autowired
068        public ProgramService programService;
069        @Autowired
070        public StatementService statementService;
071        private static final String OTHER_LO_CAT_ID = "550e8400-e29b-41d4-a716-446655440000";
072        
073        /**
074         * A set of methods that have a dummy implementation in ProgramServiceImpl.  Method names should be removed from here once
075         * they have a working implementation.
076         */
077        private final String[] DUMMY_SERVICE_METHODS = {"createHonorsProgram", "createMinorDiscipline", "deleteHonorsProgram", 
078                "deleteMinorDiscipline", "getCredentialProgramType", "getCredentialProgramTypes", 
079                "getHonorsByCredentialProgramType", "getHonorsProgram", "getMajorIdsByCredentialProgramType", 
080                "getMinorDiscipline", "getMinorsByCredentialProgramType", "updateHonorsProgram", "updateMinorDiscipline", 
081                "validateHonorsProgram", "validateMinorDiscipline", "getSearchCriteriaType", "getSearchCriteriaTypes", 
082                "getSearchResultType", "getSearchResultTypes", "getSearchType", "getSearchTypes", "getSearchTypesByCriteria", 
083                "getSearchTypesByResult", "search"};
084    
085        @Test
086        public void testProgramServiceSetup() {
087            assertNotNull(programService);
088            assertNotNull(statementService);
089        }
090    
091            @Test
092        public void testGetMetaData() {
093            MetadataServiceImpl metadataService = new MetadataServiceImpl(programService);
094            metadataService.setUiLookupContext("classpath:lum-ui-test-lookup-context.xml");
095            Metadata metadata = metadataService.getMetadata("org.kuali.student.lum.program.dto.MajorDisciplineInfo");
096            assertNotNull(metadata);
097    
098            Map<String, Metadata> properties = metadata.getProperties();
099            assertTrue(properties.size() > 0);
100    
101            assertTrue(properties.containsKey("universityClassification"));
102            metadata = properties.get("universityClassification");
103            assertEquals("STRING", metadata.getDataType().name());
104        }
105    
106    
107        @Test
108        public void testGetProgramRequirement() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
109            ProgramRequirementInfo progReqInfo = programService.getProgramRequirement("PROGREQ-1", null, null);
110            assertNotNull(progReqInfo);
111    
112            checkTreeView(progReqInfo, false);
113    
114    
115            List<LoDisplayInfo> los = progReqInfo.getLearningObjectives();
116            assertNotNull(los);
117            assertEquals(1, los.size());
118            LoDisplayInfo ldi1 = los.get(0);
119            assertNotNull(ldi1);
120    
121            LoInfo loInfo1 = ldi1.getLoInfo();
122            assertNotNull(loInfo1);
123            assertEquals("81abea67-3bcc-4088-8348-e265f3670145", loInfo1.getId());
124            assertEquals("Desc4", loInfo1.getDesc().getPlain());
125            assertEquals("Edit Wiki Message Structure", loInfo1.getName());
126            assertEquals("kuali.loRepository.key.singleUse", loInfo1.getLoRepositoryKey());
127            assertEquals(DtoConstants.STATE_DRAFT, loInfo1.getState());
128            assertEquals("kuali.lo.type.singleUse", loInfo1.getType());
129        }
130    
131        @Test
132        @Ignore // FIXME
133        public void testGetProgramRequirementNL() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
134            ProgramRequirementInfo progReqInfo = programService.getProgramRequirement("PROGREQ-1", "KUALI.RULE", "en");
135            assertNotNull(progReqInfo);
136    
137            checkTreeView(progReqInfo, true);
138        }
139    
140            private void checkTreeView(final ProgramRequirementInfo progReqInfo, final boolean checkNaturalLanguage) {
141                    StatementTreeViewInfo rootTree = progReqInfo.getStatement();
142            assertNotNull(rootTree);
143            List<StatementTreeViewInfo> subTreeView = rootTree.getStatements();
144            assertNotNull(subTreeView);
145            assertEquals(2, subTreeView.size());
146            StatementTreeViewInfo subTree1 = subTreeView.get(0);
147            StatementTreeViewInfo subTree2 = subTreeView.get(1);
148    
149            // Check root tree
150            assertNotNull(rootTree);
151            assertEquals(2, subTreeView.size());
152            assertNotNull(subTree1);
153            assertNotNull(subTree2);
154    
155            // Check reqComps of sub-tree 1
156            assertEquals("STMT-TV-2", subTree1.getId());
157            assertEquals(2, subTree1.getReqComponents().size());
158            assertEquals("REQCOMP-TV-1", subTree1.getReqComponents().get(0).getId());
159            assertEquals("REQCOMP-TV-2", subTree1.getReqComponents().get(1).getId());
160            if (checkNaturalLanguage) {
161                    assertEquals("Student must have completed all of MATH 152, MATH 180", subTree1.getReqComponents().get(0).getNaturalLanguageTranslation());
162                    assertEquals("Student needs a minimum GPA of 3.5 in MATH 152, MATH 180", subTree1.getReqComponents().get(1).getNaturalLanguageTranslation());
163            }
164    
165            // Check reqComps of sub-tree 2
166            assertEquals("STMT-TV-3", subTree2.getId());
167            assertEquals(2, subTree2.getReqComponents().size());
168            assertEquals("REQCOMP-TV-3", subTree2.getReqComponents().get(0).getId());
169            assertEquals("REQCOMP-TV-4", subTree2.getReqComponents().get(1).getId());
170            if (checkNaturalLanguage) {
171                    assertEquals("Student must have completed 1 of MATH 152, MATH 180", subTree2.getReqComponents().get(0).getNaturalLanguageTranslation());
172                    assertEquals("Student needs a minimum GPA of 4.0 in MATH 152, MATH 180", subTree2.getReqComponents().get(1).getNaturalLanguageTranslation());
173            }
174            }
175    
176        @Test(expected = MissingParameterException.class)
177        public void testGetProgramRequirement_nullId() throws Exception {
178            programService.getProgramRequirement(null, null, null);
179        }
180    
181        @Test(expected = DoesNotExistException.class)
182        public void testGetProgramRequirement_badId() throws Exception {
183            programService.getProgramRequirement("CLU-XXX ", null, null);
184        }
185    
186        @Test
187        public void testGetCoreProgram() throws InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DoesNotExistException {
188            CoreProgramInfo core = null;
189                try {
190                    core = programService.getCoreProgram("d4ea77dd-b492-4554-b104-863e42c5f8b7");
191                    fail("Should have received DoesNotExistException");
192                } catch (DoesNotExistException dnee) {
193                    String expectedExceptionMessage = "Specified CLU is not a CoreProgram";
194                    assertEquals("Expected DoesNotExistException has incorrect message:", expectedExceptionMessage, dnee.getMessage());
195                }
196                core = programService.getCoreProgram("00f5f8c5-fff1-4c8b-92fc-789b891e0849");
197    
198                assertNotNull(core);
199    
200                assertNotNull(core.getReferenceURL());
201                assertEquals("http://www.google.ca", core.getReferenceURL());
202                assertNotNull(core.getUniversityClassification());
203                assertEquals(core.getUniversityClassification(), "UNIVERSITYCLASSIFICATIONCODE");
204                assertNotNull(core.getStartTerm());
205                assertEquals("start_term", core.getStartTerm());
206                assertNotNull(core.getEndTerm());
207                assertEquals("end_term", core.getEndTerm());
208                assertNotNull(core.getEndProgramEntryTerm());
209                assertEquals("end_admit_term", core.getEndProgramEntryTerm());
210                assertNotNull(core.getCode());
211                assertEquals("BS", core.getCode());
212                assertNotNull(core.getShortTitle());
213                assertEquals("B.S.", core.getShortTitle());
214                assertNotNull(core.getLongTitle());
215                assertEquals("Bachelor of Science", core.getLongTitle());
216                assertNotNull(core.getTranscriptTitle());
217                assertEquals(core.getTranscriptTitle(), "TRANSCRIPT-TITLE");
218                assertNotNull(core.getDescr());
219                assertEquals("Anthropology Major", core.getDescr().getPlain());
220    
221    //            //TODO catalog descr
222    //            //TODO catalog pub targets
223    
224                assertNotNull(core.getLearningObjectives());
225                assertTrue(core.getLearningObjectives().size() ==1);
226                assertEquals("Core Program Learning objectives", core.getLearningObjectives().get(0).getLoInfo().getDesc().getPlain());
227    
228                assertNotNull(core.getDivisionsContentOwner());
229                assertTrue(core.getDivisionsContentOwner().size() == 1);
230                assertEquals(core.getDivisionsContentOwner().get(0), "48");
231                assertNotNull(core.getDivisionsStudentOversight());
232                assertTrue(core.getDivisionsStudentOversight().size() == 1);
233                assertEquals(core.getDivisionsStudentOversight().get(0), "50");
234                assertNotNull(core.getUnitsContentOwner());
235                assertTrue(core.getUnitsContentOwner().size() == 1);
236                assertEquals(core.getUnitsContentOwner().get(0), "49");
237                assertNotNull(core.getUnitsStudentOversight());
238                assertTrue(core.getUnitsStudentOversight().size() == 1);
239                assertEquals(core.getUnitsStudentOversight().get(0), "51");
240    
241                assertNotNull(core.getAttributes());
242                assertTrue(core.getAttributes().size() ==2);
243                assertEquals("GINGER GEM", core.getAttributes().get("COOKIES"));
244                assertEquals("JAM TART", core.getAttributes().get("CAKES"));
245    
246                assertNotNull(core.getMetaInfo());
247                assertEquals("1", core.getMetaInfo().getVersionInd());
248                assertNotNull(core.getType());
249                assertEquals(ProgramAssemblerConstants.CORE_PROGRAM, core.getType());
250                assertNotNull(core.getState());
251                assertEquals(DtoConstants.STATE_ACTIVE, core.getState());
252                assertNotNull(core.getId());
253                assertEquals("00f5f8c5-fff1-4c8b-92fc-789b891e0849", core.getId());
254        }
255        @Test
256        public void testGetMajorDiscipline() throws InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DoesNotExistException {
257            MajorDisciplineInfo major = null;
258    //              MajorDisciplineDataGenerator generator = new MajorDisciplineDataGenerator();
259                // MajorDisciplineInfo majorDisciplineInfo = generator.getMajorDisciplineInfoTestData();
260                try {
261                    major = programService.getMajorDiscipline("0d8c42bc-77ba-450e-ae0e-eecd76fae779");
262                    fail("Should have received DoesNotExistException");
263                } catch (DoesNotExistException dnee) {
264                    String expectedExceptionMessage = "Specified CLU is not a Major Discipline";
265                    assertEquals("Expected DoesNotExistException has incorrect message:", expectedExceptionMessage, dnee.getMessage());
266                }
267                major = programService.getMajorDiscipline("d4ea77dd-b492-4554-b104-863e42c5f8b7");
268    
269                assertNotNull(major);
270    
271                assertNotNull(major.getIntensity());
272                assertEquals("kuali.atp.duration.full", major.getIntensity());
273                assertNotNull(major.getReferenceURL());
274                assertEquals("http://www.google.ca", major.getReferenceURL());
275                assertEquals(1, major.getPublishedInstructors().size());
276    
277                assertEquals("INSTR-1", major.getPublishedInstructors().get(0).getPersonId());
278                assertNotNull(major.getCredentialProgramId());
279                assertEquals("d02dbbd3-20e2-410d-ab52-1bd6d362748b", major.getCredentialProgramId());
280    
281                assertNotNull(major.getVariations());
282                assertTrue(major.getVariations().size() == 2);
283                assertEquals("ZOOA", major.getVariations().get(0).getCode());
284                assertEquals("ARCB", major.getVariations().get(1).getCode());
285    
286                assertNotNull(major.getCode());
287                assertEquals("ANTH", major.getCode());
288                assertNotNull(major.getCip2000Code());
289                assertEquals("45.0202", major.getCip2000Code());
290                assertNotNull(major.getCip2010Code());
291                assertEquals("45.0201", major.getCip2010Code());
292                assertNotNull(major.getHegisCode());
293                assertEquals("220200", major.getHegisCode());
294                assertNotNull(major.getUniversityClassification());
295                assertEquals("UNIVERSITYCLASSIFICATIONCODE", major.getUniversityClassification());
296                assertNotNull(major.getSelectiveEnrollmentCode());
297                assertEquals("SELECTIVEENROLLMENTCODE", major.getSelectiveEnrollmentCode());
298    
299                assertNotNull(major.getResultOptions());
300                assertTrue(major.getResultOptions().size() == 2);
301                assertEquals("kuali.resultComponent.degree.ba", major.getResultOptions().get(0));
302                assertEquals("kuali.resultComponent.degree.bsc", major.getResultOptions().get(1));
303    
304                assertNotNull(major.getStdDuration());
305                assertEquals("kuali.atp.duration.Week", major.getStdDuration().getAtpDurationTypeKey());
306                assertEquals(new Integer(100), major.getStdDuration().getTimeQuantity());
307                assertNotNull(major.getStartTerm());
308                assertEquals("start_term", major.getStartTerm());
309                assertNotNull(major.getEndTerm());
310                assertEquals("end_term", major.getEndTerm());
311                assertNotNull(major.getEndProgramEntryTerm());
312                assertEquals("end_admit_term", major.getEndProgramEntryTerm());
313    
314                assertNotNull(major.getNextReviewPeriod());
315                assertEquals("kuali.atp.SU2009-2010S1", major.getNextReviewPeriod());
316    
317                assertNotNull(major.getEffectiveDate());
318                //TODO effectiveDate
319    //            Calendar effectiveDate = GregorianCalendar.getInstance();
320    //            effectiveDate.set(1984, 7, 1, 0, 0, 0);
321    //            Date testDate = new Date(effectiveDate.getTimeInMillis());
322    //            assertTrue(major.getEffectiveDate().compareTo(testDate) == 0);
323    
324                assertNotNull(major.getShortTitle());
325                assertEquals("Anthro", major.getShortTitle());
326                assertNotNull(major.getLongTitle());
327                assertEquals("Anthropology", major.getLongTitle());
328                assertNotNull(major.getTranscriptTitle());
329                assertEquals("TRANSCRIPT-TITLE", major.getTranscriptTitle());
330                assertNotNull(major.getDiplomaTitle());
331                assertEquals("DIPLOMA-TITLE", major.getDiplomaTitle() );
332                assertNotNull(major.getDescr());
333                assertEquals("Anthropology Major", major.getDescr().getPlain());
334    
335                //TODO catalog descr
336    
337                assertNotNull(major.getCatalogDescr());
338                assertEquals("This is the catalog description", major.getCatalogDescr().getPlain());
339                assertNotNull(major.getCatalogPublicationTargets());
340                assertEquals(1, major.getCatalogPublicationTargets().size());
341                assertEquals("kuali.lu.publication.UndergradCatalog", major.getCatalogPublicationTargets().get(0));
342                assertNotNull(major.getLearningObjectives());
343                assertTrue(major.getLearningObjectives().size() ==1);
344                assertEquals("Annihilate Wiki", major.getLearningObjectives().get(0).getLoInfo().getDesc().getPlain());
345                assertNotNull(major.getCampusLocations());
346                assertTrue(major.getCampusLocations().size() == 2);
347                assertEquals("NO", major.getCampusLocations().get(0));
348                assertEquals("SO", major.getCampusLocations().get(1));
349    
350                assertNotNull(major.getOrgCoreProgram());
351                assertEquals("kuali.lu.type.CoreProgram", major.getOrgCoreProgram().getType());
352                assertEquals("00f5f8c5-fff1-4c8b-92fc-789b891e0849", major.getOrgCoreProgram().getId());
353                assertNotNull(major.getProgramRequirements());
354                assertTrue(major.getProgramRequirements().size() == 1);
355                assertEquals("REQ-200", major.getProgramRequirements().get(0));
356    
357                assertNotNull(major.getAccreditingAgencies());
358                assertTrue(major.getAccreditingAgencies().size() == 1);
359                assertEquals("23", major.getAccreditingAgencies().get(0).getOrgId());
360                assertNotNull(major.getDivisionsContentOwner());
361                assertTrue(major.getDivisionsContentOwner().size() == 1);
362                assertEquals(major.getDivisionsContentOwner().get(0), "31");
363                assertNotNull(major.getDivisionsStudentOversight());
364                assertTrue(major.getDivisionsStudentOversight().size() == 1);
365                assertEquals(major.getDivisionsStudentOversight().get(0), "32");
366                assertNotNull(major.getDivisionsDeployment());
367                assertTrue(major.getDivisionsDeployment().size() == 1);
368                assertEquals(major.getDivisionsDeployment().get(0), "33");
369                assertNotNull(major.getDivisionsFinancialResources());
370                assertTrue(major.getDivisionsFinancialResources().size() == 1);
371                assertEquals(major.getDivisionsFinancialResources().get(0), "34");
372                assertNotNull(major.getDivisionsFinancialControl());
373                assertTrue(major.getDivisionsFinancialControl().size() == 1);
374                assertEquals(major.getDivisionsFinancialControl().get(0), "36");
375    
376                assertNotNull(major.getUnitsContentOwner());
377                assertTrue(major.getUnitsContentOwner().size() == 1);
378                assertEquals(major.getUnitsContentOwner().get(0), "41");
379                assertNotNull(major.getUnitsStudentOversight());
380                assertTrue(major.getUnitsStudentOversight().size() == 1);
381                assertEquals(major.getUnitsStudentOversight().get(0), "42");
382                assertNotNull(major.getUnitsDeployment());
383                assertTrue(major.getUnitsDeployment().size() == 1);
384                assertEquals(major.getUnitsDeployment().get(0), "43");
385                assertNotNull(major.getUnitsFinancialResources());
386                assertTrue(major.getUnitsFinancialResources().size() == 1);
387                assertEquals(major.getUnitsFinancialResources().get(0), "44");
388                assertNotNull(major.getUnitsFinancialControl());
389                assertTrue(major.getUnitsFinancialControl().size() == 2);
390                assertEquals(major.getUnitsFinancialControl().get(0), "46");
391                assertEquals(major.getUnitsFinancialControl().get(1), "47");
392                assertNotNull(major.getAttributes());
393                assertEquals(2, major.getAttributes().size());
394                assertEquals("GINGER GEM", major.getAttributes().get("COOKIES"));
395                assertEquals("JAM TART", major.getAttributes().get("CAKES"));
396    
397                assertNotNull(major.getMetaInfo());
398                assertEquals("1", major.getMetaInfo().getVersionInd());
399               //TODO createTime
400    //            Calendar createTime = GregorianCalendar.getInstance();
401    //            createTime.set(2009, 4, 7, 12, 5, 36);
402    //            testDate = new Date(createTime.getTimeInMillis());
403    //            assertTrue(major.getEffectiveDate().compareTo(testDate) == 0);
404    
405                assertNotNull(major.getType());
406                assertEquals(ProgramAssemblerConstants.MAJOR_DISCIPLINE, major.getType());
407                assertNotNull(major.getState());
408                assertEquals(DtoConstants.STATE_ACTIVE, major.getState());
409                assertNotNull(major.getId());
410                assertEquals("d4ea77dd-b492-4554-b104-863e42c5f8b7", major.getId());
411    
412    
413        }
414    
415        @Test
416        public void testGetVariationsByMajorDisciplineId() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException{
417            MajorDisciplineInfo majorDisciplineInfo = null;
418    
419                majorDisciplineInfo = programService.getMajorDiscipline("d4ea77dd-b492-4554-b104-863e42c5f8b7");
420                assertNotNull(majorDisciplineInfo);
421    
422                List<ProgramVariationInfo> pvInfos = programService.getVariationsByMajorDisciplineId("d4ea77dd-b492-4554-b104-863e42c5f8b7");
423                assertNotNull(pvInfos);
424                assertEquals(pvInfos.size(), majorDisciplineInfo.getVariations().size());
425    
426                ProgramVariationInfo pvInfo = pvInfos.get(0);
427                assertEquals("ZOOA", pvInfo.getCode());
428                assertEquals("Zooarchaeology", pvInfo.getDescr().getPlain());
429                assertEquals("Zooarchaeology", pvInfo.getLongTitle());
430                assertEquals("ZooArch", pvInfo.getShortTitle());
431                assertEquals("VAR-200", pvInfo.getId());
432                assertEquals("Active", pvInfo.getState());
433    
434        }
435    
436        @Test
437        public void testGetBaccCredentialProgram() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException{
438    
439            String credentialProgramId = "d02dbbd3-20e2-410d-ab52-1bd6d362748b";
440            CredentialProgramInfo credentialProgramInfo = null;
441                    credentialProgramInfo = programService.getCredentialProgram(credentialProgramId);
442                assertNotNull(credentialProgramInfo);
443                assertEquals("BS", credentialProgramInfo.getCode());
444                assertEquals("B.S.", credentialProgramInfo.getShortTitle());
445                assertEquals("Bachelor of Science", credentialProgramInfo.getLongTitle());
446                assertEquals("Bachelor of Science", credentialProgramInfo.getDescr().getPlain());
447                assertEquals(DtoConstants.STATE_ACTIVE, credentialProgramInfo.getState());
448                    assertEquals(ProgramAssemblerConstants.BACCALAUREATE_PROGRAM, credentialProgramInfo.getCredentialProgramType());
449                assertEquals("52", credentialProgramInfo.getInstitution().getOrgId());
450                assertEquals(ProgramAssemblerConstants.UNDERGRAD_PROGRAM_LEVEL, credentialProgramInfo.getProgramLevel());
451                assertNotNull(credentialProgramInfo.getCoreProgramIds());
452                assertEquals(1, credentialProgramInfo.getCoreProgramIds().size());
453                assertEquals("00f5f8c5-fff1-4c8b-92fc-789b891e0849", credentialProgramInfo.getCoreProgramIds().get(0));
454        }
455    
456        @Test
457        public void testCreateMajorDiscipline() throws IllegalArgumentException, SecurityException, IntrospectionException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
458                    MajorDisciplineDataGenerator mdGenerator = new MajorDisciplineDataGenerator();
459            MajorDisciplineInfo major;
460                assertNotNull(major = mdGenerator.getMajorDisciplineInfoTestData());
461    
462                MajorDisciplineInfo createdMD = programService.createMajorDiscipline(major);
463    
464                assertNotNull(createdMD);
465    
466                assertNotNull(createdMD.getId());
467    
468                assertNotNull(createdMD.getState());
469                assertEquals(DtoConstants.STATE_DRAFT, createdMD.getState());
470    
471                assertNotNull(createdMD.getType());
472                assertEquals(ProgramAssemblerConstants.MAJOR_DISCIPLINE, createdMD.getType());
473    
474                assertNotNull(createdMD.getIntensity());
475                assertEquals("intensity-test", createdMD.getIntensity());
476                assertNotNull(createdMD.getReferenceURL());
477                assertEquals("referenceURL-test", createdMD.getReferenceURL());
478    
479                assertEquals(2, createdMD.getPublishedInstructors().size());
480                assertEquals("personId-test", createdMD.getPublishedInstructors().get(0).getPersonId());
481    
482                assertNotNull(createdMD.getCredentialProgramId());
483                assertEquals("00f5f8c5-fff1-4c8b-92fc-789b891e0849", createdMD.getCredentialProgramId());
484    
485                assertNotNull(createdMD.getVariations());
486                assertTrue(createdMD.getVariations().size() == 2);
487                assertNotNull(createdMD.getVariations().get(0).getId());
488                assertNotNull(createdMD.getVariations().get(1).getId());
489                assertEquals("kuali.lu.type.Variation", createdMD.getVariations().get(0).getType());
490                assertEquals("kuali.lu.type.Variation", createdMD.getVariations().get(1).getType());
491    
492                assertNotNull(createdMD.getCode());
493    //TODO            assertEquals("ANTH", createdMD.getCode());
494    
495                assertNotNull(createdMD.getCip2000Code());
496                assertEquals(createdMD.getCip2000Code(), "cip2000Code-test");
497                assertNotNull(createdMD.getCip2010Code());
498                assertEquals(createdMD.getCip2010Code(), "cip2010Code-test");
499                assertNotNull(createdMD.getHegisCode());
500                assertEquals(createdMD.getHegisCode(), "hegisCode-test");
501                assertNotNull(createdMD.getUniversityClassification());
502                assertEquals(createdMD.getUniversityClassification(), "universityClassification-test");
503                assertNotNull(createdMD.getSelectiveEnrollmentCode());
504                assertEquals(createdMD.getSelectiveEnrollmentCode(), "selectiveEnrollmentCode-test");
505    
506                assertNotNull(createdMD.getResultOptions());
507                assertTrue(createdMD.getResultOptions().size() == 2);
508                assertEquals("resultOptions-test", createdMD.getResultOptions().get(0));
509    
510                assertNotNull(createdMD.getStdDuration());
511                assertEquals("atpDurationTypeKey-test", createdMD.getStdDuration().getAtpDurationTypeKey());
512                assertEquals(new Integer(63), createdMD.getStdDuration().getTimeQuantity());
513    
514                assertNotNull(createdMD.getStartTerm());
515                assertEquals("startTerm-test", createdMD.getStartTerm());
516                assertNotNull(createdMD.getEndTerm());
517                assertEquals("endTerm-test", createdMD.getEndTerm());
518                assertNotNull(createdMD.getEndProgramEntryTerm());
519                assertEquals("endProgramEntryTerm-test", createdMD.getEndProgramEntryTerm());
520                assertNotNull(createdMD.getNextReviewPeriod());
521                assertEquals("nextReviewPeriod-test", createdMD.getNextReviewPeriod());
522    
523                assertNotNull(createdMD.getEffectiveDate());
524                //TODO effectiveDate
525    //            Calendar effectiveDate = GregorianCalendar.getInstance();
526    //            effectiveDate.set(1984, 7, 1, 0, 0, 0);
527    //            Date testDate = new Date(effectiveDate.getTimeInMillis());
528    //            assertTrue(createdMD.getEffectiveDate().compareTo(testDate) == 0);
529    
530                assertNotNull(createdMD.getShortTitle());
531                assertEquals("shortTitle-test", createdMD.getShortTitle());
532                assertNotNull(createdMD.getLongTitle());
533                assertEquals("longTitle-test", createdMD.getLongTitle());
534                assertNotNull(createdMD.getTranscriptTitle());
535                assertEquals(createdMD.getTranscriptTitle(), "transcriptTitle-test");
536                assertNotNull(createdMD.getDiplomaTitle());
537                assertEquals(createdMD.getDiplomaTitle(), "diplomaTitle-test");
538                assertNotNull(createdMD.getDescr());
539                assertEquals("plain-test", createdMD.getDescr().getPlain());
540                assertEquals("formatted-test", createdMD.getDescr().getFormatted());
541    
542                assertNotNull(createdMD.getCatalogDescr());
543                assertEquals("plain-test", createdMD.getCatalogDescr().getPlain());
544                assertEquals("formatted-test", createdMD.getCatalogDescr().getFormatted());
545    
546                assertNotNull(createdMD.getCatalogPublicationTargets());
547                assertTrue(createdMD.getCatalogPublicationTargets().size() == 2);
548                assertEquals("kuali.lu.publication.Catalog", createdMD.getCatalogPublicationTargets().get(0));
549    
550                assertNotNull(createdMD.getLearningObjectives());
551                assertTrue(createdMD.getLearningObjectives().size() == 2);
552                assertEquals("plain-test", createdMD.getLearningObjectives().get(0).getLoInfo().getDesc().getPlain());
553    
554                assertNotNull(createdMD.getCampusLocations());
555                assertTrue(createdMD.getCampusLocations().size() == 2);
556                assertEquals("SO", createdMD.getCampusLocations().get(0));
557                assertEquals("NO", createdMD.getCampusLocations().get(1));
558    
559                assertNotNull(createdMD.getOrgCoreProgram());
560                assertEquals(ProgramAssemblerConstants.CORE_PROGRAM, createdMD.getOrgCoreProgram().getType());
561    // TODO           assertEquals("00f5f8c5-fff1-4c8b-92fc-789b891e0849", createdMD.getOrgCoreProgram().getId());
562    
563                assertNotNull(createdMD.getProgramRequirements());
564                assertTrue(createdMD.getProgramRequirements().size() == 2);
565                assertEquals("REQ-200", createdMD.getProgramRequirements().get(0));
566    
567                assertNotNull(createdMD.getAccreditingAgencies());
568                assertTrue(createdMD.getAccreditingAgencies().size() == 2);
569                assertEquals("orgId-test", createdMD.getAccreditingAgencies().get(0).getOrgId());
570    
571                assertNotNull(createdMD.getDivisionsContentOwner());
572                assertTrue(createdMD.getDivisionsContentOwner().size() == 2);
573                assertEquals("divisionsContentOwner-test", createdMD.getDivisionsContentOwner().get(0));
574    
575                assertNotNull(createdMD.getDivisionsStudentOversight());
576                assertTrue(createdMD.getDivisionsStudentOversight().size() == 2);
577                assertEquals("divisionsStudentOversight-test", createdMD.getDivisionsStudentOversight().get(0));
578    
579                assertNotNull(createdMD.getDivisionsDeployment());
580                assertTrue(createdMD.getDivisionsDeployment().size() == 2);
581                assertEquals("divisionsDeployment-test", createdMD.getDivisionsDeployment().get(0));
582    
583                assertNotNull(createdMD.getDivisionsFinancialResources());
584                assertTrue(createdMD.getDivisionsFinancialResources().size() == 2);
585                assertEquals("divisionsFinancialResources-test", createdMD.getDivisionsFinancialResources().get(0));
586    
587                assertNotNull(createdMD.getDivisionsFinancialControl());
588                assertTrue(createdMD.getDivisionsFinancialControl().size() == 2);
589                assertEquals("divisionsFinancialControl-test", createdMD.getDivisionsFinancialControl().get(0));
590    
591                assertNotNull(createdMD.getUnitsContentOwner());
592                assertTrue(createdMD.getUnitsContentOwner().size() == 2);
593                assertEquals("unitsContentOwner-test", createdMD.getUnitsContentOwner().get(0));
594    
595                assertNotNull(createdMD.getUnitsStudentOversight());
596                assertTrue(createdMD.getUnitsStudentOversight().size() == 2);
597                assertEquals("unitsStudentOversight-test", createdMD.getUnitsStudentOversight().get(0));
598    
599                assertNotNull(createdMD.getUnitsDeployment());
600                assertTrue(createdMD.getUnitsDeployment().size() == 2);
601                assertEquals("unitsDeployment-test", createdMD.getUnitsDeployment().get(0));
602    
603                assertNotNull(createdMD.getUnitsFinancialResources());
604                assertTrue(createdMD.getUnitsFinancialResources().size() == 2);
605                assertEquals("unitsFinancialResources-test", createdMD.getUnitsFinancialResources().get(0));
606    
607                assertNotNull(createdMD.getUnitsFinancialControl());
608                assertTrue(createdMD.getUnitsFinancialControl().size() == 2);
609                assertEquals("unitsFinancialControl-test", createdMD.getUnitsFinancialControl().get(0));
610    
611                assertNotNull(createdMD.getAttributes());
612                assertTrue(createdMD.getAttributes().size() ==2);
613                assertEquals("attributes-1", createdMD.getAttributes().get("attributes-1"));
614                assertEquals("attributes-2", createdMD.getAttributes().get("attributes-2"));
615    
616                assertNotNull(createdMD.getMetaInfo());
617                assertEquals("0", createdMD.getMetaInfo().getVersionInd());
618               //TODO createTime
619    //            Calendar createTime = GregorianCalendar.getInstance();
620    //            createTime.set(2009, 4, 7, 12, 5, 36);
621    //            testDate = new Date(createTime.getTimeInMillis());
622    //            assertTrue(createdMD.getEffectiveDate().compareTo(testDate) == 0);
623            }
624    
625        @Test
626        public void testMajorDisciplineVersioning() throws IllegalArgumentException, SecurityException, IntrospectionException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, VersionMismatchException, DoesNotExistException, CircularRelationshipException, DependentObjectsExistException, UnsupportedActionException, IllegalVersionSequencingException {
627                    MajorDisciplineDataGenerator mdGenerator = new MajorDisciplineDataGenerator();
628            MajorDisciplineInfo mdInfo = mdGenerator.getMajorDisciplineInfoTestData();
629            mdInfo.getProgramRequirements().clear();
630            for(ProgramVariationInfo variation :mdInfo.getVariations()){
631                    variation.getProgramRequirements().clear();
632            }
633            MajorDisciplineInfo createdMajor = programService.createMajorDiscipline(mdInfo);
634    
635            MajorDisciplineInfo newMajorDiscipline = programService.createNewMajorDisciplineVersion(createdMajor.getVersionInfo().getVersionIndId(), "test make a new version");
636            
637            // Make the created the current version
638            programService.setCurrentMajorDisciplineVersion(newMajorDiscipline.getId(), null);
639    
640                    MajorDisciplineInfo     newMajor = null;
641            try {
642                newMajor = programService.createNewMajorDisciplineVersion(createdMajor.getVersionInfo().getVersionIndId(), "test make a new version");
643                assertTrue(true);
644            } catch (Exception e) {
645                assertTrue(false);
646            }
647    
648            assertNotNull(newMajor);
649    
650        }
651    
652        @Test
653        public void testCreateMajorDisciplineDeleteRule() throws AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, IllegalArgumentException, SecurityException, IntrospectionException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException {
654                    MajorDisciplineDataGenerator mdGenerator = new MajorDisciplineDataGenerator();
655            MajorDisciplineInfo major;
656                assertNotNull(major = mdGenerator.getMajorDisciplineInfoTestData());
657    
658                MajorDisciplineInfo createdMD = programService.createMajorDiscipline(major);
659    
660                ProgramRequirementInfo progReq = createProgramRequirementTestData();
661                    ProgramRequirementInfo createdProgReq = programService.createProgramRequirement(progReq);
662        }
663    
664        @Test(expected = MissingParameterException.class)
665        public void testCreateProgramRequirement_null() throws Exception {
666            programService.createProgramRequirement(null);
667        }
668    
669        @Test
670        public void testCreateProgramRequirement() throws AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DoesNotExistException {
671            ProgramRequirementInfo progReq = createProgramRequirementTestData();
672            ProgramRequirementInfo createdProgReq = programService.createProgramRequirement(progReq);
673            checkProgramRequirement(progReq, createdProgReq);
674    
675            ProgramRequirementInfo progReq2 = programService.getProgramRequirement(createdProgReq.getId(), null, null);
676            checkProgramRequirement(progReq, progReq2);
677        }
678    
679            private ProgramRequirementInfo createProgramRequirementTestData() {
680                    ProgramRequirementInfo progReq = new ProgramRequirementInfo();
681            progReq.setShortTitle("Short Title");
682            progReq.setLongTitle("Long title");
683            progReq.setDescr(toRichText("Program Requirement"));
684    
685            List<LoDisplayInfo> los = new ArrayList<LoDisplayInfo>(0);
686    
687                    LoDisplayInfo loDisplayInfo = new LoDisplayInfo();
688                    LoInfo loInfo = new LoInfo();
689                    loInfo.setDesc(toRichText("Program Requirement LO Info"));
690                    loInfo.setLoRepositoryKey("lo rep key");
691                    loDisplayInfo.setLoInfo(loInfo);
692            los.add(loDisplayInfo);
693            progReq.setLearningObjectives(los);
694    
695            StatementTreeViewInfo statement = createStatementTree();
696            progReq.setStatement(statement);
697            progReq.setType(ProgramAssemblerConstants.PROGRAM_REQUIREMENT);
698                    return progReq;
699            }
700    
701            private static void checkProgramRequirement(
702                            ProgramRequirementInfo orig, ProgramRequirementInfo created) {
703                    assertNotNull(orig);
704                    assertNotNull(created);
705                    assertTrue(EqualsBuilder.reflectionEquals(orig, created, new String[]{"id", "descr", "learningObjectives","statement","attributes","metaInfo"}));
706            checkLoDisplays(orig.getLearningObjectives(), created.getLearningObjectives());
707            if (orig.getId() == null && created.getId() == null) {
708                    fail("both ProgramRequirements ids are null");
709            } else if (orig.getId() != null) {
710                            assertEquals(orig.getId(), created.getId());
711                    }
712    
713            checkRichText(orig.getDescr(), created.getDescr());
714            checkStatementTreeView(orig.getStatement(), created.getStatement());
715            }
716    
717            private static void checkStatementTreeView(StatementTreeViewInfo statement,
718                            StatementTreeViewInfo statement2) {
719                    assertNotNull(statement);
720                    assertNotNull(statement2);
721                    assertTrue(EqualsBuilder.reflectionEquals(statement, statement2, new String[]{"id", "desc", "attributes", "metaInfo", "statements", "reqComponents"}));
722                    if (statement.getId() == null && statement2.getId() == null) {
723                            fail("Both StatementTreeView ids are null");
724                    } else if (statement.getId() != null) {
725                            assertEquals(statement.getId(), statement2.getId());
726                    }
727                    checkRichText(statement.getDesc(), statement2.getDesc());
728                    checkStatementTreeViews(statement.getStatements(), statement2.getStatements());
729                    checkReqComponents(statement.getReqComponents(), statement2.getReqComponents());
730            }
731    
732            private static void checkReqComponents(List<ReqComponentInfo> reqComponents,
733                            List<ReqComponentInfo> reqComponents2) {
734                    assertNotNull(reqComponents);
735                    assertNotNull(reqComponents2);
736                    assertEquals(reqComponents.size(), reqComponents2.size());
737                    for (int i = 0; i < reqComponents.size(); i++) {
738                            checkReqComponent(reqComponents.get(i), reqComponents2.get(i));
739                    }
740            }
741    
742            private static void checkReqComponent(ReqComponentInfo reqComponent,
743                            ReqComponentInfo reqComponent2) {
744                    assertNotNull(reqComponent);
745                    assertNotNull(reqComponent2);
746                    assertTrue(EqualsBuilder.reflectionEquals(reqComponent, reqComponent2, new String[]{"id", "desc", "reqCompFields", "requiredComponentType", "naturalLanguageTranslation", "metaInfo"}));
747                    if (reqComponent.getId() == null && reqComponent2.getId() == null) {
748                            fail("Both ReqComponent ids are null");
749                    } else if (reqComponent.getId() != null) {
750                            assertEquals(reqComponent.getId(), reqComponent2.getId());
751                    }
752                    checkRichText(reqComponent.getDesc(), reqComponent2.getDesc());
753                    checkReqCompFields(reqComponent.getReqCompFields(), reqComponent.getReqCompFields());
754                    // TODO checkReqComponentType(reqComponent.getRequiredComponentType(), reqComponent2.getRequiredComponentType());
755            }
756    
757            private static void checkReqComponentType(
758                            ReqComponentTypeInfo requiredComponentType,
759                            ReqComponentTypeInfo requiredComponentType2) {
760                    assertNotNull(requiredComponentType);
761                    assertNotNull(requiredComponentType2);
762                    checkReqCompFieldTypes(requiredComponentType.getReqCompFieldTypeInfos(), requiredComponentType2.getReqCompFieldTypeInfos());
763            }
764    
765            private static void checkReqCompFieldTypes(
766                            List<ReqCompFieldTypeInfo> reqCompFieldTypeInfos,
767                            List<ReqCompFieldTypeInfo> reqCompFieldTypeInfos2) {
768                    assertNotNull(reqCompFieldTypeInfos);
769                    assertNotNull(reqCompFieldTypeInfos2);
770                    assertEquals(reqCompFieldTypeInfos.size(), reqCompFieldTypeInfos2.size());
771                    for (int i = 0; i < reqCompFieldTypeInfos.size(); i++) {
772                            checkReqCompFieldType(reqCompFieldTypeInfos.get(i), reqCompFieldTypeInfos2.get(i));
773                    }
774            }
775    
776            private static void checkReqCompFieldType(
777                            ReqCompFieldTypeInfo reqCompFieldTypeInfo,
778                            ReqCompFieldTypeInfo reqCompFieldTypeInfo2) {
779                    assertNotNull(reqCompFieldTypeInfo);
780                    assertNotNull(reqCompFieldTypeInfo2);
781    
782            }
783    
784            private static void checkReqCompFields(List<ReqCompFieldInfo> reqCompFields,
785                            List<ReqCompFieldInfo> reqCompFields2) {
786                    assertNotNull(reqCompFields);
787                    assertNotNull(reqCompFields2);
788                    assertEquals(reqCompFields.size(), reqCompFields2.size());
789                    for (int i = 0; i < reqCompFields.size(); i++) {
790                            checkReqCompField(reqCompFields.get(i), reqCompFields2.get(i));
791                    }
792            }
793    
794            private static void checkReqCompField(ReqCompFieldInfo reqCompField,
795                            ReqCompFieldInfo reqCompField2) {
796                    assertNotNull(reqCompField);
797                    assertNotNull(reqCompField2);
798                    assertTrue(EqualsBuilder.reflectionEquals(reqCompField,reqCompField2));
799            }
800    
801            private static void checkStatementTreeViews(List<StatementTreeViewInfo> statements,
802                            List<StatementTreeViewInfo> statements2) {
803                    assertNotNull(statements);
804                    assertNotNull(statements2);
805                    assertEquals(statements.size(), statements2.size());
806                    for (int i = 0; i < statements.size(); i++) {
807                            checkStatementTreeView(statements.get(i), statements2.get(i));
808                    }
809            }
810    
811            private static void checkLoDisplays(List<LoDisplayInfo> los,
812                            List<LoDisplayInfo> los2) {
813                    assertNotNull(los);
814                    assertNotNull(los2);
815            assertEquals(los.size(), los2.size());
816            for (int i = 0; i < los.size(); i++) {
817                    LoDisplayInfo ldi1 = los.get(i);
818                    LoDisplayInfo ldi2 = los2.get(i);
819                    checkLoDisplay(ldi1, ldi2);
820            }
821            }
822    
823        private static void checkLoDisplay(LoDisplayInfo ldi1, LoDisplayInfo ldi2) {
824                    assertNotNull(ldi1);
825                    assertNotNull(ldi2);
826                    assertTrue(EqualsBuilder.reflectionEquals(ldi1, ldi2, new String[]{"loInfo","loDisplayInfoList","loCategoryInfoList"}));
827    
828                    LoInfo li1 = ldi1.getLoInfo();
829                    LoInfo li2 = ldi2.getLoInfo();
830                    checkLo(li1, li2);
831                    checkLoDisplayLists(ldi1.getLoDisplayInfoList(), ldi2.getLoDisplayInfoList());
832                    checkLoCategorys(ldi1.getLoCategoryInfoList(), ldi2.getLoCategoryInfoList());
833            }
834    
835            private static void checkLoCategorys(List<LoCategoryInfo> loCategoryInfoList,
836                            List<LoCategoryInfo> loCategoryInfoList2) {
837                    assertNotNull(loCategoryInfoList);
838                    assertNotNull(loCategoryInfoList2);
839                    assertEquals(loCategoryInfoList.size(), loCategoryInfoList2.size());
840                    for (int i = 0; i < loCategoryInfoList.size(); i++) {
841                            checkLoCategory(loCategoryInfoList.get(i), loCategoryInfoList2.get(i));
842                    }
843            }
844    
845            private static void checkLoCategory(LoCategoryInfo loCategoryInfo,
846                            LoCategoryInfo loCategoryInfo2) {
847                    assertNotNull(loCategoryInfo);
848                    assertNotNull(loCategoryInfo2);
849                    assertTrue(EqualsBuilder.reflectionEquals(loCategoryInfo, loCategoryInfo2, new String[]{"desc","attributes","metaInfo"}));
850                    checkRichText(loCategoryInfo.getDesc(), loCategoryInfo2.getDesc());
851            }
852    
853            private static void checkLoDisplayLists(List<LoDisplayInfo> di1, List<LoDisplayInfo> di2) {
854                    assertNotNull(di1);
855                    assertNotNull(di2);
856                    assertEquals(di1.size(), di2.size());
857                    for (int i = 0; i < di1.size(); i++) {
858                            checkLoDisplay(di1.get(i), di2.get(i));
859                    }
860            }
861    
862            private static void checkLo(LoInfo li1, LoInfo li2) {
863                    assertNotNull(li1);
864                    assertNotNull(li2);
865    
866                    assertTrue(EqualsBuilder.reflectionEquals(li1, li2, new String[]{"desc","attributes","metaInfo"}));
867                    checkRichText(li1.getDesc(), li2.getDesc());
868            }
869    
870            private static void checkRichText(RichTextInfo desc, RichTextInfo desc2) {
871                    assertNotNull(desc);
872                    assertNotNull(desc2);
873    
874                    assertTrue(EqualsBuilder.reflectionEquals(desc, desc2));
875            }
876    
877            private static StatementTreeViewInfo createStatementTree() {
878            // Statement Tree
879            //                --------- STMT-1:OR ---------
880            //                |                           |
881            //           STMT-2:AND                  STMT-3:AND
882            //           |        |                  |        |
883            //      REQCOMP-1  REQCOMP-2        REQCOMP-3  REQCOMP-4
884    
885            List<StatementTreeViewInfo> subStatements = new ArrayList<StatementTreeViewInfo>(3);
886            List<ReqComponentInfo> reqCompList1 = new ArrayList<ReqComponentInfo>(3);
887            List<ReqComponentInfo> reqCompList2 = new ArrayList<ReqComponentInfo>(3);
888    
889            // req components
890            ReqComponentInfo rc1 = new ReqComponentInfo();
891            rc1.setDesc(toRichText("REQCOMP-1"));
892            rc1.setType("kuali.reqComponent.type.course.courseset.completed.all");
893            ReqComponentInfo rc2 = new ReqComponentInfo();
894            rc2.setDesc(toRichText("REQCOMP-2"));
895            rc2.setType("kuali.reqComponent.type.course.courseset.gpa.min");
896            ReqComponentInfo rc3 = new ReqComponentInfo();
897            rc3.setDesc(toRichText("REQCOMP-3"));
898            rc3.setType("kuali.reqComponent.type.course.courseset.completed.nof");
899            ReqComponentInfo rc4 = new ReqComponentInfo();
900            rc4.setDesc(toRichText("REQCOMP-4"));
901            rc4.setType("kuali.reqComponent.type.course.permission.instructor.required");
902    
903            // statement tree views
904            StatementTreeViewInfo statementTree = new StatementTreeViewInfo();
905            statementTree.setDesc(toRichText("STMT-1"));
906            statementTree.setOperator(StatementOperatorTypeKey.OR);
907            statementTree.setType("kuali.statement.type.program.entrance");
908    
909            StatementTreeViewInfo subTree1 = new StatementTreeViewInfo();
910            subTree1.setDesc(toRichText("STMT-2"));
911            subTree1.setOperator(StatementOperatorTypeKey.AND);
912            subTree1.setType("kuali.statement.type.program.entrance");
913    
914            StatementTreeViewInfo subTree2 = new StatementTreeViewInfo();
915            subTree2.setDesc(toRichText("STMT-3"));
916            subTree2.setOperator(StatementOperatorTypeKey.AND);
917            subTree2.setType("kuali.statement.type.program.entrance");
918    
919            // construct tree with statements and req components
920            reqCompList1.add(rc1);
921            reqCompList1.add(rc2);
922            subTree1.setReqComponents(reqCompList1);
923            reqCompList2.add(rc3);
924            reqCompList2.add(rc4);
925            subTree2.setReqComponents(reqCompList2);
926            subStatements.add(subTree1);
927            subStatements.add(subTree2);
928            statementTree.setStatements(subStatements);
929    
930            return statementTree;
931        }
932    
933            private static RichTextInfo toRichText(String text) {
934                    RichTextInfo richTextInfo = new RichTextInfo();
935                    if (text == null) {
936                            return null;
937                    }
938                    richTextInfo.setPlain(text);
939                    richTextInfo.setFormatted("<p>" + text + "</p>");
940                    return richTextInfo;
941            }
942    
943            @Test(expected=DoesNotExistException.class)
944            public void testUpdateProgramRequirement() throws Exception {
945                    ProgramRequirementInfo progReq = programService.createProgramRequirement(createProgramRequirementTestData());
946            StatementTreeViewInfo treeView = progReq.getStatement();
947    
948            List<ReqComponentInfo> reqCompList1 = new ArrayList<ReqComponentInfo>(3);
949            ReqComponentInfo rc1 = new ReqComponentInfo();
950            rc1.setDesc(toRichText("REQCOMP-1"));
951            rc1.setType("kuali.reqComponent.type.course.courseset.completed.all");
952            ReqComponentInfo rc2 = new ReqComponentInfo();
953            rc2.setDesc(toRichText("REQCOMP-2"));
954            rc2.setType("kuali.reqComponent.type.course.courseset.gpa.min");
955            StatementTreeViewInfo subTree1 = new StatementTreeViewInfo();
956            subTree1.setDesc(toRichText("STMT-5"));
957            subTree1.setOperator(StatementOperatorTypeKey.AND);
958            subTree1.setType("kuali.statement.type.program.entrance");
959            reqCompList1.add(rc1);
960            reqCompList1.add(rc2);
961            subTree1.setReqComponents(reqCompList1);
962    
963            StatementTreeViewInfo oldSubTree1 = treeView.getStatements().get(0);
964            treeView.getStatements().set(0, subTree1);
965            ProgramRequirementInfo updated = programService.updateProgramRequirement(progReq);
966            checkProgramRequirement(progReq, updated);
967            statementService.getStatement(oldSubTree1.getId());
968            }
969    
970        @Test
971        @Ignore public void testDeleteMajorDiscipline() throws IllegalArgumentException, SecurityException, IntrospectionException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, AlreadyExistsException, DataValidationErrorException {
972                    MajorDisciplineDataGenerator generator = new MajorDisciplineDataGenerator();
973                    MajorDisciplineInfo majorDisciplineInfo = generator.getMajorDisciplineInfoTestData();
974                assertNotNull(majorDisciplineInfo);
975                fixLoCategoryIds(majorDisciplineInfo.getLearningObjectives());
976                MajorDisciplineInfo createdMD = programService.createMajorDiscipline(majorDisciplineInfo);
977                assertNotNull(createdMD);
978                assertEquals(DtoConstants.STATE_DRAFT, createdMD.getState());
979                assertEquals(ProgramAssemblerConstants.MAJOR_DISCIPLINE, createdMD.getType());
980                assertEquals("00f5f8c5-fff1-4c8b-92fc-789b891e0849", createdMD.getCredentialProgramId());
981    
982                String majorDisciplineId = createdMD.getId();
983                MajorDisciplineInfo retrievedMD = programService.getMajorDiscipline(majorDisciplineId);
984                assertNotNull(retrievedMD);
985    
986                programService.deleteMajorDiscipline(majorDisciplineId);
987                try {
988                    retrievedMD = programService.getMajorDiscipline(majorDisciplineId);
989                    fail("Retrieval of deleted MajorDiscipline should have thrown exception");
990                } catch (DoesNotExistException e) {}
991        }
992    
993        private void fixLoCategoryIds(List<LoDisplayInfo> loDisplayInfoList) {
994            for (LoDisplayInfo parentLo : loDisplayInfoList) {
995                fixLoCategoryId(parentLo.getLoCategoryInfoList());
996                fixLoCategoryIds(parentLo.getLoDisplayInfoList());
997            }
998        }
999        private void fixLoCategoryId(List<LoCategoryInfo> loCategoryInfoList) {
1000            loCategoryInfoList.get(1).setId(OTHER_LO_CAT_ID);
1001        }
1002    
1003        @Test
1004        public void testUpdateMajorDiscipline() throws IllegalArgumentException, SecurityException, IntrospectionException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, VersionMismatchException, OperationFailedException, PermissionDeniedException {
1005                    MajorDisciplineDataGenerator generator = new MajorDisciplineDataGenerator();
1006                    MajorDisciplineInfo majorDisciplineInfo = generator.getMajorDisciplineInfoTestData();
1007                assertNotNull(majorDisciplineInfo);
1008    //            MajorDisciplineInfo createdMD = programService.createMajorDiscipline(majorDisciplineInfo);
1009                MajorDisciplineInfo major = programService.getMajorDiscipline("d4ea77dd-b492-4554-b104-863e42c5f8b7");
1010                assertNotNull(major);
1011    
1012                // minimal sanity check
1013                assertNotNull(major.getCode());
1014                assertEquals("ANTH", major.getCode());
1015                assertNotNull(major.getType());
1016                assertEquals(ProgramAssemblerConstants.MAJOR_DISCIPLINE, major.getType());
1017                assertNotNull(major.getState());
1018                assertEquals(DtoConstants.STATE_ACTIVE, major.getState());
1019                assertNotNull(major.getId());
1020                assertEquals("d4ea77dd-b492-4554-b104-863e42c5f8b7", major.getId());
1021                assertNotNull(major.getShortTitle());
1022                assertEquals("Anthro", major.getShortTitle());
1023                assertNotNull(major.getLongTitle());
1024                assertEquals("Anthropology", major.getLongTitle());
1025    
1026                // update some fields
1027                major.getCampusLocations().add("MAIN");
1028                major.setLongTitle(major.getLongTitle() + "-updated");
1029                major.getAttributes().put("PIES", "APPLE");
1030    
1031                major.setCip2000Code(major.getCip2000Code() + "-updated");
1032                major.setDiplomaTitle(major.getDiplomaTitle() + "-updated");
1033                major.setTranscriptTitle(major.getTranscriptTitle() + "-updated");
1034                //major.setEndProgramEntryTerm("kuali.atp.FA2008-2009");
1035                //major.setStartTerm("kuali.atp.FA2008-2009");
1036    
1037                major.getCatalogDescr().setPlain(major.getCatalogDescr().getPlain() + "-updated");
1038                major.getCatalogPublicationTargets().add("kuali.lu.publication.GradCatalog");
1039    
1040                for (String orgInfoId : major.getDivisionsFinancialControl()) {
1041                    orgInfoId = orgInfoId + "-updated";
1042                }
1043                for (String orgInfoId : major.getUnitsDeployment()) {
1044                    orgInfoId = orgInfoId + "-updated";
1045                }
1046    
1047                List<String> reqIds = new ArrayList<String>();
1048                reqIds.add("REQ-200");
1049                reqIds.add("REQ-300");
1050                major.setProgramRequirements(reqIds);
1051    
1052               //Perform the update
1053                MajorDisciplineInfo updatedMD = programService.updateMajorDiscipline(major);
1054    
1055                //Verify the update
1056                verifyUpdate(updatedMD);
1057                assertEquals(2, updatedMD.getProgramRequirements().size());
1058    
1059                // Now explicitly get it
1060                MajorDisciplineInfo retrievedMD = programService.getMajorDiscipline(major.getId());
1061                verifyUpdate(retrievedMD);
1062                assertEquals(2, retrievedMD.getProgramRequirements().size());
1063                //TODO: add version update
1064    
1065        }
1066    
1067        @Test
1068        public void testUpdateMajorDisciplineRemoveRule() throws IllegalArgumentException, SecurityException, IntrospectionException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DoesNotExistException, VersionMismatchException {
1069                MajorDisciplineInfo major = programService.getMajorDiscipline("d4ea77dd-b492-4554-b104-863e42c5f8b7");
1070    
1071                List<String> reqIds = new ArrayList<String>(1);
1072                ProgramRequirementInfo req1 = programService.createProgramRequirement(createProgramRequirementTestData());
1073                reqIds.add(req1.getId());
1074                major.setProgramRequirements(reqIds);
1075    
1076               //Perform the update
1077                MajorDisciplineInfo updatedMD = programService.updateMajorDiscipline(major); // FIXME Updated version info isn't returned
1078                MajorDisciplineInfo retrievedMD = programService.getMajorDiscipline(major.getId());
1079    
1080                // Test that we can remove the program requirements
1081                programService.deleteProgramRequirement(req1.getId());
1082                retrievedMD.getProgramRequirements().clear();
1083                MajorDisciplineInfo updatedMD2 = programService.updateMajorDiscipline(retrievedMD);
1084                assertEquals(0, updatedMD2.getProgramRequirements().size());
1085                retrievedMD = programService.getMajorDiscipline(major.getId());
1086                assertEquals(0, retrievedMD.getProgramRequirements().size());
1087        }
1088    
1089    
1090        private void verifyUpdate(MajorDisciplineInfo updatedMD) {
1091            assertNotNull(updatedMD);
1092    
1093            assertEquals(3, updatedMD.getAttributes().size());
1094            assertNotNull(updatedMD.getAttributes().get("PIES"));
1095            assertEquals("APPLE", updatedMD.getAttributes().get("PIES"));
1096    
1097            assertEquals(3, updatedMD.getCampusLocations().size());
1098            assertEquals("NO", updatedMD.getCampusLocations().get(0));
1099            assertEquals("SO", updatedMD.getCampusLocations().get(1));
1100            assertEquals("MAIN", updatedMD.getCampusLocations().get(2));
1101    
1102    //        assertEquals(1, updatedMD.getProgramRequirements().size());
1103    
1104            assertNotNull(updatedMD.getCatalogDescr());
1105            assertEquals("This is the catalog description-updated", updatedMD.getCatalogDescr().getPlain());
1106    
1107            assertNotNull(updatedMD.getCatalogPublicationTargets());
1108            assertEquals(2, updatedMD.getCatalogPublicationTargets().size());
1109    
1110            assertEquals("Anthropology-updated", updatedMD.getLongTitle());
1111            assertEquals("45.0202-updated", updatedMD.getCip2000Code());
1112            assertEquals("TRANSCRIPT-TITLE-updated", updatedMD.getTranscriptTitle());
1113            assertEquals("DIPLOMA-TITLE-updated", updatedMD.getDiplomaTitle() );
1114        }
1115    
1116        @Test
1117        public void testCreateBaccCredentialProgram() throws IllegalArgumentException, SecurityException, IntrospectionException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
1118            CredentialProgramDataGenerator generator = new CredentialProgramDataGenerator(ProgramAssemblerConstants.BACCALAUREATE_PROGRAM);
1119            CredentialProgramInfo credentialProgramInfo = null;
1120                assertNotNull(credentialProgramInfo = generator.getCPTestData());
1121                List<String> coreProgramIds = new ArrayList<String>();
1122                coreProgramIds.add("00f5f8c5-fff1-4c8b-92fc-789b891e0849");
1123                credentialProgramInfo.setCoreProgramIds(coreProgramIds);
1124                CredentialProgramInfo createdCP = programService.createCredentialProgram(credentialProgramInfo);
1125                assertNotNull(createdCP);
1126                assertEquals(DtoConstants.STATE_DRAFT, createdCP.getState());
1127                assertEquals(ProgramAssemblerConstants.BACCALAUREATE_PROGRAM, createdCP.getCredentialProgramType());
1128            }
1129    
1130        @Test
1131        public void testDeleteBaccCredentialProgram() throws DoesNotExistException, InvalidParameterException, MissingParameterException, PermissionDeniedException, OperationFailedException {
1132                    String credentialProgramId = "d02dbbd3-20e2-410d-ab52-1bd6d362748b";
1133                CredentialProgramInfo retrievedCP = programService.getCredentialProgram(credentialProgramId);
1134                assertNotNull(retrievedCP);
1135    
1136                try{
1137                        programService.deleteCredentialProgram(credentialProgramId);
1138                        try {
1139                            retrievedCP = programService.getCredentialProgram(credentialProgramId);
1140                            fail("Retrieval of deleted CredentialProgram should have thrown exception");
1141                        } catch (DoesNotExistException e) {}
1142                }catch (OperationFailedException e) {}
1143        }
1144    
1145        @Test
1146        public void testUpdateBaccCredentialProgram() throws DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, VersionMismatchException, OperationFailedException, PermissionDeniedException {
1147                    String credentialProgramId = "d02dbbd3-20e2-410d-ab52-1bd6d362748b";
1148                CredentialProgramInfo credentialProgramInfo = programService.getCredentialProgram(credentialProgramId);
1149                assertNotNull(credentialProgramInfo);
1150    
1151                // minimal sanity check
1152                assertEquals("BS", credentialProgramInfo.getCode());
1153                assertEquals("B.S.", credentialProgramInfo.getShortTitle());
1154                assertEquals("Bachelor of Science", credentialProgramInfo.getLongTitle());
1155                assertEquals("Bachelor of Science", credentialProgramInfo.getDescr().getPlain());
1156                assertEquals(DtoConstants.STATE_ACTIVE, credentialProgramInfo.getState());
1157                assertEquals("52", credentialProgramInfo.getInstitution().getOrgId());
1158                assertEquals(ProgramAssemblerConstants.UNDERGRAD_PROGRAM_LEVEL, credentialProgramInfo.getProgramLevel());
1159    
1160                // update some fields
1161                //credentialProgramInfo.setCode(credentialProgramInfo.getCode() + "-updated");
1162                //credentialProgramInfo.setShortTitle(credentialProgramInfo.getShortTitle() + "-updated");
1163               // credentialProgramInfo.setLongTitle(credentialProgramInfo.getLongTitle() + "-updated");
1164                credentialProgramInfo.setProgramLevel(ProgramAssemblerConstants.GRADUATE_PROGRAM_LEVEL);
1165                AdminOrgInfo institution = new AdminOrgInfo();
1166                institution.setOrgId("51");
1167                credentialProgramInfo.setInstitution(institution);
1168    
1169               //Perform the update
1170                CredentialProgramInfo updatedCP = programService.updateCredentialProgram(credentialProgramInfo);
1171    
1172                //Verify the update
1173                verifyUpdate(updatedCP);
1174    
1175                // Now explicitly get it
1176                CredentialProgramInfo retrievedCP = programService.getCredentialProgram(credentialProgramInfo.getId());
1177                verifyUpdate(retrievedCP);
1178    
1179                //TODO: add version update
1180    
1181        }
1182    
1183        private void verifyUpdate(CredentialProgramInfo updatedCP) {
1184            assertNotNull(updatedCP);
1185    
1186            //assertEquals("BS-updated", updatedCP.getCode());
1187           // assertEquals("B.S.-updated", updatedCP.getShortTitle());
1188            //assertEquals("Bachelor of Science-updated", updatedCP.getLongTitle());
1189            assertEquals(ProgramAssemblerConstants.GRADUATE_PROGRAM_LEVEL, updatedCP.getProgramLevel());
1190            assertEquals("51", updatedCP.getInstitution().getOrgId());
1191        }
1192    
1193        @Test
1194        public void testCreateCoreProgram() throws IllegalArgumentException, SecurityException, IntrospectionException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
1195            CoreProgramDataGenerator generator = new CoreProgramDataGenerator();
1196            CoreProgramInfo coreProgramInfo = null;
1197                assertNotNull(coreProgramInfo = generator.getCoreProgramTestData());
1198                CoreProgramInfo createdCP = programService.createCoreProgram(coreProgramInfo);
1199                assertNotNull(createdCP);
1200                assertEquals(DtoConstants.STATE_DRAFT, createdCP.getState());
1201                assertEquals(ProgramAssemblerConstants.CORE_PROGRAM, createdCP.getType());
1202            }
1203    
1204        @Test
1205        public void testUpdateVariationsByMajorDiscipline() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DataValidationErrorException, VersionMismatchException{
1206            MajorDisciplineInfo majorDisciplineInfo = null;
1207    
1208            majorDisciplineInfo = programService.getMajorDiscipline("d4ea77dd-b492-4554-b104-863e42c5f8b7");
1209            assertNotNull(majorDisciplineInfo);
1210    
1211            List<ProgramVariationInfo> pvInfos = majorDisciplineInfo.getVariations();
1212            assertNotNull(pvInfos);
1213    
1214            // update variation fields
1215            ProgramVariationInfo pvInfo = pvInfos.get(0);
1216    
1217            pvInfo.setLongTitle(pvInfo.getLongTitle() + "-updated");
1218            pvInfo.setCode(pvInfo.getCode() + "-updated");
1219            pvInfo.setShortTitle(pvInfo.getShortTitle() + "-updated");
1220            RichTextInfo testDesc = pvInfo.getDescr();
1221            testDesc.setPlain(testDesc.getPlain() + "-updated");
1222            pvInfo.setDescr(testDesc);
1223            pvInfo.setCip2000Code(pvInfo.getCip2000Code() + "-updated");
1224            pvInfo.setCip2010Code(pvInfo.getCip2010Code() + "-updated");
1225            pvInfo.setTranscriptTitle("transcriptTitle-updated");
1226            pvInfo.setDiplomaTitle(pvInfo.getDiplomaTitle() + "-updated");
1227    
1228            List<String> campusLocations = new ArrayList<String>();
1229            campusLocations.add(CourseAssemblerConstants.COURSE_CAMPUS_LOCATION_CD_NORTH);
1230            campusLocations.add(CourseAssemblerConstants.COURSE_CAMPUS_LOCATION_CD_SOUTH);
1231            pvInfo.setCampusLocations(campusLocations);
1232    
1233            List<String> testOrgs = new ArrayList<String>();
1234            testOrgs.add("testOrgId");
1235            if (pvInfo.getDivisionsContentOwner() != null) {
1236                pvInfo.getDivisionsContentOwner().clear();
1237                pvInfo.getDivisionsContentOwner().add("testOrgId");
1238            }
1239            else {
1240                pvInfo.setDivisionsContentOwner(testOrgs);
1241            }
1242    
1243            // Perform the update
1244            MajorDisciplineInfo updatedMD = programService.updateMajorDiscipline(majorDisciplineInfo);
1245            List<ProgramVariationInfo> updatedPvInfos = updatedMD.getVariations();
1246            assertNotNull(updatedPvInfos);
1247                
1248            // Verify the update
1249            verifyUpdatedPVinList(pvInfo, updatedPvInfos);
1250    
1251            // Now explicitly get it
1252            List<ProgramVariationInfo> retrievedPVs = programService.getVariationsByMajorDisciplineId(majorDisciplineInfo.getId());
1253            assertNotNull(retrievedPVs);
1254                
1255            // and verify the update
1256            verifyUpdatedPVinList(pvInfo, retrievedPVs);
1257        }
1258    
1259        private void verifyUpdatedPVinList(ProgramVariationInfo pvInfo, List<ProgramVariationInfo> updatedPvInfos) {
1260            boolean found = false;
1261            for (ProgramVariationInfo updatedPV : updatedPvInfos) {
1262                if (updatedPV.getId().equals(pvInfo.getId()) && updatedPV.getState().equals("Active")) {
1263                    verifyUpdate(pvInfo, updatedPV); // see comment in verifyUpdate
1264                    found = true;
1265                    break;
1266                }
1267            }
1268            if (!found) {
1269                fail("Unable to find updated ProgramVariationInfo for comparison");
1270            }
1271        }
1272    
1273        private void verifyUpdate(ProgramVariationInfo source, ProgramVariationInfo target) {
1274            assertNotNull(target);
1275    
1276            assertEquals(source.getDescr().getPlain(), target.getDescr().getPlain());
1277            assertEquals(source.getLongTitle(), target.getLongTitle());
1278            assertEquals(source.getShortTitle(), target.getShortTitle());
1279    
1280            assertEquals(source.getCip2000Code(), target.getCip2000Code());
1281            assertEquals(source.getCip2010Code(), target.getCip2010Code());
1282            assertEquals(source.getTranscriptTitle(), target.getTranscriptTitle());
1283            assertEquals(source.getDiplomaTitle(), target.getDiplomaTitle());
1284    
1285            assertNotNull(target.getCampusLocations());
1286            for(String loc : target.getCampusLocations()){
1287                    assertTrue(CourseAssemblerConstants.COURSE_CAMPUS_LOCATION_CD_NORTH.equals(loc) || CourseAssemblerConstants.COURSE_CAMPUS_LOCATION_CD_SOUTH.equals(loc));
1288            }
1289    
1290            assertNotNull(target.getDivisionsContentOwner());
1291            // TODO: this should actually be passing; get working again after  today's change of
1292            // AdminOrgInfo's to those orgs ID's in Program-related DTOs
1293            // assertEquals("testOrgId", target.getDivisionsContentOwner().get(0));
1294        }
1295    
1296        @Test
1297        public void testCreateVariationsByMajorDiscipline() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, DataValidationErrorException, VersionMismatchException, PermissionDeniedException{
1298            MajorDisciplineInfo majorDisciplineInfo = null;
1299    
1300            majorDisciplineInfo = programService.getMajorDiscipline("d4ea77dd-b492-4554-b104-863e42c5f8b7");
1301            assertNotNull(majorDisciplineInfo);
1302    
1303            List<ProgramVariationInfo> pvInfos = majorDisciplineInfo.getVariations();
1304            assertNotNull(pvInfos);
1305    
1306            ProgramVariationInfo pvInfoS = pvInfos.get(0);
1307            ProgramVariationInfo pvInfoT = new ProgramVariationInfo();
1308    
1309            BeanUtils.copyProperties(pvInfoS, pvInfoT, new String[]{"id"});
1310    
1311            pvInfoT.setLongTitle(pvInfoT.getLongTitle() + "-created");
1312            pvInfoT.setShortTitle(pvInfoT.getShortTitle() + "-created");
1313            RichTextInfo testDesc = pvInfoT.getDescr();
1314            testDesc.setPlain(testDesc.getPlain() + "-created");
1315            pvInfoT.setDescr(testDesc);
1316            pvInfoT.setCip2000Code(pvInfoT.getCip2000Code() + "-created");
1317            pvInfoT.setCip2010Code(pvInfoT.getCip2010Code() + "-created");
1318            pvInfoT.setTranscriptTitle(pvInfoT.getTranscriptTitle() + "-created");
1319            pvInfoT.setDiplomaTitle(pvInfoT.getDiplomaTitle() + "-created");
1320    
1321            // Perform the update: adding the new variation
1322            pvInfos.add(pvInfoT);
1323            MajorDisciplineInfo updatedMD = programService.updateMajorDiscipline(majorDisciplineInfo);
1324            List<ProgramVariationInfo> updatedPvInfos = updatedMD.getVariations();
1325            assertNotNull(updatedPvInfos);
1326            assertEquals(3, updatedPvInfos.size());
1327    
1328            // Verify the update
1329            verifyUpdatedPVinList(pvInfoT, updatedPvInfos);
1330    
1331            // Now explicitly get it
1332            MajorDisciplineInfo retrievedMD = programService.getMajorDiscipline(majorDisciplineInfo.getId());
1333            assertEquals(3, retrievedMD.getVariations().size());
1334    
1335            List<ProgramVariationInfo> retrievedPVs = programService.getVariationsByMajorDisciplineId(majorDisciplineInfo.getId());
1336            assertNotNull(retrievedPVs);
1337            assertEquals(3, updatedPvInfos.size());
1338                
1339            verifyUpdatedPVinList(pvInfoT, retrievedPVs);
1340        }
1341    
1342        @Test
1343        public void testDeleteVariationsByMajorDiscipline() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DataValidationErrorException, VersionMismatchException{
1344            MajorDisciplineInfo majorDisciplineInfo = null;
1345    
1346                majorDisciplineInfo = programService.getMajorDiscipline("d4ea77dd-b492-4554-b104-863e42c5f8b7");
1347                assertNotNull(majorDisciplineInfo);
1348    
1349                List<ProgramVariationInfo> pvInfos = majorDisciplineInfo.getVariations();
1350                assertNotNull(pvInfos);
1351    
1352                //Perform the update: remove a variation
1353                String var1 = pvInfos.get(1).getId();
1354                pvInfos.remove(1);
1355                MajorDisciplineInfo updatedMD = programService.updateMajorDiscipline(majorDisciplineInfo);
1356                List<ProgramVariationInfo> updatedPvInfos = updatedMD.getVariations();
1357                assertNotNull(updatedPvInfos);
1358                assertEquals(2, updatedPvInfos.size());
1359    
1360                // Now explicitly get it
1361                MajorDisciplineInfo retrievedMD = programService.getMajorDiscipline(majorDisciplineInfo.getId());
1362                assertEquals(2, retrievedMD.getVariations().size());
1363    
1364                List<ProgramVariationInfo> retrievedPVs = programService.getVariationsByMajorDisciplineId(majorDisciplineInfo.getId());
1365                assertNotNull(retrievedPVs);
1366                for(ProgramVariationInfo pvi : retrievedPVs){
1367                    if(pvi.getId().equals(var1)){
1368                            assertEquals("Suspended", pvi.getState());
1369                    }
1370                }
1371        }
1372    
1373        @Test(expected=DoesNotExistException.class)
1374        public void testDeleteProgramRequirement() throws Exception {
1375            ProgramRequirementInfo progReq = createProgramRequirementTestData();
1376            ProgramRequirementInfo createdProgReq = programService.createProgramRequirement(progReq);
1377                            programService.deleteProgramRequirement(createdProgReq.getId());
1378            programService.getProgramRequirement(createdProgReq.getId(), null, null);
1379        }
1380    
1381        @Test
1382        public void testUpdateCoreProgram() throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DataValidationErrorException, VersionMismatchException {
1383            CoreProgramInfo core = null;
1384                    core = programService.getCoreProgram("00f5f8c5-fff1-4c8b-92fc-789b891e0849");
1385    
1386                // minimal sanity check
1387                assertNotNull(core);
1388                assertEquals("BS", core.getCode());
1389                assertNotNull(core.getShortTitle());
1390                assertEquals("B.S.", core.getShortTitle());
1391                assertNotNull(core.getLongTitle());
1392                assertEquals("Bachelor of Science", core.getLongTitle());
1393                assertNotNull(core.getDescr());
1394                assertEquals("Anthropology Major", core.getDescr().getPlain());
1395                assertEquals(ProgramAssemblerConstants.CORE_PROGRAM, core.getType());
1396                assertEquals(DtoConstants.STATE_ACTIVE, core.getState());
1397    
1398                // update some fields
1399                core.setCode(core.getCode() + "-updated");
1400                core.setShortTitle(core.getShortTitle() + "-updated");
1401                core.setLongTitle(core.getLongTitle() + "-updated");
1402                core.setTranscriptTitle(core.getTranscriptTitle() + "-updated");
1403                core.setState(DtoConstants.STATE_RETIRED);
1404    
1405               //Perform the update
1406                CoreProgramInfo updatedCP = programService.updateCoreProgram(core);
1407    
1408                //Verify the update
1409                verifyUpdate(updatedCP);
1410    
1411                // Now explicitly get it
1412                CoreProgramInfo retrievedCP = programService.getCoreProgram(core.getId());
1413                verifyUpdate(retrievedCP);
1414    
1415                //TODO: update versioning
1416            }
1417    
1418        private void verifyUpdate(CoreProgramInfo updatedCP) {
1419            assertNotNull(updatedCP);
1420            assertEquals("BS-updated", updatedCP.getCode());
1421            assertEquals("B.S.-updated", updatedCP.getShortTitle());
1422            assertEquals("Bachelor of Science-updated", updatedCP.getLongTitle());
1423            assertEquals("TRANSCRIPT-TITLE-updated", updatedCP.getTranscriptTitle());
1424            assertEquals(DtoConstants.STATE_RETIRED, updatedCP.getState());
1425        }
1426    
1427        @Test
1428        public void testDeleteCoreProgram() throws AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, IllegalArgumentException, SecurityException, IntrospectionException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, DoesNotExistException {
1429                    CoreProgramDataGenerator generator = new CoreProgramDataGenerator();
1430                    CoreProgramInfo coreProgramInfo = generator.getCoreProgramTestData();
1431    
1432                assertNotNull(coreProgramInfo);
1433                fixLoCategoryIds(coreProgramInfo.getLearningObjectives());
1434                CoreProgramInfo createdCP = programService.createCoreProgram(coreProgramInfo);
1435                assertNotNull(createdCP);
1436                assertEquals(DtoConstants.STATE_DRAFT, createdCP.getState());
1437                assertEquals(ProgramAssemblerConstants.CORE_PROGRAM, createdCP.getType());
1438    
1439    
1440                String coreProgramId = createdCP.getId();
1441                CoreProgramInfo retrievedCP = programService.getCoreProgram(coreProgramId);
1442                assertNotNull(retrievedCP);
1443    
1444                try{
1445                        programService.deleteCoreProgram(coreProgramId);
1446                        try {
1447                            retrievedCP = programService.getCoreProgram(coreProgramId);
1448                            fail("Retrieval of deleted coreProgram should have thrown exception");
1449                        } catch (DoesNotExistException e) {}
1450                }catch (OperationFailedException e) {}
1451    
1452        }
1453    
1454        @Test
1455        public void testCreditsProgramRequirement() throws AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DoesNotExistException {
1456            ProgramRequirementInfo progReq = createProgramRequirementTestData();
1457            progReq.setMinCredits(3);
1458            progReq.setMaxCredits(45);
1459            ProgramRequirementInfo createdProgReq = programService.createProgramRequirement(progReq);
1460            assertEquals("3", Integer.toString(createdProgReq.getMinCredits()));
1461            assertEquals("45", Integer.toString(createdProgReq.getMaxCredits()));
1462    
1463            ProgramRequirementInfo progReq2 = programService.getProgramRequirement(createdProgReq.getId(), null, null);
1464            assertEquals("3", Integer.toString(progReq2.getMinCredits()));
1465            assertEquals("45", Integer.toString(progReq2.getMaxCredits()));
1466        }
1467        
1468        private class ServiceMethodInvocationData {
1469            String methodName;
1470            Object[] parameters;
1471            Class<?>[] paramterTypes;
1472        }
1473        
1474        private void invokeForExpectedException(Collection<ServiceMethodInvocationData> methods, Class<? extends Exception> expectedExceptionClass) throws Exception {
1475            for(ServiceMethodInvocationData methodData : methods) {
1476                Method method = programService.getClass().getMethod(methodData.methodName, methodData.paramterTypes);
1477                Throwable expected = null;
1478                Exception unexpected = null;
1479                try {
1480                    method.invoke(programService, methodData.parameters);
1481                }
1482                catch(InvocationTargetException ex) {
1483                    if(ex.getCause() != null && ex.getCause().getClass().equals(expectedExceptionClass)) {
1484                        expected = ex.getCause();
1485                    }
1486                    else {
1487                        unexpected = ex;
1488                        unexpected.printStackTrace();
1489                    }
1490                }
1491                catch(Exception other) {
1492                    unexpected = other;
1493                }
1494                finally {
1495                    assertNotNull("An exception of class: " + expectedExceptionClass.toString() + " was expected, but the method: " + methodData.methodName + " threw this exception: " + unexpected, expected);
1496                }
1497            }
1498        }
1499        
1500        @Test
1501        public void testGetVersionMethodsForInvalidParameters() throws Exception {
1502            String[] getVersionMethods = {"getVersionBySequenceNumber", "getVersions", "getFirstVersion", "getVersionsInDateRange", "getCurrentVersion", "getCurrentVersionOnDate"};
1503            
1504            // build an object array with the appropriate number of arguments for each version method to be called
1505            Object[][] getVersionParams = {new Object[3], new Object[2], new Object[2], new Object[4], new Object[2], new Object[3]};
1506            
1507            // build a class array with the parameter types for each method call
1508            Class<?>[][] getVersionParamTypes = {{String.class, String.class, Long.class}, // for getVersionBySequenceNumber
1509                    {String.class, String.class}, // for getVersions
1510                    {String.class, String.class}, // for getFirstVersion
1511                    {String.class, String.class, Date.class, Date.class}, // for getVersionsInDateRange
1512                    {String.class, String.class}, // for getCurrentVersion
1513                    {String.class, String.class, Date.class}}; // for getCurrentVersionOnDate
1514            
1515            String badRefObjectTypeURI = "BADBADBAD";
1516            Collection<ServiceMethodInvocationData> methods = new ArrayList<ServiceMethodInvocationData>(getVersionMethods.length);
1517            for(int i = 0; i < getVersionMethods.length; i++) {
1518                ServiceMethodInvocationData invocationData = new ServiceMethodInvocationData();
1519                invocationData.methodName = getVersionMethods[i];
1520                
1521                // set the first parameter of each invocation to the invalid data
1522                getVersionParams[i][0] = badRefObjectTypeURI;
1523                
1524                invocationData.parameters = getVersionParams[i];
1525                invocationData.paramterTypes = getVersionParamTypes[i];
1526                
1527                methods.add(invocationData);
1528            }
1529            
1530            invokeForExpectedException(methods, InvalidParameterException.class);
1531        }
1532        
1533        /**
1534         * 
1535         * This method is a catch-all test for code coverage.  
1536         * It calls methods in ProgramServiceImpl that have contracts in the interface but are not yet implemented
1537         * All calls are expected to return null.  Once a method is implemented, its name should be removed from
1538         * the DUMMY_SERVICE_METHODS array.
1539         * 
1540         * NOTE: This method does not work for methods that are overloaded (i.e. have two declarations with the same name, but different parameters)
1541         * 
1542         * @throws Exception
1543         */
1544        @Test
1545        public void testCallDummyMethods() throws Exception {
1546            // We need to get the Method objects, but we do not know or care about the parameter types for the methods
1547            // so get the all methods of the service and load them into a hashtable, indexed by method name
1548            Method[] serviceMethods = ProgramService.class.getMethods();
1549            Map<String, Method> methodMap = new HashMap<String, Method>();
1550            
1551            for(Method m : serviceMethods) {
1552                // if a method is already loaded into the map, ignore subsequent instances with the same name
1553                if(!methodMap.containsKey(m.getName())) {
1554                    methodMap.put(m.getName(), m);
1555                }
1556            }
1557            
1558            for(String s : DUMMY_SERVICE_METHODS) {
1559                Method dummyMethod = methodMap.get(s);
1560                
1561                if(dummyMethod == null) {
1562                    throw new Exception("No method " + s + " defined in ProgramService");
1563                }
1564                
1565                // create a set of null parameters to pass to the method
1566                Object[] params = new Object[dummyMethod.getParameterTypes().length];
1567                
1568                Object returned = dummyMethod.invoke(programService, params);
1569                
1570                assertTrue("The invocation of " + s + " returned a non-null value", returned == null);
1571            }
1572        }
1573        
1574        @Test
1575        public void testCoreProgramVersioning() throws Exception {
1576            CoreProgramDataGenerator dataGen = new CoreProgramDataGenerator();
1577            CoreProgramInfo coreData = dataGen.getCoreProgramTestData();
1578            
1579            coreData.getProgramRequirements().clear();
1580            
1581            CoreProgramInfo core = programService.createCoreProgram(coreData);
1582            
1583            CoreProgramInfo newCore = programService.createNewCoreProgramVersion(core.getVersionInfo().getVersionIndId(), "test core program versioning");
1584            
1585            assertNotNull(newCore);
1586            
1587            programService.setCurrentCoreProgramVersion(newCore.getId(), null);
1588            
1589            // create a second version, and ensure the sequence numbers are different
1590            CoreProgramInfo secondVersion = null;
1591            
1592            try {
1593                secondVersion = programService.createNewCoreProgramVersion(core.getVersionInfo().getVersionIndId(), "test core program second version");
1594                assertTrue(true);
1595            }
1596            catch (Exception e) {
1597                assertTrue(false);
1598            }
1599            
1600            assertNotNull(secondVersion);
1601            
1602            assertTrue(newCore.getVersionInfo().getSequenceNumber() != secondVersion.getVersionInfo().getSequenceNumber());
1603            
1604        }
1605        
1606    }