tests.py 6.13 KB
Newer Older
1 2 3
"""
Test for LMS courseware app.
"""
lapentab committed
4
import mock
5
from django.core.urlresolvers import reverse
6
from django.test.utils import override_settings
7

8 9
from textwrap import dedent

10
from xmodule.error_module import ErrorDescriptor
11 12 13
from xmodule.modulestore.django import modulestore
from xmodule.modulestore import Location
from xmodule.modulestore.xml_importer import import_from_xml
14
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
Victor Shnayder committed
15

16 17
from courseware.tests.helpers import LoginEnrollmentTestCase
from courseware.tests.modulestore_config import TEST_DATA_DIR, \
18
    TEST_DATA_MONGO_MODULESTORE, \
19 20
    TEST_DATA_DRAFT_MONGO_MODULESTORE, \
    TEST_DATA_MIXED_MODULESTORE
21 22 23 24 25 26 27 28


class ActivateLoginTest(LoginEnrollmentTestCase):
    """
    Test logging in and logging out.
    """
    def setUp(self):
        self.setup_user()
Victor Shnayder committed
29

30 31 32
    def test_activate_login(self):
        """
        Test login -- the setup function does all the work.
Victor Shnayder committed
33
        """
34 35 36
        pass

    def test_logout(self):
Victor Shnayder committed
37
        """
38
        Test logout -- setup function does login.
Victor Shnayder committed
39
        """
40 41 42 43 44 45 46
        self.logout()


class PageLoaderTestCase(LoginEnrollmentTestCase):
    """
    Base class that adds a function to load all pages in a modulestore.
    """
47

48
    def check_all_pages_load(self, course_id):
49
        """
50 51
        Assert that all pages in the course load correctly.
        `course_id` is the ID of the course to check.
52
        """
53 54 55 56 57

        store = modulestore()

        # Enroll in the course before trying to access pages
        course = store.get_course(course_id)
58 59 60 61 62
        self.enroll(course, True)

        # Search for items in the course
        # None is treated as a wildcard
        course_loc = course.location
63 64 65 66
        location_query = Location(
            course_loc.tag, course_loc.org,
            course_loc.course, None, None, None
        )
67

68
        items = store.get_items(
Will Daly committed
69 70 71
            location_query,
            course_id=course_id,
            depth=2
72
        )
73 74 75 76

        if len(items) < 1:
            self.fail('Could not retrieve any items from course')

77 78
        # Try to load each item in the course
        for descriptor in items:
79

80 81 82 83
            if descriptor.location.category == 'about':
                self._assert_loads('about_course',
                                   {'course_id': course_id},
                                   descriptor)
84

85 86 87 88
            elif descriptor.location.category == 'static_tab':
                kwargs = {'course_id': course_id,
                          'tab_slug': descriptor.location.name}
                self._assert_loads('static_tab', kwargs, descriptor)
89

90 91 92
            elif descriptor.location.category == 'course_info':
                self._assert_loads('info', {'course_id': course_id},
                                   descriptor)
93

94
            else:
95

96 97
                kwargs = {'course_id': course_id,
                          'location': descriptor.location.url()}
98

99 100 101
                self._assert_loads('jump_to', kwargs, descriptor,
                                   expect_redirect=True,
                                   check_content=True)
102 103 104 105 106 107 108 109 110

    def _assert_loads(self, django_url, kwargs, descriptor,
                      expect_redirect=False,
                      check_content=False):
        """
        Assert that the url loads correctly.
        If expect_redirect, then also check that we were redirected.
        If check_content, then check that we don't get
        an error message about unavailable modules.
111
        """
Victor Shnayder committed
112

113 114
        url = reverse(django_url, kwargs=kwargs)
        response = self.client.get(url, follow=True)
Will Daly committed
115

116 117 118
        if response.status_code != 200:
            self.fail('Status %d for page %s' %
                      (response.status_code, descriptor.location.url()))
Will Daly committed
119

120 121
        if expect_redirect:
            self.assertEqual(response.redirect_chain[0][1], 302)
Will Daly committed
122

123
        if check_content:
124 125
            self.assertNotContains(response, "this module is temporarily unavailable")
            self.assertNotIsInstance(descriptor, ErrorDescriptor)
126

127

128 129
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class TestXmlCoursesLoad(ModuleStoreTestCase, PageLoaderTestCase):
130 131 132
    """
    Check that all pages in test courses load properly from XML.
    """
133 134

    def setUp(self):
135
        super(TestXmlCoursesLoad, self).setUp()
136
        self.setup_user()
137

138
    def test_toy_course_loads(self):
139 140 141 142
        # Load one of the XML based courses
        # Our test mapping rules allow the MixedModuleStore
        # to load this course from XML, not Mongo.
        self.check_all_pages_load('edX/toy/2012_Fall')
143 144


145 146
# Importing XML courses isn't possible with MixedModuleStore,
# so we use a Mongo modulestore directly (as we would in Studio)
147
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
148
class TestMongoCoursesLoad(ModuleStoreTestCase, PageLoaderTestCase):
149 150 151
    """
    Check that all pages in test courses load properly from Mongo.
    """
152

153
    def setUp(self):
154
        super(TestMongoCoursesLoad, self).setUp()
155
        self.setup_user()
156

157 158 159
        # Import the toy course into a Mongo-backed modulestore
        self.store = modulestore()
        import_from_xml(self.store, TEST_DATA_DIR, ['toy'])
160

lapentab committed
161 162
    @mock.patch('xmodule.course_module.requests.get')
    def test_toy_textbooks_loads(self, mock_get):
lapentab committed
163 164 165 166 167 168
        mock_get.return_value.text = dedent("""
            <?xml version="1.0"?><table_of_contents>
            <entry page="5" page_label="ii" name="Table of Contents"/>
            </table_of_contents>
        """).strip()

169 170
        location = Location(['i4x', 'edX', 'toy', 'course', '2012_Fall', None])
        course = self.store.get_item(location)
171
        self.assertGreater(len(course.textbooks), 0)
172

lapentab committed
173

174
@override_settings(MODULESTORE=TEST_DATA_DRAFT_MONGO_MODULESTORE)
Will Daly committed
175
class TestDraftModuleStore(ModuleStoreTestCase):
176 177
    def test_get_items_with_course_items(self):
        store = modulestore()
178

179 180 181
        # fix was to allow get_items() to take the course_id parameter
        store.get_items(Location(None, None, 'vertical', None, None),
                        course_id='abc', depth=0)
182

183 184 185
        # test success is just getting through the above statement.
        # The bug was that 'course_id' argument was
        # not allowed to be passed in (i.e. was throwing exception)