Beispiel #1
0
 def load_root_xblock(self, student_id="student_1"):
     """
     Load (in Python) the XBlock at the root of the current scenario.
     """
     dom_node = self.browser.find_element_by_css_selector('.workbench .preview > div.xblock-v1:first-child')
     usage_id = dom_node.get_attribute('data-usage')
     runtime = WorkbenchRuntime(student_id)
     return runtime.get_block(usage_id)
def test_correct_answer_submission():
	runtime = WorkbenchRuntime()
	# WorkbenchRuntime has an id_generator, but most runtimes won't
	# (because the generator will be contextual), so we
	# pass it explicitly to parse_xml_string.
	brewing101_usage_id = runtime.parse_xml_string("""
		<brewing101/>
 	""", runtime.id_generator)

	brewing101 = runtime.get_block(brewing101_usage_id)
	json_data = json.dumps(172)
	resp = runtime.handle(brewing101, 'submit_answer', make_request(json_data))
	resp_data = json.loads(text_of_response(resp))
	print(resp_data)
	assert_equals(resp_data['answerCorrect'], True)
Beispiel #3
0
 def setUp(self):
     """
     Create the runtime.
     """
     super(XBlockHandlerTestCaseMixin, self).setUp()
     self.runtime = WorkbenchRuntime()
     mock_publish = mock.MagicMock(side_effect=self.runtime.publish)
     self.runtime.publish = mock_publish
Beispiel #4
0
class TestChildIsInstance(unittest.TestCase):
    """
    Test child_isinstance helper method, in the workbench runtime.
    """

    @XBlock.register_temp_plugin(GoldenRetrieverXBlock, "gr")
    @XBlock.register_temp_plugin(CatXBlock, "cat")
    @XBlock.register_temp_plugin(BasicXBlock, "block")
    def test_child_isinstance(self):
        """
        Check that child_isinstance() works on direct children
        """
        self.runtime = WorkbenchRuntime()
        self.root_id = self.runtime.parse_xml_string('<block> <block><cat/><gr/></block> <cat/> <gr/> </block>')
        root = self.runtime.get_block(self.root_id)
        self.assertFalse(child_isinstance(root, root.children[0], DogXBlock))
        self.assertFalse(child_isinstance(root, root.children[0], GoldenRetrieverXBlock))
        self.assertTrue(child_isinstance(root, root.children[0], BasicXBlock))

        self.assertFalse(child_isinstance(root, root.children[1], DogXBlock))
        self.assertFalse(child_isinstance(root, root.children[1], GoldenRetrieverXBlock))
        self.assertTrue(child_isinstance(root, root.children[1], CatXBlock))

        self.assertFalse(child_isinstance(root, root.children[2], CatXBlock))
        self.assertTrue(child_isinstance(root, root.children[2], DogXBlock))
        self.assertTrue(child_isinstance(root, root.children[2], GoldenRetrieverXBlock))

    @XBlock.register_temp_plugin(GoldenRetrieverXBlock, "gr")
    @XBlock.register_temp_plugin(CatXBlock, "cat")
    @XBlock.register_temp_plugin(BasicXBlock, "block")
    def test_child_isinstance_descendants(self):
        """
        Check that child_isinstance() works on deeper descendants
        """
        self.runtime = WorkbenchRuntime()
        self.root_id = self.runtime.parse_xml_string('<block> <block><cat/><gr/></block> <cat/> <gr/> </block>')
        root = self.runtime.get_block(self.root_id)
        block = root.runtime.get_block(root.children[0])
        self.assertIsInstance(block, BasicXBlock)

        self.assertFalse(child_isinstance(root, block.children[0], DogXBlock))
        self.assertTrue(child_isinstance(root, block.children[0], CatXBlock))

        self.assertTrue(child_isinstance(root, block.children[1], DogXBlock))
        self.assertTrue(child_isinstance(root, block.children[1], GoldenRetrieverXBlock))
        self.assertFalse(child_isinstance(root, block.children[1], CatXBlock))
Beispiel #5
0
class XmlTest(object):
    """Helpful things for XML tests."""

    def setUp(self):
        super(XmlTest, self).setUp()
        self.runtime = WorkbenchRuntime()

    def parse_xml_to_block(self, xml):
        """A helper to get a block from some XML."""
        usage_id = self.runtime.parse_xml_string(xml)
        block = self.runtime.get_block(usage_id)
        return block

    def export_xml_for_block(self, block):
        """A helper to return the XML string for a block."""
        output = StringIO.StringIO()
        self.runtime.export_to_xml(block, output)
        return output.getvalue()
Beispiel #6
0
def test_problem_submission():
    runtime = WorkbenchRuntime()
    problem_usage_id = runtime.parse_xml_string("""
        <problem>
            <textinput name='vote_count' input_type='int'/>

            <script>
                numvotes = 4
            </script>
            <equality name='votes_named' left='./vote_count/@student_input' right='$numvotes'>
                Number of upvotes matches entered string
            </equality>
        </problem>
    """)
    problem = runtime.get_block(problem_usage_id)
    json_data = json.dumps({"vote_count": [{"name": "input", "value": "4"}]})
    resp = runtime.handle(problem, 'check', make_request(json_data))
    resp_data = json.loads(text_of_response(resp))
    assert_equals(resp_data['checkResults']['votes_named'], True)
Beispiel #7
0
class XmlTest(object):
    """Helpful things for XML tests."""

    def setUp(self):
        super(XmlTest, self).setUp()
        self.runtime = WorkbenchRuntime()

    def parse_xml_to_block(self, xml):
        """A helper to get a block from some XML."""

        # WorkbenchRuntime has an id_generator, but most runtimes won't
        # (because the generator will be contextual), so we
        # pass it explicitly to parse_xml_string.
        usage_id = self.runtime.parse_xml_string(xml, self.runtime.id_generator)
        block = self.runtime.get_block(usage_id)
        return block

    def export_xml_for_block(self, block):
        """A helper to return the XML string for a block."""
        output = StringIO.StringIO()
        self.runtime.export_to_xml(block, output)
        return output.getvalue()
Beispiel #8
0
def test_problem_submission():
    runtime = WorkbenchRuntime()

    # WorkbenchRuntime has an id_generator, but most runtimes won't
    # (because the generator will be contextual), so we
    # pass it explicitly to parse_xml_string.
    problem_usage_id = runtime.parse_xml_string("""
        <problem_demo>
            <textinput_demo name='vote_count' input_type='int'/>

            <script>
                numvotes = 4
            </script>
            <equality_demo name='votes_named' left='./vote_count/@student_input' right='$numvotes'>
                Number of upvotes matches entered string
            </equality_demo>
        </problem_demo>
    """, runtime.id_generator)
    problem = runtime.get_block(problem_usage_id)
    json_data = json.dumps({"vote_count": [{"name": "input", "value": "4"}]})
    resp = runtime.handle(problem, 'check', make_request(json_data))
    resp_data = json.loads(text_of_response(resp))
    assert_equals(resp_data['checkResults']['votes_named'], True)
Beispiel #9
0
    def test_child_isinstance_descendants(self):
        """
        Check that child_isinstance() works on deeper descendants
        """
        self.runtime = WorkbenchRuntime()
        self.root_id = self.runtime.parse_xml_string('<block> <block><cat/><gr/></block> <cat/> <gr/> </block>')
        root = self.runtime.get_block(self.root_id)
        block = root.runtime.get_block(root.children[0])
        self.assertIsInstance(block, BasicXBlock)

        self.assertFalse(child_isinstance(root, block.children[0], DogXBlock))
        self.assertTrue(child_isinstance(root, block.children[0], CatXBlock))

        self.assertTrue(child_isinstance(root, block.children[1], DogXBlock))
        self.assertTrue(child_isinstance(root, block.children[1], GoldenRetrieverXBlock))
        self.assertFalse(child_isinstance(root, block.children[1], CatXBlock))
Beispiel #10
0
    def test_child_isinstance(self):
        """
        Check that child_isinstance() works on direct children
        """
        self.runtime = WorkbenchRuntime()
        self.root_id = self.runtime.parse_xml_string('<block> <block><cat/><gr/></block> <cat/> <gr/> </block>')
        root = self.runtime.get_block(self.root_id)
        self.assertFalse(child_isinstance(root, root.children[0], DogXBlock))
        self.assertFalse(child_isinstance(root, root.children[0], GoldenRetrieverXBlock))
        self.assertTrue(child_isinstance(root, root.children[0], BasicXBlock))

        self.assertFalse(child_isinstance(root, root.children[1], DogXBlock))
        self.assertFalse(child_isinstance(root, root.children[1], GoldenRetrieverXBlock))
        self.assertTrue(child_isinstance(root, root.children[1], CatXBlock))

        self.assertFalse(child_isinstance(root, root.children[2], CatXBlock))
        self.assertTrue(child_isinstance(root, root.children[2], DogXBlock))
        self.assertTrue(child_isinstance(root, root.children[2], GoldenRetrieverXBlock))
 def setUp(self):
     super(TestChildIsInstance, self).setUp()
     self.runtime = WorkbenchRuntime()
     self.root_id = self.runtime.parse_xml_string('<block> <block><cat/><gr/></block> <cat/> <gr/> </block>')
Beispiel #12
0
 def get_root(self):
     self.runtime = WorkbenchRuntime()
     self.root_id = self.runtime.parse_xml_string('<showanswer />')
     return self.runtime.get_block(self.root_id)
Beispiel #13
0
class TestShowAnswerXBlock(TestCase):
    """
    Unit tests for ShowAnswerXBlockMixin
    """
    def get_root(self):
        self.runtime = WorkbenchRuntime()
        self.root_id = self.runtime.parse_xml_string('<showanswer />')
        return self.runtime.get_block(self.root_id)

    @ddt.data(*[
        [True, True, True],
        [True, False, False],
        [False, True, True],
        [False, False, True],
    ])
    @ddt.unpack
    @XBlock.register_temp_plugin(ShowAnswerXBlock, "showanswer")
    def test_closed(self, can_attempt, past_due, expected):
        """
        Assert possible values for closed()
        """
        block = self.get_root()
        with mock.patch.object(
                ShowAnswerXBlock,
                'can_attempt',
                return_value=can_attempt,
        ), mock.patch.object(
                ShowAnswerXBlock,
                'is_past_due',
                return_value=past_due,
        ):
            self.assertEqual(block.closed(), expected)

    @XBlock.register_temp_plugin(ShowAnswerXBlock, "showanswer")
    def test_answer_available_no_correctness(self):
        """
        If no correctness is available, the answer is not available
        """
        block = self.get_root()
        with mock.patch.object(ShowAnswerXBlock,
                               'correctness_available',
                               return_value=False):
            self.assertFalse(block.answer_available())

    @XBlock.register_temp_plugin(ShowAnswerXBlock, "showanswer")
    def test_answer_available_user_is_staff(self):
        """
        If user is staff and correctness is available, the answer is available
        """
        block = self.get_root()
        self.runtime.user_is_staff = True
        with mock.patch.object(ShowAnswerXBlock,
                               'correctness_available',
                               return_value=True), mock.patch.object(
                                   ShowAnswerXBlock,
                                   'runtime_user_is_staff',
                                   return_value=True,
                               ):
            self.assertTrue(block.answer_available())

    @ddt.data(*[
        ['', {}, False],
        [ShowAnswer.NEVER, {}, False],
        [ShowAnswer.ATTEMPTED, {}, False],
        [ShowAnswer.ATTEMPTED, {
            'has_attempted': True
        }, True],
        [ShowAnswer.ANSWERED, {}, False],
        [ShowAnswer.ANSWERED, {
            'is_correct': True
        }, True],
        [ShowAnswer.CLOSED, {}, False],
        [ShowAnswer.CLOSED, {
            'closed': True
        }, True],
        [ShowAnswer.FINISHED, {}, False],
        [ShowAnswer.FINISHED, {
            'closed': True
        }, True],
        [ShowAnswer.FINISHED, {
            'is_correct': True
        }, True],
        [ShowAnswer.FINISHED, {
            'closed': True,
            'is_correct': True
        }, True],
        [ShowAnswer.CORRECT_OR_PAST_DUE, {}, False],
        [ShowAnswer.CORRECT_OR_PAST_DUE, {
            'is_correct': True
        }, True],
        [ShowAnswer.CORRECT_OR_PAST_DUE, {
            'is_past_due': True
        }, True],
        [
            ShowAnswer.CORRECT_OR_PAST_DUE, {
                'is_correct': True,
                'is_past_due': True
            }, True
        ],
        [ShowAnswer.PAST_DUE, {}, False],
        [ShowAnswer.PAST_DUE, {
            'is_past_due': True
        }, True],
        [ShowAnswer.ALWAYS, {}, True],
        ['unexpected', {}, False],
    ])
    @ddt.unpack
    @XBlock.register_temp_plugin(ShowAnswerXBlock, "showanswer")
    def test_answer_available_showanswer(self, showanswer, properties,
                                         expected):
        """
        Try different values of showanswer and assert answer_available()
        """
        block = self.get_root()
        block.showanswer = showanswer
        with mock.patch.object(
                ShowAnswerXBlock,
                'correctness_available',
                return_value=True,
        ), mock.patch.object(
                ShowAnswerXBlock,
                'runtime_user_is_staff',
                return_value=False,
        ), mock.patch.object(
                ShowAnswerXBlock,
                'has_attempted',
                return_value=properties.get('has_attempted', False),
        ), mock.patch.object(
                ShowAnswerXBlock,
                'is_correct',
                return_value=properties.get('is_correct', False),
        ), mock.patch.object(
                ShowAnswerXBlock,
                'closed',
                return_value=properties.get('closed', False),
        ), mock.patch.object(
                ShowAnswerXBlock,
                'is_past_due',
                return_value=properties.get('is_past_due', False),
        ):
            self.assertEqual(block.answer_available(), expected)
Beispiel #14
0
class XBlockHandlerTestCaseMixin:
    """
    Load the XBlock in the workbench runtime to test its handler.
    """
    def setUp(self):
        """
        Create the runtime.
        """
        super().setUp()
        self.runtime = WorkbenchRuntime()
        mock_publish = mock.MagicMock(side_effect=self.runtime.publish)
        self.runtime.publish = mock_publish

    def set_user(self, user_id):
        """
        Provide a user ID to the runtime.

        Args:
            user_id (str): a user ID.

        Returns:
            None
        """
        self.runtime.user_id = user_id

    def load_scenario(self, xml_path):
        """
        Load an XML definition of an XBlock and return the XBlock instance.

        Args:
            xml (string): Path to an XML definition of the XBlock, relative
                to the test module.

        Returns:
            XBlock
        """
        block_id = self.runtime.parse_xml_string(
            self.load_fixture_str(xml_path), self.runtime.id_generator)
        return self.runtime.get_block(block_id)

    def request(self,
                xblock,
                handler_name,
                content,
                request_method="POST",
                response_format=None,
                use_runtime=True):
        """
        Make a request to an XBlock handler.

        Args:
            xblock (XBlock): The XBlock instance that should handle the request.
            handler_name (str): The name of the handler.
            content (unicode): Content of the request.

        Keyword Arguments:
            request_method (str): The HTTP method of the request (defaults to POST)
            response_format (None or str): Expected format of the response string.
                If `None`, return the raw response content; if 'json', parse the
                response as JSON and return the result.

        Raises:
            NotImplementedError: Response format not supported.

        Returns:
            Content of the response (mixed).
        """
        # Create a fake request
        request = webob.Request(dict())
        request.method = request_method
        request.body = content.encode('utf-8')

        # Send the request to the XBlock handler
        if use_runtime:
            response = self.runtime.handle(xblock, handler_name, request)
        else:
            response = getattr(xblock, handler_name)(request)

        # Parse the response (if a format is specified)
        if response_format is None:
            return response.body
        elif response_format == 'json':
            return json.loads(response.body.decode('utf-8'))
        else:
            raise NotImplementedError(
                f"Response format '{response_format}' not supported")

    def assert_assessment_event_published(self, xblock, event_name, assessment,
                                          **kwargs):
        """ Checks assessment event published successfuly. """
        parts_list = []
        for part in assessment["parts"]:
            # Some assessment parts do not include point values,
            # only written feedback.  In this case, the assessment
            # part won't have an associated option.
            option_dict = None
            if part["option"] is not None:
                option_dict = {
                    "name": part["option"]["name"],
                    "points": part["option"]["points"],
                }

            # All assessment parts are associated with criteria
            criterion_dict = {
                "name": part["criterion"]["name"],
                "points_possible": part["criterion"]["points_possible"]
            }

            parts_list.append({
                "option": option_dict,
                "criterion": criterion_dict,
                "feedback": part["feedback"]
            })

        event_data = {
            "feedback": assessment["feedback"],
            "rubric": {
                "content_hash": assessment["rubric"]["content_hash"],
            },
            "scorer_id": assessment["scorer_id"],
            "score_type": assessment["score_type"],
            "scored_at": assessment["scored_at"],
            "submission_uuid": assessment["submission_uuid"],
            "parts": parts_list
        }

        for key in kwargs:
            event_data[key] = kwargs[key]

        self.assert_event_published(xblock, event_name, event_data)

    def assert_event_published(self, xblock, event_name, event_data):
        """
        Assert that an event was emitted with the given parameters.
        Args:
            event_name(str): The name of the event emitted
            event_data(dict): A dictionary containing the data we expect to have publish
        """
        self.runtime.publish.assert_any_call(xblock, event_name, event_data)

    @staticmethod
    def load_fixture_str(path):
        """
        Load data from a fixture file.

        Args:
            path (str): Path to the file.

        Returns:
            unicode: contents of the file.
        """
        base_dir = os.path.dirname(os.path.abspath(__file__))
        with open(os.path.join(base_dir, path)) as file_handle:
            return file_handle.read()
Beispiel #15
0
 def setUp(self):
     super(TestChildIsInstance, self).setUp()
     self.runtime = WorkbenchRuntime()
     self.root_id = self.runtime.parse_xml_string(
         '<block> <block><cat/><gr/></block> <cat/> <gr/> </block>')
Beispiel #16
0
 def setUp(self):
     """Create the runtime. """
     super(XBlockHandlerTestCaseMixin, self).setUp()
     self.runtime = WorkbenchRuntime()
Beispiel #17
0
class XBlockHandlerTestCaseMixin(object):
    """
    Load the XBlock in the workbench runtime to test its handler.
    """

    def setUp(self):
        """
        Create the runtime.
        """
        super(XBlockHandlerTestCaseMixin, self).setUp()
        self.runtime = WorkbenchRuntime()
        mock_publish = mock.MagicMock(side_effect=self.runtime.publish)
        self.runtime.publish = mock_publish

    def set_user(self, user_id):
        """
        Provide a user ID to the runtime.

        Args:
            user_id (str): a user ID.

        Returns:
            None
        """
        self.runtime.user_id = user_id

    def load_scenario(self, xml_path):
        """
        Load an XML definition of an XBlock and return the XBlock instance.

        Args:
            xml (string): Path to an XML definition of the XBlock, relative
                to the test module.

        Returns:
            XBlock
        """
        block_id = self.runtime.parse_xml_string(
            self.load_fixture_str(xml_path), self.runtime.id_generator
        )
        return self.runtime.get_block(block_id)

    def request(self, xblock, handler_name, content, request_method="POST", response_format=None, use_runtime=True):
        """
        Make a request to an XBlock handler.

        Args:
            xblock (XBlock): The XBlock instance that should handle the request.
            handler_name (str): The name of the handler.
            content (unicode): Content of the request.

        Keyword Arguments:
            request_method (str): The HTTP method of the request (defaults to POST)
            response_format (None or str): Expected format of the response string.
                If `None`, return the raw response content; if 'json', parse the
                response as JSON and return the result.

        Raises:
            NotImplementedError: Response format not supported.

        Returns:
            Content of the response (mixed).
        """
        # Create a fake request
        request = webob.Request(dict())
        request.method = request_method
        request.body = content

        # Send the request to the XBlock handler
        if use_runtime:
            response = self.runtime.handle(xblock, handler_name, request)
        else:
            response = getattr(xblock, handler_name)(request)

        # Parse the response (if a format is specified)
        if response_format is None:
            return response.body
        elif response_format == 'json':
            return json.loads(response.body)
        else:
            raise NotImplementedError("Response format '{format}' not supported".format(response_format))

    def assert_assessment_event_published(self, xblock, event_name, assessment, **kwargs):
        parts_list = []
        for part in assessment["parts"]:
            # Some assessment parts do not include point values,
            # only written feedback.  In this case, the assessment
            # part won't have an associated option.
            option_dict = None
            if part["option"] is not None:
                option_dict = {
                    "name": part["option"]["name"],
                    "points": part["option"]["points"],
                }

            # All assessment parts are associated with criteria
            criterion_dict = {
                "name": part["criterion"]["name"],
                "points_possible": part["criterion"]["points_possible"]
            }

            parts_list.append({
                "option": option_dict,
                "criterion": criterion_dict,
                "feedback": part["feedback"]
            })

        event_data = {
            "feedback": assessment["feedback"],
            "rubric": {
                "content_hash": assessment["rubric"]["content_hash"],
            },
            "scorer_id": assessment["scorer_id"],
            "score_type": assessment["score_type"],
            "scored_at": assessment["scored_at"],
            "submission_uuid": assessment["submission_uuid"],
            "parts": parts_list
        }

        for key in kwargs:
            event_data[key] = kwargs[key]

        self.assert_event_published(
            xblock, event_name, event_data
        )

    def assert_event_published(self, xblock, event_name, event_data):
        """
        Assert that an event was emitted with the given parameters.
        Args:
            event_name(str): The name of the event emitted
            event_data(dict): A dictionary containing the data we expect to have publish
        """
        self.runtime.publish.assert_any_call(
            xblock, event_name, event_data
        )

    @staticmethod
    def load_fixture_str(path):
        """
        Load data from a fixture file.

        Args:
            path (str): Path to the file.

        Returns:
            unicode: contents of the file.
        """
        base_dir = os.path.dirname(os.path.abspath(__file__))
        with open(os.path.join(base_dir, path)) as file_handle:
            return file_handle.read()
Beispiel #18
0
class XBlockHandlerTestCaseMixin(object):
    """Load the XBlock in the workbench runtime to test its handler. """

    def setUp(self):
        """Create the runtime. """
        super(XBlockHandlerTestCaseMixin, self).setUp()
        self.runtime = WorkbenchRuntime()

    def set_user(self, user_id):
        """Provide a user ID to the runtime.

        Args:
            user_id (str): a user ID.

        Returns:
            None
        """
        self.runtime.user_id = user_id

    def load_scenario(self, xml_path):
        """Load an XML definition of an XBlock and return the XBlock instance.

        Args:
            xml (string): Path to an XML definition of the XBlock, relative
                to the test module.

        Returns:
            XBlock
        """
        block_id = self.runtime.parse_xml_string(
            self.load_fixture_str(xml_path), self.runtime.id_generator
        )
        return self.runtime.get_block(block_id)

    def request(self, xblock, handler_name, content, request_method="POST", response_format=None):
        """Make a request to an XBlock handler.

        Args:
            xblock (XBlock): The XBlock instance that should handle the request.
            handler_name (str): The name of the handler.
            content (unicode): Content of the request.

        Keyword Arguments:
            request_method (str): The HTTP method of the request (defaults to POST)
            response_format (None or str): Expected format of the response string.
                If `None`, return the raw response content; if 'json', parse the
                response as JSON and return the result.

        Raises:
            NotImplementedError: Response format not supported.

        Returns:
            Content of the response (mixed).
        """
        # Create a fake request
        request = webob.Request(dict())
        request.method = request_method
        request.body = content

        # Send the request to the XBlock handler
        response = self.runtime.handle(xblock, handler_name, request)

        # Parse the response (if a format is specified)
        if response_format is None:
            return response.body
        elif response_format == 'json':
            return json.loads(response.body)
        else:
            raise NotImplementedError("Response format '{format}' not supported".format(response_format))

    @staticmethod
    def load_fixture_str(path):
        """Load data from a fixture file.

        Args:
            path (str): Path to the file.

        Returns:
            unicode: contents of the file.
        """
        with open(path, 'rb') as file_handle:
            return file_handle.read()
Beispiel #19
0
 def setUp(self):
     super(XmlTest, self).setUp()
     self.runtime = WorkbenchRuntime()
Beispiel #20
0
 def setUp(self):
     """
     Create the runtime.
     """
     self.runtime = WorkbenchRuntime()
Beispiel #21
0
class XBlockHandlerTestCaseMixin(object):
    """Load the XBlock in the workbench runtime to test its handler. """
    def setUp(self):
        """Create the runtime. """
        super(XBlockHandlerTestCaseMixin, self).setUp()
        self.runtime = WorkbenchRuntime()

    def set_user(self, user_id):
        """Provide a user ID to the runtime.

        Args:
            user_id (str): a user ID.

        Returns:
            None
        """
        self.runtime.user_id = user_id

    def load_scenario(self, xml_path):
        """Load an XML definition of an XBlock and return the XBlock instance.

        Args:
            xml (string): Path to an XML definition of the XBlock, relative
                to the test module.

        Returns:
            XBlock
        """
        block_id = self.runtime.parse_xml_string(
            self.load_fixture_str(xml_path), self.runtime.id_generator)
        return self.runtime.get_block(block_id)

    def request(self,
                xblock,
                handler_name,
                content,
                request_method="POST",
                response_format=None):
        """Make a request to an XBlock handler.

        Args:
            xblock (XBlock): The XBlock instance that should handle the request.
            handler_name (str): The name of the handler.
            content (unicode): Content of the request.

        Keyword Arguments:
            request_method (str): The HTTP method of the request (defaults to POST)
            response_format (None or str): Expected format of the response string.
                If `None`, return the raw response content; if 'json', parse the
                response as JSON and return the result.

        Raises:
            NotImplementedError: Response format not supported.

        Returns:
            Content of the response (mixed).
        """
        # Create a fake request
        request = webob.Request(dict())
        request.method = request_method
        request.body = content

        # Send the request to the XBlock handler
        response = self.runtime.handle(xblock, handler_name, request)

        # Parse the response (if a format is specified)
        if response_format is None:
            return response.body
        elif response_format == 'json':
            return json.loads(response.body)
        else:
            raise NotImplementedError(
                u"Response format '{}' not supported".format(response_format))

    @staticmethod
    def load_fixture_str(path):
        """Load data from a fixture file.

        Args:
            path (str): Path to the file.

        Returns:
            unicode: contents of the file.
        """
        with open(path, 'rb') as file_handle:
            return file_handle.read()
Beispiel #22
0
 def setUp(self):
     """Create the runtime. """
     super(XBlockHandlerTestCaseMixin, self).setUp()
     self.runtime = WorkbenchRuntime()