/** * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at the * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Initial code contributed and copyrighted by<br> * frentix GmbH, http://www.frentix.com * <p> */ package org.olat.modules.coach; import static org.junit.Assert.assertNotNull; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Random; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.olat.basesecurity.GroupRoles; import org.olat.core.commons.persistence.DB; import org.olat.core.id.Identity; import org.olat.course.CourseFactory; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.group.manager.BusinessGroupRelationDAO; import org.olat.modules.coach.model.CourseStatEntry; import org.olat.modules.coach.model.EfficiencyStatementEntry; import org.olat.modules.coach.model.GroupStatEntry; import org.olat.modules.coach.model.SearchCoachedIdentityParams; import org.olat.modules.coach.model.StudentStatEntry; import org.olat.modules.coach.ui.UserListController; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryService; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; import org.olat.user.UserManager; import org.olat.user.propertyhandlers.UserPropertyHandler; import org.springframework.beans.factory.annotation.Autowired; /** * This is mainly a test with a large number of courses and groups. * It check if the rights courses are seen, but not details of the * statistics. * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ public class CoachingLargeTest extends OlatTestCase { private static boolean isInitialized = false; private static final Random rnd = new Random(); private static int NUM_OF_COURSES = 5; private static int NUM_OF_STUDENTS = 15; private static Identity author; private static Identity coach10, coach11, coach12, coach13; private static Identity coach20, coach21, coach22, coach23, coach24, coach25, coach26; private static Identity aStudent; private static RepositoryEntry course10; private static Map<Long,List<Long>> coachToCourseMap = new ConcurrentHashMap<Long,List<Long>>(); private static Map<Identity,List<RepositoryEntry>> studentToCourseMap = new ConcurrentHashMap<Identity,List<RepositoryEntry>>(); private static Map<Long,List<Long>> coachToGroupCourseMap = new ConcurrentHashMap<Long,List<Long>>(); private static List<UserPropertyHandler> userPropertyHandlers; @Autowired private DB dbInstance; @Autowired private UserManager userManager; @Autowired private CoachingService coachingService; @Autowired private RepositoryService repositoryService; @Autowired private BusinessGroupService businessGroupService; @Autowired private BusinessGroupRelationDAO businessGroupRelationDao; @Before public void setUp() throws Exception { if(isInitialized) return; userPropertyHandlers = userManager.getUserPropertyHandlersFor(UserListController.usageIdentifyer, false); //author author = JunitTestHelper.createAndPersistIdentityAsAuthor("author_" + UUID.randomUUID()); //r1 set of coach coach10 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-10"); coach11 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-11"); coach12 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-12"); coach13 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-13"); //r2 set of coach coach20 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-20"); coach21 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-21"); coach22 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-22"); coach23 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-23"); coach24 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-24"); coach25 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-25"); coach26 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-26"); List<Identity> students = new ArrayList<Identity>(); //r1 set of student for(int i=0; i<NUM_OF_STUDENTS; i++) { Identity student = JunitTestHelper.createAndPersistIdentityAsRndUser("student-" + i); students.add(student); } int qCount = 0; //create courses with members for(int i=0; i<NUM_OF_COURSES; i++) { URL courseWithForumsUrl = CoachingLargeTest.class.getResource("CoachingCourse.zip"); File courseWithForums = new File(courseWithForumsUrl.toURI()); String softKey = UUID.randomUUID().toString(); RepositoryEntry re = CourseFactory.deployCourseFromZIP(courseWithForums, softKey, 3); if(i == 0) { course10 = re; } int r1 = (i % 4); int r2 = (i % 7); switch(r1) { case 0: addCoachToCourse(coach10, re); break; case 1: addCoachToCourse(coach11, re); break; case 2: addCoachToCourse(coach12, re); break; case 3: addCoachToCourse(coach13, re); break; } switch(r2) { case 0: addCoachToCourse(coach20, re); break; case 1: addCoachToCourse(coach21, re); break; case 2: addCoachToCourse(coach22, re); break; case 3: addCoachToCourse(coach23, re); break; case 4: addCoachToCourse(coach24, re); break; case 5: addCoachToCourse(coach25, re); break; case 6: addCoachToCourse(coach26, re); break; } assertNotNull(re); List<Identity> newStudents = reservoirSample(students, NUM_OF_STUDENTS / 2); for(Identity newStudent:newStudents) { if(aStudent == null) { aStudent = newStudent; } addStudentToCourse(newStudent, re); if(qCount++ % 20 == 0) { dbInstance.intermediateCommit(); } } dbInstance.intermediateCommit(); } //create courses with members for(int i=0; i<NUM_OF_COURSES; i++) { URL courseWithForumsUrl = CoachingLargeTest.class.getResource("CoachingCourse.zip"); File courseWithForums = new File(courseWithForumsUrl.toURI()); String softKey = UUID.randomUUID().toString(); RepositoryEntry re = CourseFactory.deployCourseFromZIP(courseWithForums, softKey, 3); // create groups without waiting list BusinessGroup g1 = businessGroupService.createBusinessGroup(author, "coach-g1", null, new Integer(0), new Integer(10), false, false, re); BusinessGroup g2 = businessGroupService.createBusinessGroup(author, "coach-g2", null, new Integer(0), new Integer(10), false, false, re); //permission to see owners and participants businessGroupService.updateDisplayMembers(g1, false, false, false, false, false, false, false); businessGroupService.updateDisplayMembers(g2, true, true, false, false, false, false, false); // coach addCoachToGroupCourse(coach10, g1, re); addCoachToGroupCourse(coach11, g1, re); addCoachToGroupCourse(coach12, g2, re); //students List<Identity> newStudents = reservoirSample(students, NUM_OF_STUDENTS / 2); for(Iterator<Identity> it=newStudents.iterator(); it.hasNext(); ) { Identity newStudent = it.next(); addStudentToGroupCourse(newStudent, g1, re); it.remove(); if(qCount++ % 20 == 0) { dbInstance.intermediateCommit(); } if(rnd.nextDouble() > 0.8d) { break; } } // members g2 for(Iterator<Identity> it=newStudents.iterator(); it.hasNext(); ) { addStudentToGroupCourse(it.next(), g2, re); if(qCount++ % 20 == 0) { dbInstance.intermediateCommit(); } } dbInstance.intermediateCommit(); } isInitialized = true; } private void addCoachToCourse(Identity coach, RepositoryEntry re) { Long coachKey = coach.getKey(); repositoryService.addRole(coach, re, GroupRoles.coach.name()); if(!coachToCourseMap.containsKey(coachKey)) { coachToCourseMap.put(coachKey, new ArrayList<Long>()); } coachToCourseMap.get(coachKey).add(re.getKey()); } private void addCoachToGroupCourse(Identity coach, BusinessGroup group, RepositoryEntry re) { Long coachKey = coach.getKey(); businessGroupRelationDao.addRole(coach, group, GroupRoles.coach.name()); if(!coachToCourseMap.containsKey(coachKey)) { coachToCourseMap.put(coachKey, new ArrayList<Long>()); } coachToCourseMap.get(coachKey).add(re.getKey()); //GROUPS if(!coachToGroupCourseMap.containsKey(coachKey)) { coachToGroupCourseMap.put(coachKey, new ArrayList<Long>()); } coachToGroupCourseMap.get(coachKey).add(group.getKey()); } private void addStudentToCourse(Identity student, RepositoryEntry re) { repositoryService.addRole(student, re, GroupRoles.participant.name()); if(!studentToCourseMap.containsKey(student)) { studentToCourseMap.put(student, new ArrayList<RepositoryEntry>()); } studentToCourseMap.get(student).add(re); } private void addStudentToGroupCourse(Identity student, BusinessGroup group, RepositoryEntry re) { businessGroupRelationDao.addRole(student, group, GroupRoles.participant.name()); if(!studentToCourseMap.containsKey(student)) { studentToCourseMap.put(student, new ArrayList<RepositoryEntry>()); } studentToCourseMap.get(student).add(re); } public List<Identity> reservoirSample(Iterable<Identity> items, int m) { List<Identity> res = new ArrayList<Identity>(m); int count = 0; for(Identity item : items){ count++; if (count <= m) res.add(item); else{ int r = rnd.nextInt(count); if (r < m) res.set(r, item); } } return res; } @Test public void getStudentsStatistics() { List<StudentStatEntry> statEntries = coachingService.getStudentsStatistics(coach10, userPropertyHandlers); Assert.assertNotNull(statEntries); } @Test public void getCoursesStatistics() { List<CourseStatEntry> courseStatEntries = coachingService.getCoursesStatistics(coach10); Assert.assertNotNull(courseStatEntries); List<Long> coachedCourses = coachToCourseMap.get(coach10.getKey()); Assert.assertNotNull(coachedCourses); Assert.assertEquals(coachedCourses.size(), courseStatEntries.size()); List<Long> courseStatsKeys = new ArrayList<>(); for(CourseStatEntry statEntry:courseStatEntries) { courseStatsKeys.add(statEntry.getRepoKey()); } Assert.assertTrue(courseStatsKeys.containsAll(coachedCourses)); Assert.assertTrue(coachedCourses.containsAll(courseStatsKeys)); } @Test public void getGroupsStatistics() { List<GroupStatEntry> groupStatEntries = coachingService.getGroupsStatistics(coach10); Assert.assertNotNull(groupStatEntries); List<Long> coachedGroups = coachToGroupCourseMap.get(coach10.getKey()); Assert.assertNotNull(coachedGroups); Assert.assertEquals(coachedGroups.size(), groupStatEntries.size()); List<Long> groupStatsKeys = new ArrayList<>(); for(GroupStatEntry statEntry:groupStatEntries) { groupStatsKeys.add(statEntry.getGroupKey()); } Assert.assertTrue(groupStatsKeys.containsAll(coachedGroups)); Assert.assertTrue(coachedGroups.containsAll(groupStatsKeys)); } @Test public void getCourse() { List<Long> coachedCourses = coachToCourseMap.get(coach10.getKey()); Assert.assertNotNull(coachedCourses); List<EfficiencyStatementEntry> statEntries = coachingService.getCourse(coach10, course10, userPropertyHandlers, Locale.ENGLISH); Assert.assertNotNull(statEntries); Assert.assertFalse(statEntries.isEmpty()); Assert.assertTrue(coachedCourses.contains(course10.getKey())); for(EfficiencyStatementEntry statEntry:statEntries) { Assert.assertNotNull(statEntry.getCourse()); Assert.assertEquals(course10.getKey(), statEntry.getCourse().getKey()); } } @Test public void getStudentsCourses() { List<RepositoryEntry> courses = coachingService.getStudentsCourses(coach10, aStudent); Assert.assertNotNull(courses); List<Long> myCourses = coachToCourseMap.get(coach10.getKey()); Assert.assertNotNull(myCourses); } @Test public void getUserCourses() { List<RepositoryEntry> courses = coachingService.getUserCourses(aStudent); Assert.assertNotNull(courses); Assert.assertEquals(studentToCourseMap.get(aStudent).size(), courses.size()); } @Test public void getUsersStatistics() { SearchCoachedIdentityParams params = new SearchCoachedIdentityParams(); params.setLogin(aStudent.getName()); List<StudentStatEntry> statEntries = coachingService.getUsersStatistics(params, userPropertyHandlers); Assert.assertNotNull(statEntries); Assert.assertEquals(1, statEntries.size()); StudentStatEntry statEntry = statEntries.get(0); Assert.assertEquals(aStudent.getKey(), statEntry.getIdentityKey()); Assert.assertEquals(studentToCourseMap.get(aStudent).size(), statEntry.getCountRepo()); } }