def test_user_moved_to_another_team(self): """ We should be able to move a user from one team to another """ # Create a learner, enroll in course audit_learner = UserFactory.create(username='******') CourseEnrollmentFactory.create(user=audit_learner, course_id=self.course.id, mode='audit') # Make two teams in the same teamset, enroll the user in one team_1 = CourseTeamFactory(course_id=self.course.id, name='test_team_1', topic_id='teamset_1') team_2 = CourseTeamFactory(course_id=self.course.id, name='test_team_2', topic_id='teamset_1') team_1.add_user(audit_learner) csv_row = _csv_dict_row(audit_learner, '', 'audit', teamset_1=team_2.name) csv_import(self.course, [csv_row]) assert not CourseTeamMembership.is_user_on_team(audit_learner, team_1) assert CourseTeamMembership.is_user_on_team(audit_learner, team_2) self.assert_learner_removed_emitted(team_1.team_id, audit_learner.id) self.assert_learner_added_emitted(team_2.team_id, audit_learner.id)
def test_switch_memberships(self): # Given a bunch of students enrolled in a course users = [] for i in range(5): user = UserFactory.create(username='******'.format(id=i)) CourseEnrollmentFactory.create(user=user, course_id=self.course.id, mode='audit') users.append(user) # When a team is already at/near capaciy for i in range(3): user = users[i] row = {'user': user, 'teamset_1': 'team_1', 'mode': 'audit'} self.import_manager.add_user_to_team(row) # ... and I try to switch membership (add/remove) csv_data = self._csv_reader_from_array([ ['user', 'mode', 'teamset_1'], ['learner_4', 'audit', 'team_1'], ['learner_0', 'audit', 'team_2'], ]) result = self.import_manager.set_team_memberships(csv_data) # Then membership size is calculated correctly, import finishes w/out error self.assertTrue(result) # ... and the users are assigned to the correct teams team_1 = CourseTeam.objects.get(course_id=self.course.id, topic_id='teamset_1', name='team_1') self.assertTrue(CourseTeamMembership.is_user_on_team(users[4], team_1)) self.assert_learner_added_emitted(team_1.team_id, users[4].id) team_2 = CourseTeam.objects.get(course_id=self.course.id, topic_id='teamset_1', name='team_2') self.assertTrue(CourseTeamMembership.is_user_on_team(users[0], team_2)) self.assert_learner_added_emitted(team_2.team_id, users[0].id)
def test_team_removals_are_scoped_correctly(self): """ Team memberships should not search across topics in different courses """ # Given a learner enrolled in similarly named teamsets across 2 courses audit_learner = UserFactory.create(username='******') CourseEnrollmentFactory.create(user=audit_learner, course_id=self.course.id, mode='audit') course_1_team = CourseTeamFactory(course_id=self.course.id, name='cross_course_test', topic_id='teamset_1') course_1_team.add_user(audit_learner) CourseEnrollmentFactory.create(user=audit_learner, course_id=self.second_course.id, mode='audit') course_2_team = CourseTeamFactory( course_id=self.second_course.id, name='cross_course_test', topic_id='teamset_1' ) course_2_team.add_user(audit_learner) self.assertTrue(CourseTeamMembership.is_user_on_team(audit_learner, course_1_team)) # When I try to remove them from the team row = { 'mode': 'audit', 'teamset_1': None, 'user': audit_learner } self.import_manager.remove_user_from_team_for_reassignment(row) # They are successfully removed from the team self.assertFalse(CourseTeamMembership.is_user_on_team(audit_learner, course_1_team)) self.assert_learner_removed_emitted(course_1_team.team_id, audit_learner.id)
def test_get_memberships(self, username, course_ids, team_ids, expected_count): self.assertEqual( CourseTeamMembership.get_memberships(username=username, course_ids=course_ids, team_ids=team_ids).count(), expected_count)
def test_add_incompatible_mode_to_existing_protected_team_fails(self): # Given an existing protected team protected_team = CourseTeamFactory( course_id=self.course.id, name='protected_team', topic_id='teamset_1', organization_protected=True, ) masters_learner = self._create_and_enroll_test_user('masters_learner', mode='masters') protected_team.add_user(masters_learner) # When I attempt to add a student of an incompatible enrollment mode verified_learner = self._create_and_enroll_test_user( 'verified_learner', mode='verified') csv_data = self._csv_reader_from_array( [['username', 'mode', 'teamset_1'], [verified_learner.username, 'verified', 'protected_team']]) result = self.import_manager.set_team_memberships(csv_data) # The import fails with "mixed users" error and learner not added to team assert not result self.assert_no_events_were_emitted() assert self.import_manager.validation_errors[0] ==\ 'Team protected_team cannot have Master’s track users mixed with users in other tracks.' assert not CourseTeamMembership.is_user_on_team( verified_learner, protected_team)
def load_course_team_memberships(self): """ Caches existing team memberships by (user_id, teamset_id) """ for membership in CourseTeamMembership.get_memberships(course_ids=[self.course.id]): user_id = membership.user_id teamset_id = membership.team.topic_id self.existing_course_team_memberships[(user_id, teamset_id)] = membership.team
def test_remove_from_team(self): # Given a user already in a course and on a team user = UserFactory.create(username='******') mode = 'audit' CourseEnrollmentFactory.create(user=user, course_id=self.course.id, mode=mode) team = CourseTeamFactory(course_id=self.course.id, name='team_1', topic_id='teamset_1') team.add_user(user) self.assertTrue(CourseTeamMembership.is_user_on_team(user, team)) # When I try to remove them from the team csv_data = self._csv_reader_from_array([ ['user', 'mode', 'teamset_1'], [user.username, mode, ''], ]) result = self.import_manager.set_team_memberships(csv_data) # Then they are removed from the team and the correct events are issued self.assertFalse(CourseTeamMembership.is_user_on_team(user, team)) self.assert_learner_removed_emitted(team.team_id, user.id)
def user_on_team_or_team_is_public(user, team): """ The only users who should be able to see private_managed teams or recieve any information about them at all from the API are: - Course staff - Users who are enrolled in a team in a private_managed teamset * They should only be able to see their own team, no other teams. """ if CourseTeamMembership.is_user_on_team(user, team): return True course_module = modulestore().get_course(team.course_id) teamset = course_module.teams_configuration.teamsets_by_id[team.topic_id] return teamset.teamset_type != TeamsetType.private_managed
def teamset_is_public_or_user_is_on_team_in_teamset(user, course_module, teamset_id): """ The only users who should be able to see private_managed teamsets or recieve any information about them at all from the API are: - Course staff - Users who are enrolled in a team in a private_managed teamset course_module is passed in because almost universally where we'll be calling this, we will already need to have looked up the course from modulestore to make sure that the topic we're interested in exists in the course. """ teamset = course_module.teams_configuration.teamsets_by_id[teamset_id] if teamset.teamset_type != TeamsetType.private_managed: return True return CourseTeamMembership.user_in_team_for_course(user, course_module.id, topic_id=teamset_id)
def test_exceed_max_size(self): # Given a bunch of students enrolled in a course users = [] for i in range(5): user = UserFactory.create(username='******'.format(id=i)) CourseEnrollmentFactory.create(user=user, course_id=self.course.id, mode='audit') users.append(user) # When a team is already near capaciy team = CourseTeam.objects.create( name='team_1', course_id=self.course.id, topic_id='teamset_1', description='Team 1!', ) for i in range(2): user = users[i] team.add_user(user) # ... and I try to add members in excess of capacity csv_data = self._csv_reader_from_array([ ['user', 'mode', 'teamset_1'], ['max_size_0', 'audit', ''], ['max_size_2', 'audit', 'team_1'], ['max_size_3', 'audit', 'team_1'], ['max_size_4', 'audit', 'team_1'], ]) result = self.import_manager.set_team_memberships(csv_data) # Then the import fails with no events emitted and a "team is full" error self.assertFalse(result) self.assert_no_events_were_emitted() self.assertEqual( self.import_manager.validation_errors[0], 'New membership for team team_1 would exceed max size of 3.') # Confirm that memberships were not altered for i in range(2): self.assertTrue(CourseTeamMembership.is_user_on_team(user, team))
def test_create_new_team_from_import(self): # Given a user in a course user = UserFactory.create(username='******') mode = 'audit' CourseEnrollmentFactory.create(user=user, course_id=self.course.id, mode=mode) # When I add them to a team that does not exist self.assertEquals(CourseTeam.objects.all().count(), 0) csv_data = self._csv_reader_from_array([ ['user', 'mode', 'teamset_1'], [user.username, mode, 'new_exciting_team'], ]) result = self.import_manager.set_team_memberships(csv_data) # Then a new team is created self.assertEqual(CourseTeam.objects.all().count(), 1) # ... and the user is assigned to the team new_team = CourseTeam.objects.get(topic_id='teamset_1', name='new_exciting_team') self.assertTrue(CourseTeamMembership.is_user_on_team(user, new_team)) self.assert_learner_added_emitted(new_team.team_id, user.id)
def test_user_in_team_for_course_teamset(self, username, course_id, teamset_id, expected_value): user = getattr(self, username) self.assertEqual( CourseTeamMembership.user_in_team_for_course( user, course_id, teamset_id), expected_value)
def assert_user_not_on_team(self, user): self.assertFalse(CourseTeamMembership.is_user_on_team(user, self.team))
def test_get_memberships(self, username, course_ids, team_id, expected_count): self.assertEqual( CourseTeamMembership.get_memberships(username=username, course_ids=course_ids, team_id=team_id).count(), expected_count )
def test_user_in_team_for_course(self, username, course_id, expected_value): user = getattr(self, username) self.assertEqual( CourseTeamMembership.user_in_team_for_course(user, course_id), expected_value )
def assert_user_not_on_team(self, user): assert not CourseTeamMembership.is_user_on_team(user, self.team)