tests.py 7.34 KB
Newer Older
1
# pylint: disable=missing-docstring
2
from django.core.cache import cache
3 4 5
from django.test.utils import override_settings
from lang_pref import LANGUAGE_KEY
from opaque_keys.edx.locations import SlashSeparatedCourseKey
6 7

from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_TOY_MODULESTORE
8
from student.models import anonymous_id_for_user
9
from student.models import UserProfile
10 11
from student.roles import CourseStaffRole, CourseInstructorRole
from student.tests.factories import UserFactory, UserProfileFactory
12
from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
13
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
14 15 16 17 18

# Will also run default tests for IDTokens and UserInfo
from oauth2_provider.tests import IDTokenTestCase, UserInfoTestCase


muhammad-ammar committed
19
class BaseTestMixin(ModuleStoreTestCase):
20 21
    profile = None

22 23
    MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
    def setUp(self):
        super(BaseTestMixin, self).setUp()

        self.course_key = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
        self.course_id = unicode(self.course_key)

        self.user_factory = UserFactory
        self.set_user(self.make_user())

    def set_user(self, user):
        super(BaseTestMixin, self).set_user(user)
        self.profile = UserProfileFactory(user=self.user)


class IDTokenTest(BaseTestMixin, IDTokenTestCase):
39 40 41 42 43 44
    def setUp(self):
        super(IDTokenTest, self).setUp()

        # CourseAccessHandler uses the application cache.
        cache.clear()

45
    def test_sub_claim(self):
46
        scopes, claims = self.get_id_token_values('openid')
47 48 49 50 51 52 53
        self.assertIn('openid', scopes)

        sub = claims['sub']

        expected_sub = anonymous_id_for_user(self.user, None)
        self.assertEqual(sub, expected_sub)

54
    def test_user_name_claim(self):
55
        _scopes, claims = self.get_id_token_values('openid profile')
56 57 58 59 60 61 62
        claim_name = claims['name']

        user_profile = UserProfile.objects.get(user=self.user)
        user_name = user_profile.name

        self.assertEqual(claim_name, user_name)

63
    @override_settings(LANGUAGE_CODE='en')
64
    def test_user_without_locale_claim(self):
65
        scopes, claims = self.get_id_token_values('openid profile')
66
        self.assertIn('profile', scopes)
67
        self.assertEqual(claims['locale'], 'en')
68

69
    def test_user_with_locale_claim(self):
70
        language = 'en'
71
        set_user_preference(self.user, LANGUAGE_KEY, language)
72
        scopes, claims = self.get_id_token_values('openid profile')
73 74 75 76 77 78 79

        self.assertIn('profile', scopes)

        locale = claims['locale']
        self.assertEqual(language, locale)

    def test_no_special_course_access(self):
80
        scopes, claims = self.get_id_token_values('openid course_instructor course_staff')
81 82 83 84 85 86 87 88 89
        self.assertNotIn('course_staff', scopes)
        self.assertNotIn('staff_courses', claims)

        self.assertNotIn('course_instructor', scopes)
        self.assertNotIn('instructor_courses', claims)

    def test_course_staff_courses(self):
        CourseStaffRole(self.course_key).add_users(self.user)

90
        scopes, claims = self.get_id_token_values('openid course_staff')
91 92 93 94 95 96 97

        self.assertIn('course_staff', scopes)
        self.assertNotIn('staff_courses', claims)  # should not return courses in id_token

    def test_course_instructor_courses(self):
        CourseInstructorRole(self.course_key).add_users(self.user)

98
        scopes, claims = self.get_id_token_values('openid course_instructor')
99 100

        self.assertIn('course_instructor', scopes)
101
        self.assertNotIn('instructor_courses', claims)  # should not return courses in id_token
102

103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
    def test_course_staff_courses_with_claims(self):
        CourseStaffRole(self.course_key).add_users(self.user)

        course_id = unicode(self.course_key)
        nonexistent_course_id = 'some/other/course'

        claims = {
            'staff_courses': {
                'values': [course_id, nonexistent_course_id],
                'essential': True,
            }
        }

        scopes, claims = self.get_id_token_values(scope='openid course_staff', claims=claims)

        self.assertIn('course_staff', scopes)
        self.assertIn('staff_courses', claims)
        self.assertEqual(len(claims['staff_courses']), 1)
        self.assertIn(course_id, claims['staff_courses'])
        self.assertNotIn(nonexistent_course_id, claims['staff_courses'])

124 125 126 127 128 129 130 131 132 133
    def test_permissions_scope(self):
        scopes, claims = self.get_id_token_values('openid profile permissions')
        self.assertIn('permissions', scopes)
        self.assertFalse(claims['administrator'])

        self.user.is_staff = True
        self.user.save()
        _scopes, claims = self.get_id_token_values('openid profile permissions')
        self.assertTrue(claims['administrator'])

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197

class UserInfoTest(BaseTestMixin, UserInfoTestCase):
    def token_for_scope(self, scope):
        full_scope = 'openid %s' % scope
        self.set_access_token_scope(full_scope)

        token = self.access_token.token  # pylint: disable=no-member
        return full_scope, token

    def get_with_scope(self, scope):
        scope, token = self.token_for_scope(scope)
        result, claims = self.get_userinfo(token, scope)
        self.assertEqual(result.status_code, 200)

        return claims

    def get_with_claim_value(self, scope, claim, values):
        _full_scope, token = self.token_for_scope(scope)

        result, claims = self.get_userinfo(
            token,
            claims={claim: {'values': values}}
        )

        self.assertEqual(result.status_code, 200)
        return claims

    def test_request_staff_courses_using_scope(self):
        CourseStaffRole(self.course_key).add_users(self.user)
        claims = self.get_with_scope('course_staff')

        courses = claims['staff_courses']
        self.assertIn(self.course_id, courses)
        self.assertEqual(len(courses), 1)

    def test_request_instructor_courses_using_scope(self):
        CourseInstructorRole(self.course_key).add_users(self.user)
        claims = self.get_with_scope('course_instructor')

        courses = claims['instructor_courses']
        self.assertIn(self.course_id, courses)
        self.assertEqual(len(courses), 1)

    def test_request_staff_courses_with_claims(self):
        CourseStaffRole(self.course_key).add_users(self.user)

        values = [self.course_id, 'some_invalid_course']
        claims = self.get_with_claim_value('course_staff', 'staff_courses', values)
        self.assertEqual(len(claims), 2)

        courses = claims['staff_courses']
        self.assertIn(self.course_id, courses)
        self.assertEqual(len(courses), 1)

    def test_request_instructor_courses_with_claims(self):
        CourseInstructorRole(self.course_key).add_users(self.user)

        values = ['edX/toy/TT_2012_Fall', self.course_id, 'invalid_course_id']
        claims = self.get_with_claim_value('course_instructor', 'instructor_courses', values)
        self.assertEqual(len(claims), 2)

        courses = claims['instructor_courses']
        self.assertIn(self.course_id, courses)
        self.assertEqual(len(courses), 1)
198 199 200 201 202 203 204 205 206 207

    def test_permissions_scope(self):
        claims = self.get_with_scope('permissions')
        self.assertIn('administrator', claims)
        self.assertFalse(claims['administrator'])

        self.user.is_staff = True
        self.user.save()
        claims = self.get_with_scope('permissions')
        self.assertTrue(claims['administrator'])