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 copy import deepcopy
7

8
from django.contrib.auth.models import User
9 10
from django.core.urlresolvers import reverse
from nose.plugins.attrib import attr
11

12
from common.test.utils import XssTestMixin
13
from courseware.tests.helpers import LoginEnrollmentTestCase
14 15 16
from survey.models import SurveyAnswer, SurveyForm
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
17 18


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

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

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
    @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()

44 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
    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)

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

73 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
        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)

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

133 134 135 136 137 138 139 140 141 142 143 144
    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)

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
    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)

191 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
    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)})
        )
228 229 230 231 232 233 234 235 236

    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
237
        self.assert_no_xss(response, '<script>alert("XSS")</script>')