test_ccx_modulestore.py 5.26 KB
Newer Older
cewing committed
1 2 3 4
"""
Test the CCXModulestoreWrapper
"""
from collections import deque
5
from ccx_keys.locator import CCXLocator
cewing committed
6
import datetime
7
from itertools import izip_longest, chain
cewing committed
8
import pytz
9
from student.tests.factories import AdminFactory
cewing committed
10 11
from xmodule.modulestore.tests.django_utils import (
    ModuleStoreTestCase,
12 13
    TEST_DATA_SPLIT_MODULESTORE
)
cewing committed
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory

from ..models import CustomCourseForEdX


class TestCCXModulestoreWrapper(ModuleStoreTestCase):
    """tests for a modulestore wrapped by CCXModulestoreWrapper
    """
    MODULESTORE = TEST_DATA_SPLIT_MODULESTORE

    def setUp(self):
        """
        Set up tests
        """
        super(TestCCXModulestoreWrapper, self).setUp()
29
        self.course = course = CourseFactory.create()
cewing committed
30 31 32 33 34 35 36 37 38

        # Create instructor account
        coach = AdminFactory.create()

        # Create a course outline
        self.mooc_start = start = datetime.datetime(
            2010, 5, 12, 2, 42, tzinfo=pytz.UTC)
        self.mooc_due = due = datetime.datetime(
            2010, 7, 7, 0, 0, tzinfo=pytz.UTC)
39 40 41 42
        self.chapters = chapters = [
            ItemFactory.create(start=start, parent=course) for _ in xrange(2)
        ]
        self.sequentials = sequentials = [
43 44
            ItemFactory.create(parent=c) for _ in xrange(2) for c in chapters
        ]
45
        self.verticals = verticals = [
46 47 48 49
            ItemFactory.create(
                due=due, parent=s, graded=True, format='Homework'
            ) for _ in xrange(2) for s in sequentials
        ]
50
        self.blocks = [
51 52
            ItemFactory.create(parent=v) for _ in xrange(2) for v in verticals
        ]
cewing committed
53 54 55 56 57 58 59 60

        self.ccx = ccx = CustomCourseForEdX(
            course_id=course.id,
            display_name='Test CCX',
            coach=coach
        )
        ccx.save()

61
        self.ccx_locator = CCXLocator.from_course_locator(course.id, ccx.id)  # pylint: disable=no-member
cewing committed
62 63

    def get_all_children_bf(self, block):
64
        """traverse the children of block in a breadth-first order"""
cewing committed
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
        queue = deque([block])
        while queue:
            item = queue.popleft()
            yield item
            queue.extend(item.get_children())

    def get_course(self, key):
        """get a course given a key"""
        with self.store.bulk_operations(key):
            course = self.store.get_course(key)
        return course

    def test_get_course(self):
        """retrieving a course with a ccx key works"""
        expected = self.get_course(self.ccx_locator.to_course_locator())
        actual = self.get_course(self.ccx_locator)
        self.assertEqual(
            expected.location.course_key,
            actual.location.course_key.to_course_locator())
        self.assertEqual(expected.display_name, actual.display_name)

    def test_get_children(self):
        """the children of retrieved courses should be the same with course and ccx keys
        """
        course_key = self.ccx_locator.to_course_locator()
        course = self.get_course(course_key)
        ccx = self.get_course(self.ccx_locator)
92
        test_fodder = izip_longest(
cewing committed
93
            self.get_all_children_bf(course), self.get_all_children_bf(ccx)
94 95
        )
        for expected, actual in test_fodder:
cewing committed
96 97 98 99 100 101 102 103
            if expected is None:
                self.fail('course children exhausted before ccx children')
            if actual is None:
                self.fail('ccx children exhausted before course children')
            self.assertEqual(expected.display_name, actual.display_name)
            self.assertEqual(expected.location.course_key, course_key)
            self.assertEqual(actual.location.course_key, self.ccx_locator)

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
    def test_has_item(self):
        """can verify that a location exists, using ccx block usage key"""
        for item in chain(self.chapters, self.sequentials, self.verticals, self.blocks):
            block_key = self.ccx_locator.make_usage_key(
                item.location.block_type, item.location.block_id
            )
            self.assertTrue(self.store.has_item(block_key))

    def test_get_item(self):
        """can retrieve an item by a location key, using a ccx block usage key

        the retrieved item should be the same as the the one read without ccx
        info
        """
        for expected in chain(self.chapters, self.sequentials, self.verticals, self.blocks):
            block_key = self.ccx_locator.make_usage_key(
                expected.location.block_type, expected.location.block_id
            )
            actual = self.store.get_item(block_key)
            self.assertEqual(expected.display_name, actual.display_name)
            self.assertEqual(expected.location, actual.location.to_block_locator())

    def test_publication_api(self):
        """verify that we can correctly discern a published item by ccx key"""
        for expected in self.blocks:
            block_key = self.ccx_locator.make_usage_key(
                expected.location.block_type, expected.location.block_id
            )
            self.assertTrue(self.store.has_published_version(expected))
            self.store.unpublish(block_key, self.user.id)
            self.assertFalse(self.store.has_published_version(expected))
            self.store.publish(block_key, self.user.id)
            self.assertTrue(self.store.has_published_version(expected))