View Javadoc

1   package org.kuali.student.enrollment.class2.courseoffering.service.impl;
2   
3   import org.apache.commons.lang.StringUtils;
4   import org.joda.time.DateTime;
5   import org.joda.time.Duration;
6   import org.junit.Before;
7   import org.junit.Test;
8   import org.junit.runner.RunWith;
9   import org.kuali.student.enrollment.class1.lui.service.impl.LuiServiceDataLoader;
10  import org.kuali.student.enrollment.class2.acal.util.AcalTestDataLoader;
11  import org.kuali.student.enrollment.class2.acal.util.MockAcalTestDataLoader;
12  import org.kuali.student.enrollment.courseoffering.dto.ActivityOfferingInfo;
13  import org.kuali.student.enrollment.courseoffering.dto.CourseOfferingInfo;
14  import org.kuali.student.enrollment.courseoffering.dto.FinalExam;
15  import org.kuali.student.enrollment.courseoffering.dto.FormatOfferingInfo;
16  import org.kuali.student.enrollment.courseoffering.dto.OfferingInstructorInfo;
17  import org.kuali.student.enrollment.courseoffering.service.CourseOfferingService;
18  import org.kuali.student.enrollment.lui.service.LuiService;
19  import org.kuali.student.lum.lrc.service.util.MockLrcTestDataLoader;
20  import org.kuali.student.r2.common.dto.AttributeInfo;
21  import org.kuali.student.r2.common.dto.ContextInfo;
22  import org.kuali.student.r2.common.dto.RichTextInfo;
23  import org.kuali.student.r2.common.dto.StatusInfo;
24  import org.kuali.student.r2.common.dto.TimeOfDayInfo;
25  import org.kuali.student.r2.common.exceptions.DataValidationErrorException;
26  import org.kuali.student.r2.common.exceptions.DependentObjectsExistException;
27  import org.kuali.student.r2.common.exceptions.DoesNotExistException;
28  import org.kuali.student.r2.common.exceptions.InvalidParameterException;
29  import org.kuali.student.r2.common.exceptions.MissingParameterException;
30  import org.kuali.student.r2.common.exceptions.OperationFailedException;
31  import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
32  import org.kuali.student.r2.common.exceptions.ReadOnlyException;
33  import org.kuali.student.r2.common.exceptions.VersionMismatchException;
34  import org.kuali.student.r2.common.util.ContextUtils;
35  import org.kuali.student.r2.common.util.constants.LuServiceConstants;
36  import org.kuali.student.r2.common.util.constants.LuiServiceConstants;
37  import org.kuali.student.r2.core.acal.service.AcademicCalendarService;
38  import org.kuali.student.r2.core.atp.service.AtpService;
39  import org.kuali.student.r2.core.class1.state.dto.LifecycleInfo;
40  import org.kuali.student.r2.core.class1.state.dto.StateInfo;
41  import org.kuali.student.r2.core.class1.state.service.StateService;
42  import org.kuali.student.r2.core.class1.type.service.TypeService;
43  import org.kuali.student.r2.core.constants.AtpServiceConstants;
44  import org.kuali.student.r2.core.scheduling.SchedulingServiceDataLoader;
45  import org.kuali.student.r2.core.scheduling.constants.SchedulingServiceConstants;
46  import org.kuali.student.r2.core.scheduling.dto.TimeSlotInfo;
47  import org.kuali.student.r2.core.scheduling.service.SchedulingService;
48  import org.kuali.student.r2.core.scheduling.util.SchedulingServiceUtil;
49  import org.kuali.student.r2.lum.course.dto.CourseInfo;
50  import org.kuali.student.r2.lum.course.service.CourseService;
51  import org.kuali.student.r2.lum.lrc.dto.ResultValuesGroupInfo;
52  import org.kuali.student.r2.lum.lrc.service.LRCService;
53  import org.kuali.student.r2.lum.util.constants.LrcServiceConstants;
54  import org.springframework.test.context.ContextConfiguration;
55  import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
56  
57  import javax.annotation.Resource;
58  import java.util.ArrayList;
59  import java.util.Arrays;
60  import java.util.Calendar;
61  import java.util.Collections;
62  import java.util.Comparator;
63  import java.util.Date;
64  import java.util.List;
65  
66  import static org.junit.Assert.assertEquals;
67  import static org.junit.Assert.assertNotNull;
68  import static org.junit.Assert.assertTrue;
69  import static org.junit.Assert.fail;
70  
71  @RunWith(SpringJUnit4ClassRunner.class)
72  @ContextConfiguration(locations = {"classpath:co-test-with-mocks-context.xml"})
73  public class TestCourseOfferingServiceImplWithClass1Mocks {
74  
75      public static String principalId = "123";
76      public ContextInfo callContext = new ContextInfo();
77  
78      @Resource(name = "coService")
79      protected CourseOfferingService courseOfferingService;
80      @Resource(name = "courseService")
81      protected CourseService courseService;
82      @Resource(name = "stateService")
83      protected StateService stateService;
84      @Resource(name = "typeService")
85      protected TypeService typeService;
86      @Resource(name = "luiService")
87      protected LuiService luiService;
88      @Resource(name = "acalService")
89      protected AcademicCalendarService acalService;
90      @Resource(name = "atpService")
91      protected AtpService atpService;
92      @Resource(name = "LrcService")
93      protected LRCService lrcService;
94      @Resource(name = "schedulingService")
95      protected SchedulingService schedulingService;
96      @Resource(name = "schedulingServiceDataLoader")
97      private SchedulingServiceDataLoader schedulingServiceDataLoader;
98  
99      @Before
100     public void setUp() {
101         callContext.setPrincipalId(principalId);
102         try {
103             new CourseR1TestDataLoader(this.courseService).loadData();
104             new LuiServiceDataLoader(this.luiService).loadData();
105 
106             // due to KSENROLL-4185, data must be loaded into the mock Atp and mock Acal services
107             AcalTestDataLoader acalLoader = new AcalTestDataLoader(this.atpService);
108             acalLoader.loadTerm("testAtpId1", "test1", "2000-01-01 00:00:00.0", "2100-12-31 00:00:00.0", AtpServiceConstants.ATP_FALL_TYPE_KEY, AtpServiceConstants.ATP_OFFICIAL_STATE_KEY, "description 1");
109             new MockAcalTestDataLoader(this.acalService).loadData();
110             new MockLrcTestDataLoader(this.lrcService).loadData();
111 
112             createStateTestData();
113             createSchedulingServiceData();
114         } catch (Exception ex) {
115             throw new RuntimeException(ex);
116         }
117     }
118 
119     protected void createSchedulingServiceData() throws Exception {
120         schedulingServiceDataLoader.loadData();
121     }
122 
123     protected void createStateTestData() throws Exception {
124 
125         // ActivityOffering state
126         cleanupStateTestData( LuiServiceConstants.LUI_AO_STATE_DRAFT_KEY );
127         cleanupLifecycleTestData( LuiServiceConstants.ACTIVITY_OFFERING_LIFECYCLE_KEY );
128         LifecycleInfo aoLifecycle = addLifecycle( LuiServiceConstants.ACTIVITY_OFFERING_LIFECYCLE_KEY );
129         addState( aoLifecycle, LuiServiceConstants.LUI_AO_STATE_DRAFT_KEY, true );
130 
131         // FormatOffering state
132         cleanupStateTestData( LuiServiceConstants.LUI_FO_STATE_DRAFT_KEY );
133         cleanupLifecycleTestData( LuiServiceConstants.FORMAT_OFFERING_LIFECYCLE_KEY );
134         LifecycleInfo foLifecycle = addLifecycle( LuiServiceConstants.FORMAT_OFFERING_LIFECYCLE_KEY );
135         addState( foLifecycle, LuiServiceConstants.LUI_FO_STATE_DRAFT_KEY, true );
136 
137         // CourseOffering state
138         cleanupStateTestData( LuiServiceConstants.LUI_CO_STATE_DRAFT_KEY );
139         cleanupLifecycleTestData( LuiServiceConstants.COURSE_OFFERING_LIFECYCLE_KEY );
140         LifecycleInfo coLifecycle = addLifecycle( LuiServiceConstants.COURSE_OFFERING_LIFECYCLE_KEY );
141         addState( coLifecycle, LuiServiceConstants.LUI_CO_STATE_DRAFT_KEY, true );
142     }
143 
144     // TODO: temporary stop-gap because SS throws an error about duplicate-data; this cleans state from previous runs
145     private void cleanupStateTestData( String state ) {
146         try {
147             stateService.deleteState( state, callContext );
148         } catch( Exception e ) { }
149     }
150 
151     // TODO: temporary stop-gap because SS throws an error about duplicate-data; this cleans state from previous runs
152     private void cleanupLifecycleTestData( String name ) {
153         try {
154             stateService.deleteLifecycle( name, callContext );
155         } catch( Exception e ) { }
156     }
157 
158     private LifecycleInfo addLifecycle( String name ) throws Exception {
159 
160         LifecycleInfo origLife = new LifecycleInfo();
161         RichTextInfo rti = new RichTextInfo();
162         rti.setFormatted("<b>Formatted</b> lifecycle for testing purposes");
163         rti.setPlain("Plain lifecycle for testing purposes");
164         origLife.setDescr(rti);
165         origLife.setKey( name );
166         origLife.setName( "TEST_NAME" );
167         origLife.setRefObjectUri( "TEST_URI" );
168         AttributeInfo attr = new AttributeInfo();
169         attr.setKey("attribute.key");
170         attr.setValue("attribute value");
171         origLife.getAttributes().add(attr);
172 
173         return stateService.createLifecycle(origLife.getKey(), origLife, callContext);
174     }
175 
176     private StateInfo addState( LifecycleInfo lifecycleInfo, String state, boolean isInitialState ) throws Exception {
177 
178         StateInfo orig = new StateInfo();
179         orig.setKey(state);
180         orig.setLifecycleKey(lifecycleInfo.getKey());
181         RichTextInfo rti = new RichTextInfo();
182         rti.setFormatted("<b>Formatted again</b> state for testing purposes");
183         rti.setPlain("Plain state again for testing purposes");
184         orig.setDescr(rti);
185         orig.setName("Testing state");
186         Date effDate = new Date();
187         orig.setEffectiveDate(effDate);
188         Calendar cal = Calendar.getInstance();
189         cal.set(2022, 8, 23);
190         orig.setExpirationDate(cal.getTime());
191         AttributeInfo attr = new AttributeInfo();
192         attr.setKey("attribute.key");
193         attr.setValue("attribute value");
194         orig.getAttributes().add(attr);
195         orig.setIsInitialState(isInitialState);
196 
197         return stateService.createState(orig.getLifecycleKey(), orig.getKey(), orig, callContext);
198     }
199 
200     @Test
201     public void testCRUD() throws DoesNotExistException,
202             DataValidationErrorException, InvalidParameterException, MissingParameterException,
203             OperationFailedException, PermissionDeniedException, ReadOnlyException, VersionMismatchException,
204             DependentObjectsExistException {
205         CourseOfferingInfo co = this.testCRUDCourseOffering();
206         FormatOfferingInfo fo = this.testCRUDFormatOffering(co);
207         ActivityOfferingInfo ao = this.testCRUDActivityOffering(fo);
208 
209         searchForTimeSlots(ao);
210 
211         this.testDeletes(co, fo, ao);
212     }
213 
214     public void searchForTimeSlots(ActivityOfferingInfo ao) throws PermissionDeniedException, MissingParameterException,
215             InvalidParameterException, OperationFailedException, DoesNotExistException {
216         /*
217          *  Search for time slots for an AO in a Fall term, with days == Tues, Thurs, and start time == 8am
218          */
219         String aoId = ao.getId();
220         List<Integer> days = new ArrayList<Integer>();
221         days.add(3);
222         days.add(5);
223         Collections.sort(days);  //  Make the order predictable.
224 
225         TimeOfDayInfo startTime = SchedulingServiceUtil.makeTimeOfDayFromMilitaryTimeString("08:00");
226         //  Define some end times
227         TimeOfDayInfo endTime850 =  SchedulingServiceUtil.makeTimeOfDayFromMilitaryTimeString("08:50");
228         TimeOfDayInfo endTime910 =  SchedulingServiceUtil.makeTimeOfDayFromMilitaryTimeString("09:10");
229         TimeOfDayInfo endTime950 =  SchedulingServiceUtil.makeTimeOfDayFromMilitaryTimeString("09:50");
230         TimeOfDayInfo endTime1050 =  SchedulingServiceUtil.makeTimeOfDayFromMilitaryTimeString("10:50");
231         TimeOfDayInfo endTime1110 =  SchedulingServiceUtil.makeTimeOfDayFromMilitaryTimeString("11:10");
232 
233         //  Search
234         List<TimeSlotInfo> timeSlots = courseOfferingService
235                 .getAllowedTimeSlotsByDaysAndStartTimeForActivityOffering(aoId, days, startTime, ContextUtils.createDefaultContextInfo());
236 
237         assertEquals(3, timeSlots.size());
238 
239         //  Make the time slot order predictable.
240         Collections.sort(timeSlots, SchedulingServiceUtil.makeTimeSlotComparator());
241 
242         //  Type, days, start time should be the same
243         for (TimeSlotInfo ts : timeSlots) {
244             assertEquals(SchedulingServiceConstants.TIME_SLOT_TYPE_ACTIVITY_OFFERING_STANDARD_FULLTERM_FALL, ts.getTypeKey());
245             List<Integer> tsDays = new ArrayList<Integer>();
246             tsDays.addAll(ts.getWeekdays());
247             Collections.sort(tsDays);
248             assertEquals(days.toString(), tsDays.toString());
249             assertEquals(startTime.getMilliSeconds(), ts.getStartTime().getMilliSeconds());
250         }
251 
252         //  Check end times.
253         TimeSlotInfo endTime = timeSlots.get(0);
254         assertEquals(endTime850.getMilliSeconds(), endTime.getEndTime().getMilliSeconds());
255         endTime = timeSlots.get(1);
256         assertEquals(endTime910.getMilliSeconds(), endTime.getEndTime().getMilliSeconds());
257         endTime = timeSlots.get(2);
258         assertEquals(endTime950.getMilliSeconds(), endTime.getEndTime().getMilliSeconds());
259 
260         /*
261          *  Search for time slots for an AO in a Fall term, with days == MWF, and start time == 10am
262          */
263         startTime = SchedulingServiceUtil.makeTimeOfDayFromMilitaryTimeString("10:00");
264 
265         days = new ArrayList<Integer>();
266         days.add(2);
267         days.add(4);
268         days.add(6);
269         Collections.sort(days);
270 
271         timeSlots = courseOfferingService
272                 .getAllowedTimeSlotsByDaysAndStartTimeForActivityOffering(aoId, days, startTime, ContextUtils.createDefaultContextInfo());
273 
274         assertEquals(2, timeSlots.size());
275 
276         //  Type, days, start time should be the same
277         for (TimeSlotInfo ts : timeSlots) {
278             assertEquals(SchedulingServiceConstants.TIME_SLOT_TYPE_ACTIVITY_OFFERING_STANDARD_FULLTERM_FALL, ts.getTypeKey());
279             List<Integer> tsDays = new ArrayList<Integer>();
280             tsDays.addAll(ts.getWeekdays());
281             Collections.sort(tsDays);
282             assertEquals(days.toString(), tsDays.toString());
283             assertEquals(startTime.getMilliSeconds(), ts.getStartTime().getMilliSeconds());
284         }
285 
286         //  Check end times.
287         endTime = timeSlots.get(0);
288         assertEquals(endTime1050.getMilliSeconds(), endTime.getEndTime().getMilliSeconds());
289         endTime = timeSlots.get(1);
290         assertEquals(endTime1110.getMilliSeconds(), endTime.getEndTime().getMilliSeconds());
291     }
292 
293     private CourseOfferingInfo testCRUDCourseOffering() throws DoesNotExistException,
294             DataValidationErrorException, InvalidParameterException, MissingParameterException,
295             OperationFailedException, PermissionDeniedException, ReadOnlyException, VersionMismatchException {
296         // get course
297         CourseInfo course;
298         try {
299             course = courseService.getCourse("COURSE1", ContextUtils.getContextInfo());
300         } catch (Exception ex) {
301             throw new RuntimeException(ex);
302         }
303         // create co from course
304         List<String> optionKeys = new ArrayList<String>();
305         CourseOfferingInfo orig = new CourseOfferingInfo();
306         orig.setCourseId(course.getId());
307         orig.setTermId("testAtpId1");
308         orig.setTypeKey(LuiServiceConstants.COURSE_OFFERING_TYPE_KEY);
309         orig.setStateKey(LuiServiceConstants.LUI_CO_STATE_DRAFT_KEY);
310         orig.setCourseOfferingTitle("my name");
311         orig.setWaitlistLevelTypeKey("waitlist key");
312         orig.setHasWaitlist(true);
313         orig.setFinalExamType(FinalExam.STANDARD.toString());
314         orig.setIsEvaluated(true);
315         orig.setIsFeeAtActivityOffering(false);
316         orig.setFundingSource("funding source");
317         orig.setCourseOfferingCode("CODE");
318         orig.setCourseOfferingTitle("Title");
319 
320         orig.getStudentRegistrationGradingOptions().add(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_AUDIT);
321         orig.getStudentRegistrationGradingOptions().add(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_PASSFAIL);
322         orig.setGradingOptionId(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_LETTER);
323 
324         CourseOfferingInfo info = courseOfferingService.createCourseOffering(orig.getCourseId(), orig.getTermId(), 
325                 orig.getTypeKey(), orig, optionKeys, callContext);
326         assertNotNull(info);
327         assertNotNull(info.getId());
328         assertEquals(orig.getCourseId(), info.getCourseId());
329         assertEquals(orig.getTermId(), info.getTermId());
330         assertEquals(orig.getStateKey(), info.getStateKey());
331         assertEquals(orig.getTypeKey(), info.getTypeKey());
332         assertEquals(orig.getWaitlistLevelTypeKey(), info.getWaitlistLevelTypeKey());
333         assertEquals(orig.getHasWaitlist(), info.getHasWaitlist());
334         assertEquals(orig.getFinalExamType(), info.getFinalExamType());
335         assertEquals(orig.getIsFeeAtActivityOffering(), info.getIsFeeAtActivityOffering());
336         assertEquals(orig.getFundingSource(), info.getFundingSource());
337         assertEquals(course.getCode(), info.getCourseOfferingCode());
338 //        assertEquals(course.getCourseNumberSuffix(), info.getCourseNumberSuffix());
339         assertEquals(course.getSubjectArea(), info.getSubjectArea());
340         if (course.getDescr() != null) {
341             assertEquals(course.getDescr().getPlain(), info.getDescr().getPlain());
342             assertEquals(course.getDescr().getFormatted(), info.getDescr().getFormatted());
343         }
344 //        assertEquals(2,info.getStudentRegistrationOptionIds().size());
345 //        assertTrue(info.getStudentRegistrationOptionIds().contains(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_AUDIT));
346 //        assertTrue(info.getStudentRegistrationOptionIds().contains(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_PASSFAIL));
347 //
348 //        assertEquals(2,info.getGradingOptionIds().size());
349 //        assertTrue(info.getGradingOptionIds().contains(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_LETTER));
350 //        assertTrue(info.getGradingOptionIds().contains(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_PERCENTAGE));
351 
352         // TODO: test for these things 
353 //        assertEquals(course.getUnitsContentOwnerOrgIds(), info.getUnitsContentOwnerOrgIds());
354 //        assertEquals(course.getUnitsDeploymentOrgIds(), info.getUnitsDeploymentOrgIds());
355 
356 
357         // refetch co 
358         orig = info;
359         info = courseOfferingService.getCourseOffering(orig.getId(), callContext);
360         assertNotNull(info);
361         assertEquals(orig.getId(), info.getId());
362         assertEquals(orig.getCourseId(), info.getCourseId());
363         assertEquals(orig.getTermId(), info.getTermId());
364         assertEquals(orig.getStateKey(), info.getStateKey());
365         assertEquals(orig.getTypeKey(), info.getTypeKey());
366 
367         // update co
368         orig = info;
369         orig.setIsHonorsOffering(true);
370         orig.setMaximumEnrollment(40);
371         orig.setMinimumEnrollment(10);
372         List<OfferingInstructorInfo> instructors = new ArrayList<OfferingInstructorInfo>();
373 //        OfferingInstructorInfo instructor = new OfferingInstructorInfo();
374 //        instructor.setPersonId("Pers-1");
375 //        instructor.setPercentageEffort(Float.valueOf("60"));
376 //        instructor.setTypeKey(LprServiceConstants.INSTRUCTOR_MAIN_TYPE_KEY);
377 //        instructor.setStateKey(LprServiceConstants.ASSIGNED_STATE_KEY);
378         // TODO: add this back in and test for it
379 //        instructors.add(instructor);
380         orig.setInstructors(instructors);
381         info = courseOfferingService.updateCourseOffering(orig.getId(), orig, callContext);
382         assertNotNull(info);
383         assertEquals(orig.getId(), info.getId());
384         assertEquals(orig.getCourseId(), info.getCourseId());
385         assertEquals(orig.getTermId(), info.getTermId());
386         assertEquals(orig.getStateKey(), info.getStateKey());
387         assertEquals(orig.getTypeKey(), info.getTypeKey());
388         assertEquals(orig.getIsHonorsOffering(), info.getIsHonorsOffering());
389         assertEquals(orig.getMaximumEnrollment(), info.getMaximumEnrollment());
390         assertEquals(orig.getMinimumEnrollment(), info.getMinimumEnrollment());
391         assertEquals(orig.getInstructors().size(), info.getInstructors().size());
392 //        OfferingInstructorInfo origInst1 = orig.getInstructors().get(0);
393 //        OfferingInstructorInfo infoInst1 = info.getInstructors().get(0);
394 //        assertEquals(origInst1.getPersonId(), infoInst1.getPersonId());
395 //        assertEquals(origInst1.getPercentageEffort(), infoInst1.getPercentageEffort());
396 //        assertEquals(origInst1.getTypeKey(), infoInst1.getTypeKey());
397 //        assertEquals(origInst1.getStateKey(), infoInst1.getStateKey());
398         return info;
399     }
400 
401     private void testDeletes(CourseOfferingInfo co, FormatOfferingInfo fo, ActivityOfferingInfo ao)
402             throws InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DoesNotExistException, DependentObjectsExistException {
403 
404         // delete activity offering
405         StatusInfo status = this.courseOfferingService.deleteActivityOffering(ao.getId(), callContext);
406         assertNotNull(status);
407         assertEquals(Boolean.TRUE, status.getIsSuccess());
408 
409         try {
410             ao = courseOfferingService.getActivityOffering(ao.getId(), callContext);
411             fail("should have thrown DoesNotExistException");
412         } catch (DoesNotExistException ex) {
413             // expected
414         }
415 
416         // delete fo
417         status = this.courseOfferingService.deleteFormatOffering(fo.getId(), callContext);
418         assertNotNull(status);
419         assertEquals(Boolean.TRUE, status.getIsSuccess());
420 
421         try {
422             fo = courseOfferingService.getFormatOffering(fo.getId(), callContext);
423             fail("should have thrown DoesNotExistException");
424         } catch (DoesNotExistException ex) {
425             // expected
426         }
427 
428         // delete co
429         status = this.courseOfferingService.deleteCourseOffering(co.getId(), callContext);
430         assertNotNull(status);
431         assertEquals(Boolean.TRUE, status.getIsSuccess());
432 
433         try {
434             co = courseOfferingService.getCourseOffering(co.getId(), callContext);
435             fail("should have thrown DoesNotExistException");
436         } catch (DoesNotExistException ex) {
437             // expected
438         }
439     }
440 
441     private FormatOfferingInfo testCRUDFormatOffering(CourseOfferingInfo co)
442             throws DoesNotExistException,
443             InvalidParameterException, MissingParameterException,
444             OperationFailedException, PermissionDeniedException, DataValidationErrorException,
445                    VersionMismatchException, ReadOnlyException, DependentObjectsExistException {
446         FormatOfferingInfo orig = new FormatOfferingInfo();
447         orig.setCourseOfferingId(co.getId());
448         orig.setFormatId("COURSE1-FORMAT1");
449         orig.setActivityOfferingTypeKeys(Arrays.asList(LuiServiceConstants.LECTURE_ACTIVITY_OFFERING_TYPE_KEY));
450         orig.setTypeKey(LuiServiceConstants.FORMAT_OFFERING_TYPE_KEY);
451         orig.setStateKey(LuiServiceConstants.LUI_FO_STATE_DRAFT_KEY);
452         FormatOfferingInfo info = courseOfferingService.createFormatOffering(orig.getCourseOfferingId(), orig.getFormatId(), orig.getTypeKey(), orig, callContext);
453         assertNotNull(info);
454         assertNotNull(info.getId());
455         assertEquals(orig.getCourseOfferingId(), info.getCourseOfferingId());
456         assertEquals(orig.getStateKey(), info.getStateKey());
457         assertEquals(orig.getTypeKey(), info.getTypeKey());
458         assertEquals(orig.getFormatId(), info.getFormatId());
459         // TODO: turn these tests back on once we get the corresponding JPA entities working 
460 //        assertEquals(orig.getActivityOfferingTypeKeys().size(), info.getActivityOfferingTypeKeys().size());
461 //        assertEquals(orig.getActivityOfferingTypeKeys().get(0), info.getActivityOfferingTypeKeys().get(0));
462 
463         List<FormatOfferingInfo> formats = courseOfferingService.getFormatOfferingsByCourseOffering(co.getId(), callContext);
464         info = formats.get(0);
465         assertNotNull(info);
466         assertNotNull(info.getId());
467         assertEquals(orig.getCourseOfferingId(), info.getCourseOfferingId());
468         assertEquals(orig.getStateKey(), info.getStateKey());
469         assertEquals(orig.getTypeKey(), info.getTypeKey());
470         assertEquals(orig.getFormatId(), info.getFormatId());
471 
472         orig = info;
473         info = courseOfferingService.getFormatOffering(orig.getId(), callContext);
474         assertNotNull(info);
475         assertEquals(orig.getId(), info.getId());
476         assertEquals(orig.getCourseOfferingId(), info.getCourseOfferingId());
477         assertEquals(orig.getStateKey(), info.getStateKey());
478         assertEquals(orig.getTypeKey(), info.getTypeKey());
479         assertEquals(orig.getFormatId(), info.getFormatId());
480 //        assertEquals(orig.getActivityOfferingTypeKeys().size(), info.getActivityOfferingTypeKeys().size());
481 //        assertEquals(orig.getActivityOfferingTypeKeys().get(0), info.getActivityOfferingTypeKeys().get(0));
482 
483         orig = info;
484         orig.setActivityOfferingTypeKeys(Arrays.asList(LuiServiceConstants.LECTURE_ACTIVITY_OFFERING_TYPE_KEY));
485         info = courseOfferingService.updateFormatOffering(orig.getId(), orig, callContext);
486         assertNotNull(info);
487         assertEquals(orig.getId(), info.getId());
488         assertEquals(orig.getCourseOfferingId(), info.getCourseOfferingId());
489         assertEquals(orig.getStateKey(), info.getStateKey());
490         assertEquals(orig.getTypeKey(), info.getTypeKey());
491         assertEquals(orig.getFormatId(), info.getFormatId());
492 //        assertEquals(orig.getActivityOfferingTypeKeys().size(), info.getActivityOfferingTypeKeys().size());
493 //        assertEquals(orig.getActivityOfferingTypeKeys().get(0), info.getActivityOfferingTypeKeys().get(0));
494         return info;
495     }
496 
497 
498     public ActivityOfferingInfo testCRUDActivityOffering(FormatOfferingInfo fo)
499             throws DoesNotExistException,
500             InvalidParameterException, MissingParameterException,
501             OperationFailedException, PermissionDeniedException, DataValidationErrorException,
502             ReadOnlyException, VersionMismatchException {
503 
504         ActivityOfferingInfo orig = new ActivityOfferingInfo();
505         orig.setFormatOfferingId(fo.getId());
506         orig.setActivityId(fo.getId() + "." + LuServiceConstants.COURSE_ACTIVITY_LECTURE_TYPE_KEY);
507         orig.setTypeKey(LuiServiceConstants.LECTURE_ACTIVITY_OFFERING_TYPE_KEY);
508         orig.setStateKey(LuiServiceConstants.LUI_AO_STATE_DRAFT_KEY);
509         orig.setMinimumEnrollment(100);
510         orig.setMaximumEnrollment(150);
511         orig.setIsEvaluated(true);
512         orig.setIsMaxEnrollmentEstimate(false);
513         orig.setIsHonorsOffering(true);
514         orig.setScheduleIds(generateScheduleIdList("testScheduleId1", "testScheduleId2", "testScheduleId3"));
515 
516 
517         ActivityOfferingInfo info = courseOfferingService.createActivityOffering(orig.getFormatOfferingId(), orig.getActivityId(), orig.getTypeKey(), orig, callContext);
518         assertNotNull(info);
519         assertNotNull(info.getId());
520         assertEquals(orig.getStateKey(), info.getStateKey());
521         assertEquals(orig.getTypeKey(), info.getTypeKey());
522         assertEquals(orig.getFormatOfferingId(), info.getFormatOfferingId());
523         assertEquals(orig.getActivityId(), info.getActivityId());
524         assertEquals(orig.getMinimumEnrollment(), info.getMinimumEnrollment());
525         assertEquals(orig.getMaximumEnrollment(), info.getMaximumEnrollment());
526         assertEquals(orig.getIsEvaluated(), info.getIsEvaluated());
527         assertEquals(orig.getIsMaxEnrollmentEstimate(), info.getIsMaxEnrollmentEstimate());
528         assertEquals(orig.getIsHonorsOffering(), info.getIsHonorsOffering());
529         compareList(orig.getScheduleIds(), 3, info.getScheduleIds());
530 
531         orig = info;
532         info = courseOfferingService.getActivityOffering(orig.getId(), callContext);
533         assertNotNull(info);
534         assertEquals(orig.getId(), info.getId());
535         assertEquals(orig.getStateKey(), info.getStateKey());
536         assertEquals(orig.getTypeKey(), info.getTypeKey());
537         assertEquals(orig.getFormatOfferingId(), info.getFormatOfferingId());
538         assertEquals(orig.getActivityId(), info.getActivityId());
539         assertEquals(orig.getMinimumEnrollment(), info.getMinimumEnrollment());
540         assertEquals(orig.getMaximumEnrollment(), info.getMaximumEnrollment());
541         compareList(orig.getScheduleIds(), 3, info.getScheduleIds());
542 
543         orig = info;
544         orig.setMinimumEnrollment(100);
545         orig.getScheduleIds().add("testScheduleId4");
546         info = courseOfferingService.updateActivityOffering(orig.getId(), orig, callContext);
547         assertNotNull(info);
548         assertEquals(orig.getId(), info.getId());
549         assertEquals(orig.getStateKey(), info.getStateKey());
550         assertEquals(orig.getTypeKey(), info.getTypeKey());
551         assertEquals(orig.getFormatOfferingId(), info.getFormatOfferingId());
552         assertEquals(orig.getActivityId(), info.getActivityId());
553         assertEquals(orig.getMinimumEnrollment(), info.getMinimumEnrollment());
554         assertEquals(orig.getMaximumEnrollment(), info.getMaximumEnrollment());
555         compareList(orig.getScheduleIds(), 4, info.getScheduleIds());
556         return info;
557     }
558 
559     private void compareList(List<String> expectedList, int expectedSize, List<String> actualList) {
560         assertEquals(expectedSize, actualList.size());
561         for(String expected : expectedList) {
562             assertTrue(actualList.contains(expected));
563         }
564     }
565 
566     private List<String> generateScheduleIdList(String... ids) {
567         List<String> scheduleIds = new ArrayList<String>();
568         for(String id : ids) {
569             scheduleIds.add(id);
570         }
571         return scheduleIds;
572     }
573 }