View Javadoc

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