示例#1
0
 def call_handler(client, block_key, handler_name, method, data=None):
     """ Call an XBlock handler """
     url_result = client.get(
         URL_BLOCK_GET_HANDLER_URL.format(block_key=block_key,
                                          handler_name=handler_name))
     url = url_result.data["handler_url"]
     data_json = json.dumps(data) if data else None
     response = getattr(client, method)(url,
                                        data_json,
                                        content_type="application/json")
     self.assertEqual(response.status_code, 200)
     return response.json()
示例#2
0
    def test_mark_complete_via_handler(self):
        """
        Test that a "complete on view" XBlock like the HTML block can be marked
        as complete using the LmsBlockMixin.publish_completion handler.
        """
        block_id = library_api.create_library_block(
            self.library.key, "html", "completable_html").usage_key
        new_olx = """
        <html display_name="Read this HTML">
            <![CDATA[
                <p>This is some <strong>HTML</strong>.</p>
            ]]>
        </html>
        """.strip()
        library_api.set_library_block_olx(block_id, new_olx)
        library_api.publish_changes(self.library.key)

        # We should get a REST API for retrieving completion data; for now use python

        def get_block_completion_status():
            """ Get block completion status (0 to 1) """
            block = xblock_api.load_block(block_id, self.student_a)
            assert hasattr(block, 'publish_completion')
            service = block.runtime.service(block, 'completion')
            return service.get_completions([block_id])[block_id]

        # At first the block is not completed
        assert get_block_completion_status() == 0

        # Now call the 'publish_completion' handler:
        client = APIClient()
        client.login(username=self.student_a.username, password='******')
        result = client.get(
            URL_BLOCK_GET_HANDLER_URL.format(
                block_key=block_id, handler_name='publish_completion'))
        publish_completion_url = result.data["handler_url"]

        # This will test the 'completion' service and the completion event handler:
        result2 = client.post(publish_completion_url, {"completion": 1.0},
                              format='json')
        assert result2.status_code == 200

        # Now the block is completed
        assert get_block_completion_status() == 1
示例#3
0
    def test_scores_persisted(self):
        """
        Test that a block's emitted scores are cached in StudentModule

        In the future if there is a REST API to retrieve individual block's
        scores, that should be used instead of checking StudentModule directly.
        """
        block_id = library_api.create_library_block(self.library.key, "problem", "scored_problem").usage_key
        new_olx = """
        <problem display_name="New Multi Choice Question" max_attempts="5">
            <multiplechoiceresponse>
                <p>This is a normal capa problem. It has "maximum attempts" set to **5**.</p>
                <label>Blockstore is designed to store.</label>
                <choicegroup type="MultipleChoice">
                    <choice correct="false">XBlock metadata only</choice>
                    <choice correct="true">XBlock data/metadata and associated static asset files</choice>
                    <choice correct="false">Static asset files for XBlocks and courseware</choice>
                    <choice correct="false">XModule metadata only</choice>
                </choicegroup>
            </multiplechoiceresponse>
        </problem>
        """.strip()
        library_api.set_library_block_olx(block_id, new_olx)
        library_api.publish_changes(self.library.key)

        # Now view the problem as Alice:
        client = APIClient()
        client.login(username=self.student_a.username, password='******')
        student_view_result = client.get(URL_BLOCK_RENDER_VIEW.format(block_key=block_id, view_name='student_view'))
        problem_key = "input_{}_2_1".format(block_id)
        assert problem_key in student_view_result.data['content']

        # And submit a wrong answer:
        result = client.get(URL_BLOCK_GET_HANDLER_URL.format(block_key=block_id, handler_name='xmodule_handler'))
        problem_check_url = result.data["handler_url"] + 'problem_check'

        submit_result = client.post(problem_check_url, data={problem_key: "choice_3"})
        assert submit_result.status_code == 200
        submit_data = json.loads(submit_result.content.decode('utf-8'))
        self.assertDictContainsSubset({
            "current_score": 0,
            "total_possible": 1,
            "attempts_used": 1,
        }, submit_data)

        # Now test that the score is also persisted in StudentModule:
        # If we add a REST API to get an individual block's score, that should be checked instead of StudentModule.
        sm = get_score(self.student_a, block_id)
        assert sm.grade == 0
        assert sm.max_grade == 1

        # And submit a correct answer:
        submit_result = client.post(problem_check_url, data={problem_key: "choice_1"})
        assert submit_result.status_code == 200
        submit_data = json.loads(submit_result.content.decode('utf-8'))
        self.assertDictContainsSubset({
            "current_score": 1,
            "total_possible": 1,
            "attempts_used": 2,
        }, submit_data)
        # Now test that the score is also updated in StudentModule:
        # If we add a REST API to get an individual block's score, that should be checked instead of StudentModule.
        sm = get_score(self.student_a, block_id)
        assert sm.grade == 1
        assert sm.max_grade == 1