def test_with_cohorted_content(self, content_creator_method_name): self.login_and_enroll() self._setup_course_partitions(scheme_id="cohort", is_cohorted=True) cohorts = [] for group_id in [0, 1]: getattr(self, content_creator_method_name)(group_id) cohorts.append(CohortFactory(course_id=self.course.id, name=u"Cohort " + unicode(group_id))) link = CourseUserGroupPartitionGroup( course_user_group=cohorts[group_id], partition_id=self.partition_id, group_id=group_id ) link.save() for cohort_index in range(len(cohorts)): # add user to this cohort add_user_to_cohort(cohorts[cohort_index], self.user.username) # should only see video for this cohort video_outline = self.api_response().data self.assertEqual(len(video_outline), 1) self.assertEquals(u"video for group " + unicode(cohort_index), video_outline[0]["summary"]["name"]) # remove user from this cohort remove_user_from_cohort(cohorts[cohort_index], self.user.username) # un-cohorted user should see no videos video_outline = self.api_response().data self.assertEqual(len(video_outline), 0) # staff user sees all videos self.user.is_staff = True self.user.save() video_outline = self.api_response().data self.assertEqual(len(video_outline), 2)
def delete(self, request, *args, **kwargs): obj = self.get_object() # University ID object obj.can_edit = True obj.save() cohort = get_cohort(obj.user, obj.course_key, assign=False) try: remove_user_from_cohort(cohort, obj.user.username) except ValueError: # If user not already present in this cohort. pass return super(UniversityIDDeleteView, self).delete(request, *args, **kwargs)
def test_workgroups_users_post_with_cohort_backfill(self, store): self._create_course(store) """ This test asserts a case where a workgroup was created before the existence of a cohorted discussion """ data = { 'name': self.test_workgroup_name, 'project': self.test_project.id } response = self.do_post(self.test_workgroups_uri, data) self.assertEqual(response.status_code, 201) test_uri = '{}{}/'.format(self.test_workgroups_uri, str(response.data['id'])) users_uri = '{}users/'.format(test_uri) data = {"id": self.test_user.id} response = self.do_post(users_uri, data) self.assertEqual(response.status_code, 201) response = self.do_get(test_uri) self.assertEqual(response.status_code, 200) self.assertEqual(response.data['users'][0]['id'], self.test_user.id) cohort_name = Workgroup.cohort_name_for_workgroup( self.test_project.id, response.data['id'], self.test_workgroup_name ) # now let's remove existing cohort users cohort = get_cohort_by_name(self.test_course.id, cohort_name) self.assertTrue(is_user_in_cohort(cohort, self.test_user.id)) remove_user_from_cohort(cohort, self.test_user.username) self.assertFalse(is_user_in_cohort(cohort, self.test_user.id)) # delete cohort delete_empty_cohort(self.test_course.id, cohort_name) self.assertEqual(0, len(get_course_cohort_names(self.test_course.id))) # add a 2nd user and make sure a discussion cohort was created and users were backfilled test_uri = '{}{}/'.format(self.test_workgroups_uri, str(response.data['id'])) users_uri = '{}users/'.format(test_uri) data = {"id": self.test_user2.id} response = self.do_post(users_uri, data) self.assertEqual(response.status_code, 201) # now inspect cohort and assert that things are as we anticipate (i.e. both users are in there) cohort = get_cohort_by_name(self.test_course.id, cohort_name) self.assertIsNotNone(cohort) self.assertTrue(is_user_in_cohort(cohort, self.test_user.id)) self.assertTrue(is_user_in_cohort(cohort, self.test_user2.id))
def test_workgroups_users_post_with_cohort_backfill(self, store): self._create_course(store) """ This test asserts a case where a workgroup was created before the existence of a cohorted discussion """ data = { 'name': self.test_workgroup_name, 'project': self.test_project.id } response = self.do_post(self.test_workgroups_uri, data) self.assertEqual(response.status_code, 201) test_uri = '{}{}/'.format(self.test_workgroups_uri, str(response.data['id'])) users_uri = '{}users/'.format(test_uri) data = {"id": self.test_user.id} response = self.do_post(users_uri, data) self.assertEqual(response.status_code, 201) response = self.do_get(test_uri) self.assertEqual(response.status_code, 200) self.assertEqual(response.data['users'][0]['id'], self.test_user.id) cohort_name = Workgroup.cohort_name_for_workgroup( self.test_project.id, response.data['id'], self.test_workgroup_name) # now let's remove existing cohort users cohort = get_cohort_by_name(self.test_course.id, cohort_name) self.assertTrue(is_user_in_cohort(cohort, self.test_user.id)) remove_user_from_cohort(cohort, self.test_user.username) self.assertFalse(is_user_in_cohort(cohort, self.test_user.id)) # delete cohort delete_empty_cohort(self.test_course.id, cohort_name) self.assertEqual(0, len(get_course_cohort_names(self.test_course.id))) # add a 2nd user and make sure a discussion cohort was created and users were backfilled test_uri = '{}{}/'.format(self.test_workgroups_uri, str(response.data['id'])) users_uri = '{}users/'.format(test_uri) data = {"id": self.test_user2.id} response = self.do_post(users_uri, data) self.assertEqual(response.status_code, 201) # now inspect cohort and assert that things are as we anticipate (i.e. both users are in there) cohort = get_cohort_by_name(self.test_course.id, cohort_name) self.assertIsNotNone(cohort) self.assertTrue(is_user_in_cohort(cohort, self.test_user.id)) self.assertTrue(is_user_in_cohort(cohort, self.test_user2.id))
def test_with_cohorted_content(self, content_creator_method_name, api_version): self.login_and_enroll() self._setup_course_partitions(scheme_id='cohort', is_cohorted=True) cohorts = [] for group_id in [0, 1]: getattr(self, content_creator_method_name)(group_id) cohorts.append( CohortFactory(course_id=self.course.id, name=u"Cohort " + unicode(group_id))) link = CourseUserGroupPartitionGroup( course_user_group=cohorts[group_id], partition_id=self.partition_id, group_id=group_id, ) link.save() for cohort_index in range(len(cohorts)): # add user to this cohort add_user_to_cohort(cohorts[cohort_index], self.user.username) # should only see video for this cohort video_outline = self.api_response(api_version=api_version).data self.assertEqual(len(video_outline), 1) self.assertEquals(u"video for group " + unicode(cohort_index), video_outline[0]["summary"]["name"]) # remove user from this cohort remove_user_from_cohort(cohorts[cohort_index], self.user.username) # un-cohorted user should see no videos video_outline = self.api_response(api_version=api_version).data self.assertEqual(len(video_outline), 0) # staff user sees all videos self.user.is_staff = True self.user.save() video_outline = self.api_response(api_version=api_version).data self.assertEqual(len(video_outline), 2)
def remove_from_cohort(self): cohort = self.get_cohort() remove_user_from_cohort(cohort, username_or_email=self.user.email)
def users(self, request, pk): """ Add a User to a Workgroup """ if request.method == "GET": users = User.objects.filter(workgroups=pk) response_data = [] if users: for user in users: serializer = UserSerializer(user) response_data.append(serializer.data) # pylint: disable=E1101 return Response(response_data, status=status.HTTP_200_OK) elif request.method == "POST": user_id = request.DATA.get("id") try: user = User.objects.get(id=user_id) except ObjectDoesNotExist: message = "User {} does not exist".format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) workgroup = self.get_object() # Ensure the user is not already assigned to a project for this course existing_projects = Project.objects.filter(course_id=workgroup.project.course_id).filter( workgroups__users__id=user.id ) if len(existing_projects): message = "User {} already assigned to a project for this course".format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) try: workgroup.add_user(user) except ValidationError as e: return Response({"detail": unicode(e)}, status.HTTP_400_BAD_REQUEST) workgroup.save() # add user to the workgroup cohort, create it if it doesn't exist (for cases where there is a legacy # workgroup) course_descriptor, course_key, course_content = _get_course( self.request, user, workgroup.project.course_id ) # pylint: disable=W0612 try: cohort = get_cohort_by_name(course_key, workgroup.cohort_name) add_user_to_cohort(cohort, user.username) except ObjectDoesNotExist: # This use case handles cases where a workgroup might have been created before # the notion of a cohorted discussion. So we need to backfill in the data assignment_type = request.DATA.get("assignment_type", CourseCohort.RANDOM) if assignment_type not in dict(CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys(): message = "Not a valid assignment type, '{}'".format(assignment_type) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) cohort = add_cohort(course_key, workgroup.cohort_name, assignment_type) for workgroup_user in workgroup.users.all(): add_user_to_cohort(cohort, workgroup_user.username) return Response({}, status=status.HTTP_201_CREATED) else: user_id = request.DATA.get("id") try: user = User.objects.get(id=user_id) except ObjectDoesNotExist: message = "User {} does not exist".format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) workgroup = self.get_object() course_descriptor, course_key, course_content = _get_course( self.request, user, workgroup.project.course_id ) # pylint: disable=W0612 cohort = get_cohort_by_name(course_key, workgroup.cohort_name) workgroup.remove_user(user) remove_user_from_cohort(cohort, user.username) return Response({}, status=status.HTTP_204_NO_CONTENT)
def handle(self, *args, **options): self.stdout.write('### Checking CourseUserGroup group types\n') error = False for course_group in CourseUserGroup.objects.all(): if course_group.group_type != CourseUserGroup.COHORT: if options['fix']: self.stdout.write( 'Fixed: CourseUserGroup with an invalid group_type found: {} (type: {})\n' .format(course_group.name, course_group.group_type)) course_group.group_type = CourseUserGroup.COHORT course_group.save() else: error = True self.stdout.write( 'CourseUserGroup with an invalid group_type found: {} (type: {})\n' .format(course_group.name, course_group.group_type)) if not error: self.stdout.write('Ok.\n') self.stdout.write('\n### Checking user cohorts\n') error = False users = User.objects.all() _courses = modulestore().get_courses() courses = [c for c in _courses if isinstance(c, CourseDescriptor)] # for each course, check if users are in atleast and only 1 cohort for course in courses: for user in users: if not CourseEnrollment.is_enrolled(user, course.id): continue try: CourseUserGroup.objects.get(course_id=course.id, users__id=user.id) except CourseUserGroup.DoesNotExist: if options['fix']: # create a "default_cohort" is it doesn't already exist try: default_cohort = get_cohort_by_name( course.id, CourseUserGroup.default_cohort_name) except CourseUserGroup.DoesNotExist: default_cohort = add_cohort( course.id, CourseUserGroup.default_cohort_name, CourseCohort.RANDOM) self.stdout.write( 'Default cohort "{}" created for course "{}"'. format(default_cohort.name, course.display_name)) add_user_to_cohort(default_cohort, user.username) self.stdout.write( 'Fixed: User "{}" is not in a cohort in course "{}". Added in "{}" cohort\n' .format(user.username, course.display_name, default_cohort.name)) else: error = True self.stdout.write( 'User "{}" is not in a cohort in course "{}".\n'. format(user.username, course.display_name)) except MultipleObjectsReturned: self.stdout.write( 'User "{}" is in multiple cohorts in course "{}".\n'. format(user.username, course.display_name)) if options['fix']: user_cohorts = CourseUserGroup.objects.filter( course_id=course.id, users__id=user.id).all() for cohort in user_cohorts[1:]: remove_user_from_cohort(cohort, user.username) self.stdout.write( "User '{}' has been removed from cohort '{}' in course '{}'.\n" .format(user.username, cohort.name, course.display_name)) self.stdout.write( "User '{}' is now only in cohort '{}' in course '{}'.\n" .format( # pylint: disable=undefined-loop-variable user.username, cohort.name, course.display_name)) else: error = True if not error: self.stdout.write('Ok.\n') self.stdout.write( '\nTo fix issues, run the script with the "--fix" option.\n')
def users(self, request, pk): """ Add a User to a Workgroup """ if request.method == 'GET': users = User.objects.filter(workgroups=pk) response_data = [] if users: for user in users: serializer = UserSerializer(user, context={'request': request}) response_data.append(serializer.data) # pylint: disable=E1101 return Response(response_data, status=status.HTTP_200_OK) elif request.method == 'POST': user_id = request.data.get('id') try: user = User.objects.get(id=user_id) except ObjectDoesNotExist: message = 'User {} does not exist'.format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) workgroup = self.get_object() # Ensure the user is not already assigned to a project for this course existing_projects = Project.objects.filter( course_id=workgroup.project.course_id).filter( workgroups__users__id=user.id) if len(existing_projects): message = 'User {} already assigned to a project for this course'.format( user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) try: workgroup.add_user(user) except ValidationError as e: return Response({"detail": unicode(e)}, status.HTTP_400_BAD_REQUEST) workgroup.save() # add user to the workgroup cohort, create it if it doesn't exist (for cases where there is a legacy # workgroup) course_key = get_course_key(workgroup.project.course_id) try: cohort = get_cohort_by_name(course_key, workgroup.cohort_name) add_user_to_cohort(cohort, user.username) except ObjectDoesNotExist: # This use case handles cases where a workgroup might have been created before # the notion of a cohorted discussion. So we need to backfill in the data assignment_type = request.data.get('assignment_type', CourseCohort.RANDOM) if assignment_type not in dict( CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys(): message = "Not a valid assignment type, '{}'".format( assignment_type) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) workgroup = self.get_object() cohort = add_cohort(course_key, workgroup.cohort_name, assignment_type) for workgroup_user in workgroup.users.all(): add_user_to_cohort(cohort, workgroup_user.username) return Response({}, status=status.HTTP_201_CREATED) else: user_id = request.data.get('id') try: user = User.objects.get(id=user_id) except ObjectDoesNotExist: message = 'User {} does not exist'.format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) workgroup = self.get_object() course_key = get_course_key(workgroup.project.course_id) cohort = get_cohort_by_name(course_key, workgroup.cohort_name) workgroup.remove_user(user) remove_user_from_cohort(cohort, user.username) return Response({}, status=status.HTTP_204_NO_CONTENT)
def handle(self, *args, **options): self.stdout.write('### Checking CourseUserGroup group types\n') error = False for course_group in CourseUserGroup.objects.all(): if course_group.group_type != CourseUserGroup.COHORT: if options['fix']: self.stdout.write( 'Fixed: CourseUserGroup with an invalid group_type found: {} (type: {})\n'.format( course_group.name, course_group.group_type) ) course_group.group_type = CourseUserGroup.COHORT course_group.save() else: error = True self.stdout.write( 'CourseUserGroup with an invalid group_type found: {} (type: {})\n'.format( course_group.name, course_group.group_type) ) if not error: self.stdout.write('Ok.\n') self.stdout.write('\n### Checking user cohorts\n') error = False users = User.objects.all() _courses = modulestore().get_courses() courses = [c for c in _courses if isinstance(c, CourseDescriptor)] # for each course, check if users are in atleast and only 1 cohort for course in courses: for user in users: if not CourseEnrollment.is_enrolled(user, course.id): continue try: CourseUserGroup.objects.get(course_id=course.id, users__id=user.id) except CourseUserGroup.DoesNotExist: if options['fix']: # create a "default_cohort" is it doesn't already exist try: default_cohort = get_cohort_by_name(course.id, CourseUserGroup.default_cohort_name) except CourseUserGroup.DoesNotExist: default_cohort = add_cohort( course.id, CourseUserGroup.default_cohort_name, CourseCohort.RANDOM ) self.stdout.write( 'Default cohort "{}" created for course "{}"'.format( default_cohort.name, course.display_name ) ) add_user_to_cohort(default_cohort, user.username) self.stdout.write( 'Fixed: User "{}" is not in a cohort in course "{}". Added in "{}" cohort\n'.format( user.username, course.display_name, default_cohort.name) ) else: error = True self.stdout.write( 'User "{}" is not in a cohort in course "{}".\n'.format( user.username, course.display_name) ) except MultipleObjectsReturned: self.stdout.write( 'User "{}" is in multiple cohorts in course "{}".\n'.format( user.username, course.display_name) ) if options['fix']: user_cohorts = CourseUserGroup.objects.filter(course_id=course.id, users__id=user.id).all() for cohort in user_cohorts[1:]: remove_user_from_cohort(cohort, user.username) self.stdout.write( "User '{}' has been removed from cohort '{}' in course '{}'.\n".format( user.username, cohort.name, course.display_name ) ) self.stdout.write( "User '{}' is now only in cohort '{}' in course '{}'.\n".format( # pylint: disable=undefined-loop-variable user.username, cohort.name, course.display_name ) ) else: error = True if not error: self.stdout.write('Ok.\n') self.stdout.write('\nTo fix issues, run the script with the "--fix" option.\n')