test_course_survey.py 7.61 KB
Newer Older
1 2 3 4 5
"""
Python tests for the Survey workflows
"""

from collections import OrderedDict
6
from nose.plugins.attrib import attr
7
from copy import deepcopy
8 9

from django.core.urlresolvers import reverse
10
from django.contrib.auth.models import User
11

12
from survey.models import SurveyForm, SurveyAnswer
13

14
from common.test.utils import XssTestMixin
15
from xmodule.modulestore.tests.factories import CourseFactory
Toby Lawrence committed
16
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
17 18 19
from courseware.tests.helpers import LoginEnrollmentTestCase


20
@attr(shard=1)
21
class SurveyViewsTests(LoginEnrollmentTestCase, SharedModuleStoreTestCase, XssTestMixin):
22 23 24 25 26 27
    """
    All tests for the views.py file
    """

    STUDENT_INFO = [('view@test.com', 'foo')]

28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
    @classmethod
    def setUpClass(cls):
        super(SurveyViewsTests, cls).setUpClass()
        cls.test_survey_name = 'TestSurvey'
        cls.course = CourseFactory.create(
            display_name='<script>alert("XSS")</script>',
            course_survey_required=True,
            course_survey_name=cls.test_survey_name
        )

        cls.course_with_bogus_survey = CourseFactory.create(
            course_survey_required=True,
            course_survey_name="DoesNotExist"
        )

        cls.course_without_survey = CourseFactory.create()

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
    def setUp(self):
        """
        Set up the test data used in the specific tests
        """
        super(SurveyViewsTests, self).setUp()

        self.test_form = '<input name="field1"></input>'
        self.survey = SurveyForm.create(self.test_survey_name, self.test_form)

        self.student_answers = OrderedDict({
            u'field1': u'value1',
            u'field2': u'value2',
        })

        # Create student accounts and activate them.
        for i in range(len(self.STUDENT_INFO)):
            email, password = self.STUDENT_INFO[i]
            username = 'u{0}'.format(i)
            self.create_account(username, email, password)
            self.activate_user(email)

        email, password = self.STUDENT_INFO[0]
        self.login(email, password)
        self.enroll(self.course, True)
        self.enroll(self.course_without_survey, True)
        self.enroll(self.course_with_bogus_survey, True)

72 73
        self.user = User.objects.get(email=email)

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
        self.view_url = reverse('view_survey', args=[self.test_survey_name])
        self.postback_url = reverse('submit_answers', args=[self.test_survey_name])

    def _assert_survey_redirect(self, course):
        """
        Helper method to assert that all known redirect points do redirect as expected
        """
        for view_name in ['courseware', 'info', 'progress']:
            resp = self.client.get(
                reverse(
                    view_name,
                    kwargs={'course_id': unicode(course.id)}
                )
            )
            self.assertRedirects(
                resp,
                reverse('course_survey', kwargs={'course_id': unicode(course.id)})
            )

    def _assert_no_redirect(self, course):
        """
        Helper method to asswer that all known conditionally redirect points do
        not redirect as expected
        """
        for view_name in ['courseware', 'info', 'progress']:
            resp = self.client.get(
                reverse(
                    view_name,
                    kwargs={'course_id': unicode(course.id)}
                )
            )
            self.assertEquals(resp.status_code, 200)

    def test_visiting_course_without_survey(self):
        """
        Verifies that going to the courseware which does not have a survey does
        not redirect to a survey
        """
        self._assert_no_redirect(self.course_without_survey)

    def test_visiting_course_with_survey_redirects(self):
        """
        Verifies that going to the courseware with an unanswered survey, redirects to the survey
        """
        self._assert_survey_redirect(self.course)

120 121 122 123 124 125 126 127 128 129 130 131 132 133
    def test_anonymous_user_visiting_course_with_survey(self):
        """
        Verifies that anonymous user going to the courseware info with an unanswered survey is not
        redirected to survery and info page renders without server error.
        """
        self.logout()
        resp = self.client.get(
            reverse(
                'info',
                kwargs={'course_id': unicode(self.course.id)}
            )
        )
        self.assertEquals(resp.status_code, 200)

134 135 136 137 138 139 140 141 142 143 144 145
    def test_visiting_course_with_existing_answers(self):
        """
        Verifies that going to the courseware with an answered survey, there is no redirect
        """
        resp = self.client.post(
            self.postback_url,
            self.student_answers
        )
        self.assertEquals(resp.status_code, 200)

        self._assert_no_redirect(self.course)

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
    def test_course_id_field(self):
        """
        Assert that the course_id will be in the form fields, if available
        """

        resp = self.client.get(
            reverse(
                'course_survey',
                kwargs={'course_id': unicode(self.course.id)}
            )
        )

        self.assertEqual(resp.status_code, 200)
        expected = '<input type="hidden" name="course_id" value="{course_id}" />'.format(
            course_id=unicode(self.course.id)
        )

        self.assertContains(resp, expected)

    def test_course_id_persists(self):
        """
        Assert that a posted back course_id is stored in the database
        """

        answers = deepcopy(self.student_answers)
        answers.update({
            'course_id': unicode(self.course.id)
        })

        resp = self.client.post(
            self.postback_url,
            answers
        )
        self.assertEquals(resp.status_code, 200)

        self._assert_no_redirect(self.course)

        # however we want to make sure we persist the course_id
        answer_objs = SurveyAnswer.objects.filter(
            user=self.user,
            form=self.survey
        )

        for answer_obj in answer_objs:
            self.assertEquals(answer_obj.course_key, self.course.id)

192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
    def test_visiting_course_with_bogus_survey(self):
        """
        Verifies that going to the courseware with a required, but non-existing survey, does not redirect
        """
        self._assert_no_redirect(self.course_with_bogus_survey)

    def test_visiting_survey_with_bogus_survey_name(self):
        """
        Verifies that going to the courseware with a required, but non-existing survey, does not redirect
        """

        resp = self.client.get(
            reverse(
                'course_survey',
                kwargs={'course_id': unicode(self.course_with_bogus_survey.id)}
            )
        )
        self.assertRedirects(
            resp,
            reverse('info', kwargs={'course_id': unicode(self.course_with_bogus_survey.id)})
        )

    def test_visiting_survey_with_no_course_survey(self):
        """
        Verifies that going to the courseware with a required, but non-existing survey, does not redirect
        """

        resp = self.client.get(
            reverse(
                'course_survey',
                kwargs={'course_id': unicode(self.course_without_survey.id)}
            )
        )
        self.assertRedirects(
            resp,
            reverse('info', kwargs={'course_id': unicode(self.course_without_survey.id)})
        )
229 230 231 232 233 234 235 236 237

    def test_survey_xss(self):
        """Test that course display names are correctly HTML-escaped."""
        response = self.client.get(
            reverse(
                'course_survey',
                kwargs={'course_id': unicode(self.course.id)}
            )
        )
Mushtaq Ali committed
238
        self.assert_no_xss(response, '<script>alert("XSS")</script>')