Beispiel #1
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).decode('utf-8'))
    assert resp_data['checkResults']['votes_named'] == True
    assert resp_data['checkResults']['votes_named'] == True
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 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 #4
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 #5
0
class XBlockHandlerTestCaseMixin:
    """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 #6
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.
                If 'response', return the entire response object (helpful for asserting response codes).

        Raises:
            NotImplementedError: Response format not supported.

        Returns:
            Content of the response (mixed).
        """
        # Create a fake request
        request = webob.Request({})
        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'))
        elif response_format == 'response':
            return response
        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, value in kwargs.items():
            event_data[key] = value

        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 #7
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 #8
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()