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