test_module_render.py 8.35 KB
Newer Older
1
from mock import MagicMock
2 3
import json

4
from django.http import Http404, HttpResponse
Brian Wilson committed
5
from django.core.urlresolvers import reverse
6
from django.conf import settings
7 8
from django.test import TestCase
from django.test.client import RequestFactory
9
from django.test.utils import override_settings
10 11

from xmodule.modulestore.exceptions import ItemNotFoundError
12
from xmodule.modulestore.django import modulestore
13
import courseware.module_render as render
14
from courseware.tests.tests import LoginEnrollmentTestCase
15
from courseware.model_data import ModelDataCache
16

17
from .factories import UserFactory
Jay Zoldak committed
18

Jay Zoldak committed
19

20 21 22 23
class Stub:
    def __init__(self):
        pass

Jay Zoldak committed
24

Deena Wang committed
25 26
def xml_store_config(data_dir):
    return {
Jay Zoldak committed
27 28 29 30 31 32
        'default': {
            'ENGINE': 'xmodule.modulestore.xml.XMLModuleStore',
            'OPTIONS': {
                'data_dir': data_dir,
                'default_class': 'xmodule.hidden_module.HiddenDescriptor',
            }
Deena Wang committed
33 34 35 36 37 38
        }
    }

TEST_DATA_DIR = settings.COMMON_TEST_DATA_ROOT
TEST_DATA_XML_MODULESTORE = xml_store_config(TEST_DATA_DIR)

Jay Zoldak committed
39

Deena Wang committed
40
@override_settings(MODULESTORE=TEST_DATA_XML_MODULESTORE)
41
class ModuleRenderTestCase(LoginEnrollmentTestCase):
42
    def setUp(self):
Deena Wang committed
43 44 45
        self.location = ['i4x', 'edX', 'toy', 'chapter', 'Overview']
        self.course_id = 'edX/toy/2012_Fall'
        self.toy_course = modulestore().get_course(self.course_id)
46 47

    def test_get_module(self):
Jay Zoldak committed
48 49
        self.assertIsNone(render.get_module('dummyuser', None,
                                            'invalid location', None, None))
50 51 52 53 54 55

    def test_modx_dispatch(self):
        self.assertRaises(Http404, render.modx_dispatch, 'dummy', 'dummy',
                          'invalid Location', 'dummy')
        mock_request = MagicMock()
        mock_request.FILES.keys.return_value = ['file_id']
Jay Zoldak committed
56
        mock_request.FILES.getlist.return_value = ['file'] * (settings.MAX_FILEUPLOADS_PER_INPUT + 1)
57 58 59
        self.assertEquals(render.modx_dispatch(mock_request, 'dummy', self.location, 'dummy').content,
                          json.dumps({'success': 'Submission aborted! Maximum %d files may be submitted at once' %
                                      settings.MAX_FILEUPLOADS_PER_INPUT}))
60 61 62 63 64 65 66 67 68
        mock_request_2 = MagicMock()
        mock_request_2.FILES.keys.return_value = ['file_id']
        inputfile = Stub()
        inputfile.size = 1 + settings.STUDENT_FILEUPLOAD_MAX_SIZE
        inputfile.name = 'name'
        filelist = [inputfile]
        mock_request_2.FILES.getlist.return_value = filelist
        self.assertEquals(render.modx_dispatch(mock_request_2, 'dummy', self.location,
                                               'dummy').content,
Jay Zoldak committed
69
                          json.dumps({'success': 'Submission aborted! Your file "%s" is too large (max size: %d MB)' %
70
                                      (inputfile.name, settings.STUDENT_FILEUPLOAD_MAX_SIZE / (1000 ** 2))}))
71
        mock_request_3 = MagicMock()
72
        mock_request_3.POST.copy.return_value = {'position': 1}
Deena Wang committed
73 74
        mock_request_3.FILES = False
        mock_request_3.user = UserFactory()
75 76 77
        inputfile_2 = Stub()
        inputfile_2.size = 1
        inputfile_2.name = 'name'
Deena Wang committed
78
        self.assertIsInstance(render.modx_dispatch(mock_request_3, 'goto_position',
79
                                                   self.location, self.course_id), HttpResponse)
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
        self.assertRaises(
            Http404,
            render.modx_dispatch,
            mock_request_3,
            'goto_position',
            self.location,
            'bad_course_id'
        )
        self.assertRaises(
            Http404,
            render.modx_dispatch,
            mock_request_3,
            'goto_position',
            ['i4x', 'edX', 'toy', 'chapter', 'bad_location'],
            self.course_id
        )
        self.assertRaises(
            Http404,
            render.modx_dispatch,
            mock_request_3,
            'bad_dispatch',
            self.location,
            self.course_id
        )
Jay Zoldak committed
104

105 106 107 108 109 110 111 112
    def test_get_score_bucket(self):
        self.assertEquals(render.get_score_bucket(0, 10), 'incorrect')
        self.assertEquals(render.get_score_bucket(1, 10), 'partial')
        self.assertEquals(render.get_score_bucket(10, 10), 'correct')
        # get_score_bucket calls error cases 'incorrect'
        self.assertEquals(render.get_score_bucket(11, 10), 'incorrect')
        self.assertEquals(render.get_score_bucket(-1, 10), 'incorrect')

113 114 115 116 117 118 119 120 121 122 123 124
    def test_anonymous_modx_dispatch(self):
        dispatch_url = reverse(
            'modx_dispatch',
            args=[
                'edX/toy/2012_Fall',
                'i4x://edX/toy/videosequence/Toy_Videos',
                'goto_position'
            ]
        )
        response = self.client.post(dispatch_url, {'position': 2})
        self.assertEquals(403, response.status_code)

Jay Zoldak committed
125

Jay Zoldak committed
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
@override_settings(MODULESTORE=TEST_DATA_XML_MODULESTORE)
class TestTOC(TestCase):
    """Check the Table of Contents for a course"""
    def setUp(self):

        # Toy courses should be loaded
        self.course_name = 'edX/toy/2012_Fall'
        self.toy_course = modulestore().get_course(self.course_name)
        self.portal_user = UserFactory()

    def test_toc_toy_from_chapter(self):
        chapter = 'Overview'
        chapter_url = '%s/%s/%s' % ('/courses', self.course_name, chapter)
        factory = RequestFactory()
        request = factory.get(chapter_url)
141 142
        model_data_cache = ModelDataCache.cache_for_descriptor_descendents(
            self.toy_course.id, self.portal_user, self.toy_course, depth=2)
Jay Zoldak committed
143

Jay Zoldak committed
144
        expected = ([{'active': True, 'sections':
145
                      [{'url_name': 'Toy_Videos', 'display_name': u'Toy Videos', 'graded': True,
146
                        'format': u'Lecture Sequence', 'due': None, 'active': False},
147
                       {'url_name': 'Welcome', 'display_name': u'Welcome', 'graded': True,
148
                        'format': '', 'due': None, 'active': False},
149
                       {'url_name': 'video_123456789012', 'display_name': 'video 123456789012', 'graded': True,
150
                        'format': '', 'due': None, 'active': False},
151
                       {'url_name': 'video_4f66f493ac8f', 'display_name': 'video 4f66f493ac8f', 'graded': True,
152
                        'format': '', 'due': None, 'active': False}],
153 154 155
                      'url_name': 'Overview', 'display_name': u'Overview'},
                     {'active': False, 'sections':
                      [{'url_name': 'toyvideo', 'display_name': 'toyvideo', 'graded': True,
156
                        'format': '', 'due': None, 'active': False}],
157
                      'url_name': 'secret:magic', 'display_name': 'secret:magic'}])
Jay Zoldak committed
158

159
        actual = render.toc_for_course(self.portal_user, request, self.toy_course, chapter, None, model_data_cache)
Jay Zoldak committed
160 161 162 163 164 165 166 167
        self.assertEqual(expected, actual)

    def test_toc_toy_from_section(self):
        chapter = 'Overview'
        chapter_url = '%s/%s/%s' % ('/courses', self.course_name, chapter)
        section = 'Welcome'
        factory = RequestFactory()
        request = factory.get(chapter_url)
168 169
        model_data_cache = ModelDataCache.cache_for_descriptor_descendents(
            self.toy_course.id, self.portal_user, self.toy_course, depth=2)
Jay Zoldak committed
170

Jay Zoldak committed
171
        expected = ([{'active': True, 'sections':
172
                      [{'url_name': 'Toy_Videos', 'display_name': u'Toy Videos', 'graded': True,
173
                        'format': u'Lecture Sequence', 'due': None, 'active': False},
174
                       {'url_name': 'Welcome', 'display_name': u'Welcome', 'graded': True,
175
                        'format': '', 'due': None, 'active': True},
176
                       {'url_name': 'video_123456789012', 'display_name': 'video 123456789012', 'graded': True,
177
                        'format': '', 'due': None, 'active': False},
178
                       {'url_name': 'video_4f66f493ac8f', 'display_name': 'video 4f66f493ac8f', 'graded': True,
179
                        'format': '', 'due': None, 'active': False}],
180 181 182
                      'url_name': 'Overview', 'display_name': u'Overview'},
                     {'active': False, 'sections':
                      [{'url_name': 'toyvideo', 'display_name': 'toyvideo', 'graded': True,
183
                        'format': '', 'due': None, 'active': False}],
184
                      'url_name': 'secret:magic', 'display_name': 'secret:magic'}])
Jay Zoldak committed
185

186
        actual = render.toc_for_course(self.portal_user, request, self.toy_course, chapter, section, model_data_cache)
187
        self.assertEqual(expected, actual)