Пример #1
0
 def test_sender_sets_lineitems_url_with_the_value_in_auth_state_dict(
         self, lti_config_environ):
     sut = LTI13GradeSender('course-id', 'lab', {
         'course_lineitems':
         'canvas.docker.com/api/lti/courses/1/line_items'
     })
     assert sut.lineitems_url == 'canvas.docker.com/api/lti/courses/1/line_items'
Пример #2
0
 async def test_sender_raises_AssignmentWithoutGradesError_if_there_are_no_grades(
         self, lti13_config_environ, mock_nbhelper):
     sut = LTI13GradeSender('course-id', 'lab')
     with patch.object(LTI13GradeSender,
                       '_retrieve_grades_from_db',
                       return_value=(lambda: 10, [])):
         with pytest.raises(AssignmentWithoutGradesError):
             await sut.send_grades()
Пример #3
0
    async def test_get_lineitems_from_url_method_sets_all_lineitems_property(
            self, lti13_config_environ, mock_nbhelper,
            http_async_httpclient_with_simple_response):
        sut = LTI13GradeSender('course-id', 'lab')

        await sut._get_lineitems_from_url(
            'https://example.canvas.com/api/lti/courses/111/line_items')
        assert len(sut.all_lineitems) == 1
Пример #4
0
 async def test_sender_raises_AssignmentWithoutGradesError_if_there_are_not_grades(
         self, lti_config_environ):
     sut = LTI13GradeSender('course-id', 'lab', {
         'course_lineitems':
         'canvas.docker.com/api/lti/courses/1/line_items'
     })
     with patch.object(LTI13GradeSender,
                       '_retrieve_grades_from_db',
                       return_value=(lambda: 10, [])):
         with pytest.raises(AssignmentWithoutGradesError):
             await sut.send_grades()
Пример #5
0
 async def test_get_lineitems_from_url_method_does_fetch_lineitems_from_url(
         self, lti13_config_environ, mock_nbhelper, make_http_response,
         make_mock_request_handler):
     local_handler = make_mock_request_handler(RequestHandler)
     sut = LTI13GradeSender('course-id', 'lab')
     lineitems_url = 'https://example.canvas.com/api/lti/courses/111/line_items'
     with patch.object(AsyncHTTPClient,
                       'fetch',
                       return_value=make_http_response(
                           handler=local_handler.request)) as mock_client:
         await sut._get_lineitems_from_url(lineitems_url)
         assert mock_client.called
         mock_client.assert_called_with(lineitems_url,
                                        method='GET',
                                        headers={})
Пример #6
0
    async def test_sender_raises_an_error_if_no_line_items_were_found(
            self, lti13_config_environ,
            http_async_httpclient_with_simple_response, mock_nbhelper):
        sut = LTI13GradeSender('course-id', 'lab')

        access_token_result = {'token_type': '', 'access_token': ''}
        with patch('illumidesk.grades.senders.get_lms_access_token',
                   return_value=access_token_result):

            with patch.object(LTI13GradeSender,
                              '_retrieve_grades_from_db',
                              return_value=(lambda: 10, [{
                                  'score': 10
                              }])):
                with pytest.raises(GradesSenderMissingInfoError):
                    await sut.send_grades()
Пример #7
0
    async def post(self, course_id: str, assignment_name: str) -> None:
        """
        Receives a request with the course name and the assignment name as path parameters
        which then uses the appropriate class to send grades to the platform based on the
        LTI authenticator version (1.1 or 1.3).

        Arguments:
          course_id: course name which has been previously normalized by the LTIUtils.normalize_string
            function.
          assignment_name: assignment name which should coincide with the assignment name within the LMS.

        Raises:
          GradesSenderCriticalError if there was a critical error when either extracting grades from the db
            or sending grades to the tool consumer / platform.
          AssignmentWithoutGradesError if the assignment does not have any grades associated to it.
          GradesSenderMissingInfoError if ther is missing information when attempting to send grades.
        """
        self.log.debug(
            f'Data received to send grades-> course:{course_id}, assignment:{assignment_name}'
        )

        lti_grade_sender = None

        # check lti version by the authenticator setting
        if isinstance(self.authenticator, LTI11Authenticator
                      ) or self.authenticator is LTI11Authenticator:
            lti_grade_sender = LTIGradeSender(course_id, assignment_name)
        else:
            lti_grade_sender = LTI13GradeSender(course_id, assignment_name)
        try:
            await lti_grade_sender.send_grades()
        except exceptions.GradesSenderCriticalError:
            raise web.HTTPError(
                400, 'There was an critical error, please check logs.')
        except exceptions.AssignmentWithoutGradesError:
            raise web.HTTPError(400, 'There are no grades yet to submit')
        except exceptions.GradesSenderMissingInfoError as e:
            self.log.error(f'There are missing values.{e}')
            raise web.HTTPError(
                400,
                f'Impossible to send grades. There are missing values, please check logs.{e}'
            )
        self.write(json.dumps({"success": True}))
Пример #8
0
    async def test_sender_calls__set_access_token_header_before_to_send_grades(
            self, lti_config_environ):
        sut = LTI13GradeSender('course-id', 'lab', {
            'course_lineitems':
            'canvas.docker.com/api/lti/courses/1/line_items'
        })
        local_handler = mock_handler(RequestHandler)
        access_token_result = {'token_type': '', 'access_token': ''}
        line_item_result = {
            'label': 'lab',
            'id': 'line_item_url',
            'scoreMaximum': 40
        }
        with patch('illumidesk.grades.senders.get_lms_access_token',
                   return_value=access_token_result) as mock_method:
            with patch.object(
                    LTI13GradeSender,
                    '_retrieve_grades_from_db',
                    return_value=(lambda: 10, [{
                        'score': 10,
                        'lms_user_id': 'id'
                    }]),
            ):

                with patch.object(
                        AsyncHTTPClient,
                        'fetch',
                        side_effect=[
                            factory_http_response(
                                handler=local_handler.request,
                                body=[line_item_result]),
                            factory_http_response(
                                handler=local_handler.request,
                                body=line_item_result),
                            factory_http_response(
                                handler=local_handler.request, body=[]),
                        ],
                ):
                    await sut.send_grades()
                    assert mock_method.called
Пример #9
0
    async def test_get_lineitems_from_url_method_calls_itself_recursively(
            self, lti13_config_environ, mock_nbhelper, make_http_response,
            make_mock_request_handler):
        local_handler = make_mock_request_handler(RequestHandler)
        sut = LTI13GradeSender('course-id', 'lab')

        lineitems_body_result = {
            'body': [{
                "id": "value",
                "scoreMaximum": 0.0,
                "label": "label",
                "resourceLinkId": "abc"
            }]
        }
        lineitems_body_result['headers'] = HTTPHeaders({
            'content-type':
            'application/vnd.ims.lis.v2.lineitemcontainer+json',
            'link':
            '<https://learning.flatironschool.com/api/lti/courses/691/line_items?page=2&per_page=10>; rel="next"',
        })

        with patch.object(
                AsyncHTTPClient,
                'fetch',
                side_effect=[
                    make_http_response(handler=local_handler.request,
                                       **lineitems_body_result),
                    make_http_response(handler=local_handler.request,
                                       body=lineitems_body_result['body']),
                ],
        ) as mock_fetch:
            # initial call then the method will detect the Link header to get the next items
            await sut._get_lineitems_from_url(
                'https://example.canvas.com/api/lti/courses/111/line_items')
            # assert the lineitems number
            assert len(sut.all_lineitems) == 2
            # assert the number of calls
            assert mock_fetch.call_count == 2
Пример #10
0
 def test_sender_sets_lineitems_url_with_the_value_in_auth_state_dict(
         self, lti13_config_environ, mock_nbhelper):
     sut = LTI13GradeSender('course-id', 'lab')
     assert sut.course.lms_lineitems_endpoint == 'canvas.docker.com/api/lti/courses/1/line_items'
Пример #11
0
 def test_sender_raises_an_error_without_auth_state_information(self):
     with pytest.raises(GradesSenderMissingInfoError):
         LTI13GradeSender('course-id', 'lab', None)