tests.py 9.25 KB
Newer Older
1
from django.core.urlresolvers import reverse
2
from mock import patch
3
from nose.plugins.attrib import attr
4

5
from courseware.tests.tests import LoginEnrollmentTestCase
6
from openedx.features.enterprise_support.tests.mixins.enterprise import EnterpriseTestConsentRequired
7
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
muhammad-ammar committed
8
from xmodule.modulestore.tests.factories import CourseFactory
9

10

11
@attr(shard=1)
12
class WikiRedirectTestCase(EnterpriseTestConsentRequired, LoginEnrollmentTestCase, ModuleStoreTestCase):
muhammad-ammar committed
13 14 15
    """
    Tests for wiki course redirection.
    """
Calen Pennington committed
16

muhammad-ammar committed
17
    def setUp(self):
18 19
        super(WikiRedirectTestCase, self).setUp()
        self.toy = CourseFactory.create(org='edX', course='toy', display_name='2012_Fall')
20 21 22 23 24

        # Create two accounts
        self.student = 'view@test.com'
        self.instructor = 'view2@test.com'
        self.password = 'foo'
25 26 27 28
        for username, email in [('u1', self.student), ('u2', self.instructor)]:
            self.create_account(username, email, self.password)
            self.activate_user(email)
            self.logout()
Calen Pennington committed
29

30
    @patch.dict("django.conf.settings.FEATURES", {'ALLOW_WIKI_ROOT_ACCESS': True})
31 32
    def test_wiki_redirect(self):
        """
33
        Test that requesting wiki URLs redirect properly to or out of classes.
Calen Pennington committed
34 35 36

        An enrolled in student going from /courses/edX/toy/2012_Fall/progress
        to /wiki/some/fake/wiki/page/ will redirect to
37
        /courses/edX/toy/2012_Fall/wiki/some/fake/wiki/page/
Calen Pennington committed
38

39
        An unenrolled student going to /courses/edX/toy/2012_Fall/wiki/some/fake/wiki/page/
40
        will be redirected to /wiki/some/fake/wiki/page/
Calen Pennington committed
41

42 43
        """
        self.login(self.student, self.password)
Calen Pennington committed
44

45
        self.enroll(self.toy)
Calen Pennington committed
46

47
        referer = reverse("progress", kwargs={'course_id': self.toy.id.to_deprecated_string()})
48
        destination = reverse("wiki:get", kwargs={'path': 'some/fake/wiki/page/'})
Calen Pennington committed
49

50
        redirected_to = referer.replace("progress", "wiki/some/fake/wiki/page/")
Calen Pennington committed
51 52 53 54 55 56

        resp = self.client.get(destination, HTTP_REFERER=referer)
        self.assertEqual(resp.status_code, 302)

        self.assertEqual(resp['Location'], 'http://testserver' + redirected_to)

57 58 59
        # Now we test that the student will be redirected away from that page if the course doesn't exist
        # We do this in the same test because we want to make sure the redirected_to is constructed correctly
        # This is a location like /courses/*/wiki/* , but with an invalid course ID
Calen Pennington committed
60 61 62
        bad_course_wiki_page = redirected_to.replace(self.toy.location.course, "bad_course")

        resp = self.client.get(bad_course_wiki_page, HTTP_REFERER=referer)
63
        self.assertEqual(resp.status_code, 302)
Calen Pennington committed
64 65
        self.assertEqual(resp['Location'], 'http://testserver' + destination)

66 67 68 69 70 71 72 73 74 75
    @patch.dict("django.conf.settings.FEATURES", {'ALLOW_WIKI_ROOT_ACCESS': False})
    def test_wiki_no_root_access(self):
        """
        Test to verify that normally Wiki's cannot be browsed from the /wiki/xxxx/yyy/zz URLs

        """
        self.login(self.student, self.password)

        self.enroll(self.toy)

76
        referer = reverse("progress", kwargs={'course_id': self.toy.id.to_deprecated_string()})
77 78 79 80 81
        destination = reverse("wiki:get", kwargs={'path': 'some/fake/wiki/page/'})

        resp = self.client.get(destination, HTTP_REFERER=referer)
        self.assertEqual(resp.status_code, 403)

82 83 84 85 86
    def create_course_page(self, course):
        """
        Test that loading the course wiki page creates the wiki page.
        The user must be enrolled in the course to see the page.
        """
Calen Pennington committed
87

88
        course_wiki_home = reverse('course_wiki', kwargs={'course_id': course.id.to_deprecated_string()})
89
        referer = reverse("progress", kwargs={'course_id': course.id.to_deprecated_string()})
Calen Pennington committed
90

91
        resp = self.client.get(course_wiki_home, follow=True, HTTP_REFERER=referer)
Calen Pennington committed
92

93
        course_wiki_page = referer.replace('progress', 'wiki/' + course.wiki_slug + "/")
Calen Pennington committed
94

95
        ending_location = resp.redirect_chain[-1][0]
Calen Pennington committed
96 97

        self.assertEquals(ending_location, 'http://testserver' + course_wiki_page)
98
        self.assertEquals(resp.status_code, 200)
Calen Pennington committed
99

100
        self.has_course_navigator(resp)
Calen Pennington committed
101

102 103 104 105
    def has_course_navigator(self, resp):
        """
        Ensure that the response has the course navigator.
        """
106 107
        self.assertContains(resp, "Home")
        self.assertContains(resp, "Course")
Calen Pennington committed
108

109
    @patch.dict("django.conf.settings.FEATURES", {'ALLOW_WIKI_ROOT_ACCESS': True})
110 111 112 113
    def test_course_navigator(self):
        """"
        Test that going from a course page to a wiki page contains the course navigator.
        """
Calen Pennington committed
114

115 116 117 118
        self.login(self.student, self.password)
        self.enroll(self.toy)
        self.create_course_page(self.toy)

Calen Pennington committed
119
        course_wiki_page = reverse('wiki:get', kwargs={'path': self.toy.wiki_slug + '/'})
120
        referer = reverse("courseware", kwargs={'course_id': self.toy.id.to_deprecated_string()})
Calen Pennington committed
121 122 123 124

        resp = self.client.get(course_wiki_page, follow=True, HTTP_REFERER=referer)

        self.has_course_navigator(resp)
125 126 127

    @patch.dict("django.conf.settings.FEATURES", {'ALLOW_WIKI_ROOT_ACCESS': True})
    def test_wiki_not_accessible_when_not_enrolled(self):
128 129 130
        """
        Test that going from a course page to a wiki page when not enrolled
        redirects a user to the course about page
131 132 133 134 135
        """

        self.login(self.instructor, self.password)
        self.enroll(self.toy)
        self.create_course_page(self.toy)
136
        self.logout()
137 138 139

        self.login(self.student, self.password)
        course_wiki_page = reverse('wiki:get', kwargs={'path': self.toy.wiki_slug + '/'})
140
        referer = reverse("courseware", kwargs={'course_id': self.toy.id.to_deprecated_string()})
141

142 143 144 145 146
        # When not enrolled, we should get a 302
        resp = self.client.get(course_wiki_page, follow=False, HTTP_REFERER=referer)
        self.assertEqual(resp.status_code, 302)

        # and end up at the course about page
147
        resp = self.client.get(course_wiki_page, follow=True, HTTP_REFERER=referer)
148 149
        target_url, __ = resp.redirect_chain[-1]
        self.assertTrue(
150
            target_url.endswith(reverse('about_course', args=[self.toy.id.to_deprecated_string()]))
151 152 153 154 155 156 157 158 159 160 161 162 163 164
        )

    @patch.dict("django.conf.settings.FEATURES", {'ALLOW_WIKI_ROOT_ACCESS': True})
    def test_redirect_when_not_logged_in(self):
        """
        Test that attempting to reach a course wiki page when not logged in
        redirects the user to the login page
        """
        self.logout()
        course_wiki_page = reverse('wiki:get', kwargs={'path': self.toy.wiki_slug + '/'})

        # When not logged in, we should get a 302
        resp = self.client.get(course_wiki_page, follow=False)
        self.assertEqual(resp.status_code, 302)
165

166 167 168
        # and end up at the login page
        resp = self.client.get(course_wiki_page, follow=True)
        target_url, __ = resp.redirect_chain[-1]
169
        self.assertIn(reverse('signin_user'), target_url)
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 198

    @patch.dict("django.conf.settings.FEATURES", {'ALLOW_WIKI_ROOT_ACCESS': True})
    def test_create_wiki_with_long_course_id(self):
        """
        Tests that the wiki is successfully created for courses that have
        very long course ids.
        """
        # Combined course key length is currently capped at 65 characters (see MAX_SUM_KEY_LENGTH
        # in /common/static/common/js/components/utils/view_utils.js).
        # The below key components combined are exactly 65 characters long.
        org = 'a-very-long-org-name'
        course = 'a-very-long-course-name'
        display_name = 'very-long-display-name'
        # This is how wiki_slug is generated in cms/djangoapps/contentstore/views/course.py.
        wiki_slug = "{0}.{1}.{2}".format(org, course, display_name)

        self.assertEqual(len(org + course + display_name), 65)  # sanity check

        course = CourseFactory.create(org=org, course=course, display_name=display_name, wiki_slug=wiki_slug)

        self.login(self.student, self.password)
        self.enroll(course)
        self.create_course_page(course)

        course_wiki_page = reverse('wiki:get', kwargs={'path': course.wiki_slug + '/'})
        referer = reverse("courseware", kwargs={'course_id': course.id.to_deprecated_string()})

        resp = self.client.get(course_wiki_page, follow=True, HTTP_REFERER=referer)
        self.assertEqual(resp.status_code, 200)
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219

    @patch.dict("django.conf.settings.FEATURES", {'ALLOW_WIKI_ROOT_ACCESS': True})
    def test_consent_required(self):
        """
        Test that enterprise data sharing consent is required when enabled for the various courseware views.
        """
        # Public wikis can be accessed by non-enrolled users, and so direct access is not gated by the consent page
        course = CourseFactory.create()
        course.allow_public_wiki_access = False
        course.save()

        # However, for private wikis, enrolled users must pass through the consent gate
        # (Unenrolled users are redirected to course/about)
        course_id = unicode(course.id)
        self.login(self.student, self.password)
        self.enroll(course)

        for (url, status_code) in (
                (reverse('course_wiki', kwargs={'course_id': course_id}), 302),
                ('/courses/{}/wiki/'.format(course_id), 200),
        ):
220
            self.verify_consent_required(self.client, url, status_code=status_code)