""" Tests for contentstore/views/user.py. """ import json from .utils import CourseTestCase from django.contrib.auth.models import User, Group from django.core.urlresolvers import reverse from auth.authz import get_course_groupname_for_role from student.models import CourseEnrollment class UsersTestCase(CourseTestCase): def setUp(self): super(UsersTestCase, self).setUp() self.ext_user = User.objects.create_user( "joe", "joe@comedycentral.com", "haha") self.ext_user.is_active = True self.ext_user.is_staff = False self.ext_user.save() self.inactive_user = User.objects.create_user( "carl", "carl@comedycentral.com", "haha") self.inactive_user.is_active = False self.inactive_user.is_staff = False self.inactive_user.save() self.index_url = reverse("manage_users", kwargs={ "org": self.course.location.org, "course": self.course.location.course, "name": self.course.location.name, }) self.detail_url = reverse("course_team_user", kwargs={ "org": self.course.location.org, "course": self.course.location.course, "name": self.course.location.name, "email": self.ext_user.email, }) self.inactive_detail_url = reverse("course_team_user", kwargs={ "org": self.course.location.org, "course": self.course.location.course, "name": self.course.location.name, "email": self.inactive_user.email, }) self.invalid_detail_url = reverse("course_team_user", kwargs={ "org": self.course.location.org, "course": self.course.location.course, "name": self.course.location.name, "email": "nonexistent@user.com", }) self.staff_groupname = get_course_groupname_for_role(self.course.location, "staff") self.inst_groupname = get_course_groupname_for_role(self.course.location, "instructor") def test_index(self): resp = self.client.get(self.index_url) # ext_user is not currently a member of the course team, and so should # not show up on the page. self.assertNotContains(resp, self.ext_user.email) def test_index_member(self): group, _ = Group.objects.get_or_create(name=self.staff_groupname) self.ext_user.groups.add(group) self.ext_user.save() resp = self.client.get(self.index_url) self.assertContains(resp, self.ext_user.email) def test_detail(self): resp = self.client.get(self.detail_url) self.assertEqual(resp.status_code, 200) result = json.loads(resp.content) self.assertEqual(result["role"], None) self.assertTrue(result["active"]) def test_detail_inactive(self): resp = self.client.get(self.inactive_detail_url) self.assertEqual(resp.status_code, 200) result = json.loads(resp.content) self.assertFalse(result["active"]) def test_detail_invalid(self): resp = self.client.get(self.invalid_detail_url) self.assertEqual(resp.status_code, 404) result = json.loads(resp.content) self.assertIn("error", result) def test_detail_post(self): resp = self.client.post( self.detail_url, data={"role": None}, ) self.assertEqual(resp.status_code, 204) # reload user from DB ext_user = User.objects.get(email=self.ext_user.email) groups = [g.name for g in ext_user.groups.all()] # no content: should not be in any roles self.assertNotIn(self.staff_groupname, groups) self.assertNotIn(self.inst_groupname, groups) self.assert_not_enrolled() def test_detail_post_staff(self): resp = self.client.post( self.detail_url, data=json.dumps({"role": "staff"}), content_type="application/json", HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 204) # reload user from DB ext_user = User.objects.get(email=self.ext_user.email) groups = [g.name for g in ext_user.groups.all()] self.assertIn(self.staff_groupname, groups) self.assertNotIn(self.inst_groupname, groups) self.assert_enrolled() def test_detail_post_staff_other_inst(self): inst_group, _ = Group.objects.get_or_create(name=self.inst_groupname) self.user.groups.add(inst_group) self.user.save() resp = self.client.post( self.detail_url, data=json.dumps({"role": "staff"}), content_type="application/json", HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 204) # reload user from DB ext_user = User.objects.get(email=self.ext_user.email) groups = [g.name for g in ext_user.groups.all()] self.assertIn(self.staff_groupname, groups) self.assertNotIn(self.inst_groupname, groups) self.assert_enrolled() # check that other user is unchanged user = User.objects.get(email=self.user.email) groups = [g.name for g in user.groups.all()] self.assertNotIn(self.staff_groupname, groups) self.assertIn(self.inst_groupname, groups) def test_detail_post_instructor(self): resp = self.client.post( self.detail_url, data=json.dumps({"role": "instructor"}), content_type="application/json", HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 204) # reload user from DB ext_user = User.objects.get(email=self.ext_user.email) groups = [g.name for g in ext_user.groups.all()] self.assertNotIn(self.staff_groupname, groups) self.assertIn(self.inst_groupname, groups) self.assert_enrolled() def test_detail_post_missing_role(self): resp = self.client.post( self.detail_url, data=json.dumps({"toys": "fun"}), content_type="application/json", HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 400) result = json.loads(resp.content) self.assertIn("error", result) self.assert_not_enrolled() def test_detail_post_bad_json(self): resp = self.client.post( self.detail_url, data="{foo}", content_type="application/json", HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 400) result = json.loads(resp.content) self.assertIn("error", result) self.assert_not_enrolled() def test_detail_post_no_json(self): resp = self.client.post( self.detail_url, data={"role": "staff"}, HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 204) # reload user from DB ext_user = User.objects.get(email=self.ext_user.email) groups = [g.name for g in ext_user.groups.all()] self.assertIn(self.staff_groupname, groups) self.assertNotIn(self.inst_groupname, groups) self.assert_enrolled() def test_detail_delete_staff(self): group, _ = Group.objects.get_or_create(name=self.staff_groupname) self.ext_user.groups.add(group) self.ext_user.save() resp = self.client.delete( self.detail_url, HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 204) # reload user from DB ext_user = User.objects.get(email=self.ext_user.email) groups = [g.name for g in ext_user.groups.all()] self.assertNotIn(self.staff_groupname, groups) def test_detail_delete_instructor(self): group, _ = Group.objects.get_or_create(name=self.inst_groupname) self.user.groups.add(group) self.ext_user.groups.add(group) self.user.save() self.ext_user.save() resp = self.client.delete( self.detail_url, HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 204) # reload user from DB ext_user = User.objects.get(email=self.ext_user.email) groups = [g.name for g in ext_user.groups.all()] self.assertNotIn(self.inst_groupname, groups) def test_delete_last_instructor(self): group, _ = Group.objects.get_or_create(name=self.inst_groupname) self.ext_user.groups.add(group) self.ext_user.save() resp = self.client.delete( self.detail_url, HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 400) result = json.loads(resp.content) self.assertIn("error", result) # reload user from DB ext_user = User.objects.get(email=self.ext_user.email) groups = [g.name for g in ext_user.groups.all()] self.assertIn(self.inst_groupname, groups) def test_post_last_instructor(self): group, _ = Group.objects.get_or_create(name=self.inst_groupname) self.ext_user.groups.add(group) self.ext_user.save() resp = self.client.post( self.detail_url, data={"role": "staff"}, HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 400) result = json.loads(resp.content) self.assertIn("error", result) # reload user from DB ext_user = User.objects.get(email=self.ext_user.email) groups = [g.name for g in ext_user.groups.all()] self.assertIn(self.inst_groupname, groups) def test_permission_denied_self(self): group, _ = Group.objects.get_or_create(name=self.staff_groupname) self.user.groups.add(group) self.user.is_staff = False self.user.save() self_url = reverse("course_team_user", kwargs={ "org": self.course.location.org, "course": self.course.location.course, "name": self.course.location.name, "email": self.user.email, }) resp = self.client.post( self_url, data={"role": "instructor"}, HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 400) result = json.loads(resp.content) self.assertIn("error", result) def test_permission_denied_other(self): group, _ = Group.objects.get_or_create(name=self.staff_groupname) self.user.groups.add(group) self.user.is_staff = False self.user.save() resp = self.client.post( self.detail_url, data={"role": "instructor"}, HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 400) result = json.loads(resp.content) self.assertIn("error", result) def test_staff_can_delete_self(self): group, _ = Group.objects.get_or_create(name=self.staff_groupname) self.user.groups.add(group) self.user.is_staff = False self.user.save() self_url = reverse("course_team_user", kwargs={ "org": self.course.location.org, "course": self.course.location.course, "name": self.course.location.name, "email": self.user.email, }) resp = self.client.delete(self_url) self.assertEqual(resp.status_code, 204) # reload user from DB user = User.objects.get(email=self.user.email) groups = [g.name for g in user.groups.all()] self.assertNotIn(self.staff_groupname, groups) def test_staff_cannot_delete_other(self): group, _ = Group.objects.get_or_create(name=self.staff_groupname) self.user.groups.add(group) self.user.is_staff = False self.user.save() self.ext_user.groups.add(group) self.ext_user.save() resp = self.client.delete(self.detail_url) self.assertEqual(resp.status_code, 400) result = json.loads(resp.content) self.assertIn("error", result) # reload user from DB ext_user = User.objects.get(email=self.ext_user.email) groups = [g.name for g in ext_user.groups.all()] self.assertIn(self.staff_groupname, groups) def test_user_not_initially_enrolled(self): # Verify that ext_user is not enrolled in the new course before being added as a staff member. self.assert_not_enrolled() def test_remove_staff_does_not_unenroll(self): # Add user with staff permissions. self.client.post( self.detail_url, data=json.dumps({"role": "staff"}), content_type="application/json", HTTP_ACCEPT="application/json", ) self.assert_enrolled() # Remove user from staff on course. Will not un-enroll them from the course. resp = self.client.delete( self.detail_url, HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 204) self.assert_enrolled() def test_staff_to_instructor_still_enrolled(self): # Add user with staff permission. self.client.post( self.detail_url, data=json.dumps({"role": "staff"}), content_type="application/json", HTTP_ACCEPT="application/json", ) self.assert_enrolled() # Now add with instructor permission. Verify still enrolled. resp = self.client.post( self.detail_url, data=json.dumps({"role": "instructor"}), content_type="application/json", HTTP_ACCEPT="application/json", ) self.assertEqual(resp.status_code, 204) self.assert_enrolled() def assert_not_enrolled(self): """ Asserts that self.ext_user is not enrolled in self.course. """ self.assertFalse( CourseEnrollment.is_enrolled(self.ext_user, self.course.location.course_id), 'Did not expect ext_user to be enrolled in course' ) def assert_enrolled(self): """ Asserts that self.ext_user is enrolled in self.course. """ self.assertTrue( CourseEnrollment.is_enrolled(self.ext_user, self.course.location.course_id), 'User ext_user should have been enrolled in the course' )