async def test_setup_course_hook_calls_add_user_to_nbgrader_gradebook_when_role_is_learner(
    mock_mkdir,
    mock_chown,
    mock_gradebook,
    monkeypatch,
    setup_course_environ,
    setup_course_hook_environ,
    make_auth_state_dict,
    make_mock_request_handler,
    make_http_response,
):
    """
    Is the jupyterhub_api add user to nbgrader gradebook function called when the user role is
    the learner role?
    """
    local_authenticator = Authenticator(post_auth_hook=setup_course_hook)
    local_handler = make_mock_request_handler(
        RequestHandler, authenticator=local_authenticator)
    local_authentication = make_auth_state_dict()

    with patch.object(JupyterHubAPI,
                      'add_student_to_jupyterhub_group',
                      return_value=None):
        with patch.object(
                NbGraderServiceHelper,
                'add_user_to_nbgrader_gradebook',
                return_value=None) as mock_add_user_to_nbgrader_gradebook:
            with patch.object(AsyncHTTPClient,
                              'fetch',
                              return_value=make_http_response(
                                  handler=local_handler.request)):
                await setup_course_hook(local_authenticator, local_handler,
                                        local_authentication)
                assert mock_add_user_to_nbgrader_gradebook.called
async def test_setup_course_hook_calls_add_instructor_to_jupyterhub_group_when_role_is_TeachingAssistant(
    monkeypatch,
    setup_course_environ,
    setup_course_hook_environ,
    make_auth_state_dict,
    make_mock_request_handler,
    make_http_response,
    mock_nbhelper,
):
    """
    Is the jupyterhub_api add instructor to jupyterhub group function called when the user role is
    the instructor role?
    """
    local_authenticator = Authenticator(post_auth_hook=setup_course_hook)
    local_handler = make_mock_request_handler(
        RequestHandler, authenticator=local_authenticator)
    local_authentication = make_auth_state_dict(
        user_role='urn:lti:role:ims/lis/TeachingAssistant')

    with patch.object(
            JupyterHubAPI, 'add_instructor_to_jupyterhub_group',
            return_value=None) as mock_add_instructor_to_jupyterhub_group:
        with patch.object(AsyncHTTPClient,
                          'fetch',
                          return_value=make_http_response(
                              handler=local_handler.request)):
            await setup_course_hook(local_authenticator, local_handler,
                                    local_authentication)
            assert mock_add_instructor_to_jupyterhub_group.called
async def test_setup_course_hook_calls_add_student_to_jupyterhub_group_when_role_is_learner(
    setup_course_environ,
    setup_course_hook_environ,
    make_auth_state_dict,
    make_http_response,
    make_mock_request_handler,
    mock_nbhelper,
):
    """
    Is the jupyterhub_api add student to jupyterhub group function called when the user role is
    the learner role?
    """
    local_authenticator = Authenticator(post_auth_hook=setup_course_hook)
    local_handler = make_mock_request_handler(
        RequestHandler, authenticator=local_authenticator)
    local_authentication = make_auth_state_dict()

    with patch.object(
            JupyterHubAPI, 'add_student_to_jupyterhub_group',
            return_value=None) as mock_add_student_to_jupyterhub_group:
        with patch.object(AsyncHTTPClient,
                          'fetch',
                          return_value=make_http_response(
                              handler=local_handler.request)):
            result = await setup_course_hook(local_authenticator,
                                             local_handler,
                                             local_authentication)
            assert mock_add_student_to_jupyterhub_group.called
Beispiel #4
0
async def test_setup_course_hook_initialize_data_dict(
        setup_course_environ, setup_course_hook_environ):
    """
    Is the data dictionary correctly initialized when properly setting the org env-var and and consistent with the
    course id value in the auth state?
    """
    local_authenticator = Authenticator(post_auth_hook=setup_course_hook)
    local_handler = mock_handler(RequestHandler,
                                 authenticator=local_authenticator)
    local_authentication = factory_auth_state_dict()

    expected_data = {
        'org': 'test-org',
        'course_id': 'intro101',
        'domain': '127.0.0.1',
    }

    with patch.object(JupyterHubAPI,
                      'add_student_to_jupyterhub_group',
                      return_value=None):
        with patch.object(JupyterHubAPI,
                          'add_user_to_nbgrader_gradebook',
                          return_value=None):
            with patch.object(AsyncHTTPClient,
                              'fetch',
                              return_value=factory_http_response(
                                  handler=local_handler.request)):
                result = await setup_course_hook(local_authenticator,
                                                 local_handler,
                                                 local_authentication)
                assert expected_data['course_id'] == result['auth_state'][
                    'course_id']
                assert expected_data['org'] == os.environ.get(
                    'ORGANIZATION_NAME')
                assert expected_data['domain'] == local_handler.request.host
Beispiel #5
0
async def test_setup_course_hook_does_not_call_add_instructor_to_jupyterhub_group_when_role_is_learner(
    setup_course_environ,
    setup_course_hook_environ,
    make_auth_state_dict,
    make_http_response,
    make_mock_request_handler,
    mock_nbhelper,
):
    """
    Is the register_new_service function called when the user_role is learner or student?
    """
    local_authenticator = Authenticator(post_auth_hook=setup_course_hook)
    local_handler = make_mock_request_handler(
        RequestHandler, authenticator=local_authenticator)
    local_authentication = make_auth_state_dict()

    with patch.object(NbGraderServiceHelper,
                      "add_user_to_nbgrader_gradebook",
                      return_value=None):
        with patch.object(JupyterHubAPI,
                          "add_student_to_jupyterhub_group",
                          return_value=None):
            with patch.object(JupyterHubAPI,
                              "add_instructor_to_jupyterhub_group",
                              return_value=None
                              ) as mock_add_instructor_to_jupyterhub_group:
                with patch.object(
                        AsyncHTTPClient,
                        "fetch",
                        return_value=make_http_response(
                            handler=local_handler.request),
                ):
                    await setup_course_hook(local_authenticator, local_handler,
                                            local_authentication)
                    assert not mock_add_instructor_to_jupyterhub_group.called
Beispiel #6
0
async def test_setup_course_hook_does_not_call_add_student_to_jupyterhub_group_when_role_is_instructor(
    setup_course_environ,
    setup_course_hook_environ,
    make_auth_state_dict,
    make_http_response,
    make_mock_request_handler,
    mock_nbhelper,
):
    """
    Is the jupyterhub_api add student to jupyterhub group function called when the user role is
    the instructor role?
    """
    local_authenticator = Authenticator(post_auth_hook=setup_course_hook)
    local_handler = make_mock_request_handler(
        RequestHandler, authenticator=local_authenticator)
    local_authentication = make_auth_state_dict(user_role="Instructor")

    with patch.object(
            JupyterHubAPI, "add_student_to_jupyterhub_group",
            return_value=None) as mock_add_student_to_jupyterhub_group:
        with patch.object(
                JupyterHubAPI,
                "add_instructor_to_jupyterhub_group",
                return_value=None) as mock_add_instructor_to_jupyterhub_group:
            with patch.object(
                    AsyncHTTPClient,
                    "fetch",
                    return_value=make_http_response(
                        handler=local_handler.request),
            ):
                await setup_course_hook(local_authenticator, local_handler,
                                        local_authentication)
                assert not mock_add_student_to_jupyterhub_group.called
                assert mock_add_instructor_to_jupyterhub_group.called
Beispiel #7
0
async def test_setup_course_hook_calls_normalize_strings(
        auth_state_dict, setup_course_environ, setup_course_hook_environ):
    """
    Does the setup_course_hook return normalized strings for the username and the course_id?
    """
    local_authenticator = Authenticator(post_auth_hook=setup_course_hook)
    local_handler = mock_handler(RequestHandler,
                                 authenticator=local_authenticator)
    local_authentication = auth_state_dict

    with patch.object(LTIUtils, 'normalize_string',
                      return_value='intro101') as mock_normalize_string:
        with patch.object(JupyterHubAPI,
                          'add_student_to_jupyterhub_group',
                          return_value=None):
            with patch.object(JupyterHubAPI,
                              'add_user_to_nbgrader_gradebook',
                              return_value=None):
                with patch.object(AsyncHTTPClient,
                                  'fetch',
                                  return_value=factory_http_response(
                                      handler=local_handler.request)):
                    _ = await setup_course_hook(local_authenticator,
                                                local_handler,
                                                local_authentication)
                    assert mock_normalize_string.called
Beispiel #8
0
async def test_setup_course_hook_does_not_call_add_instructor_to_jupyterhub_group_when_role_is_learner(
        setup_course_environ, setup_course_hook_environ):
    """
    Is the jupyterhub_api add instructor to jupyterhub group function not called when the user role is
    the learner role?
    """
    local_authenticator = Authenticator(post_auth_hook=setup_course_hook)
    local_handler = mock_handler(RequestHandler,
                                 authenticator=local_authenticator)
    local_authentication = factory_auth_state_dict()

    with patch.object(JupyterHubAPI,
                      'add_student_to_jupyterhub_group',
                      return_value=None):
        with patch.object(JupyterHubAPI,
                          'add_user_to_nbgrader_gradebook',
                          return_value=None):
            with patch.object(JupyterHubAPI,
                              'add_instructor_to_jupyterhub_group',
                              return_value=None
                              ) as mock_add_instructor_to_jupyterhub_group:
                with patch.object(
                        AsyncHTTPClient,
                        'fetch',
                        return_value=factory_http_response(
                            handler=local_handler.request),
                ):
                    await setup_course_hook(local_authenticator, local_handler,
                                            local_authentication)
                    assert not mock_add_instructor_to_jupyterhub_group.called
Beispiel #9
0
    async def add_user(self, user):
        """Hook called whenever a new user is added
        self.create_system_users not supported.
        """
        islocaluser = '******' not in user.name
        user_exists = await maybe_future(self.system_user_exists(user))
        if not user_exists and islocaluser:
            if self.create_system_users:
                raise KeyError("There is no support for create_system_users on Windows")
            else:
                raise KeyError("User %s does not exist." % user.name)

        await maybe_future(Authenticator.add_user(self, user))
Beispiel #10
0
async def test_is_new_course_initiates_rolling_update(
        setup_course_environ, setup_course_hook_environ):
    """
    If the course is a new setup does it initiate a rolling update?
    """
    local_authenticator = Authenticator(post_auth_hook=setup_course_hook)
    local_handler = mock_handler(RequestHandler,
                                 authenticator=local_authenticator)
    local_authentication = factory_auth_state_dict()

    response_args = {
        'handler': local_handler.request,
        'body': {
            'is_new_setup': True
        }
    }
    with patch.object(
            JupyterHubAPI, 'add_student_to_jupyterhub_group',
            return_value=None) as mock_add_student_to_jupyterhub_group:
        with patch.object(JupyterHubAPI,
                          'add_user_to_nbgrader_gradebook',
                          return_value=None):

            with patch.object(
                    AsyncHTTPClient,
                    'fetch',
                    side_effect=[
                        factory_http_response(**response_args),
                        factory_http_response(**response_args),
                        None,
                    ],  # noqa: E231
            ) as mock_client:

                await setup_course_hook(local_authenticator, local_handler,
                                        local_authentication)
                assert mock_client.called

                mock_client.assert_any_call(
                    'http://setup-course:8000/rolling-update',
                    headers={'Content-Type': 'application/json'},
                    body='',
                    method='POST',
                )

                mock_client.assert_any_call(
                    'http://setup-course:8000',
                    headers={'Content-Type': 'application/json'},
                    body=
                    '{"org": "test-org", "course_id": "intro101", "domain": "127.0.0.1"}',
                    method='POST',
                )
Beispiel #11
0
async def test_setup_course_hook_raises_environment_error_with_missing_org(
        monkeypatch, setup_course_hook_environ):
    """
    Is an environment error raised when the organization name is missing when calling
    the setup_course_hook function?
    """
    monkeypatch.setenv('ORGANIZATION_NAME', '')
    local_authenticator = Authenticator(post_auth_hook=setup_course_hook)
    local_handler = mock_handler(RequestHandler,
                                 authenticator=local_authenticator)
    local_authentication = factory_auth_state_dict()
    with pytest.raises(EnvironmentError):
        await local_authenticator.post_auth_hook(local_authenticator,
                                                 local_handler,
                                                 local_authentication)
Beispiel #12
0
async def test_setup_course_hook_initialize_data_dict(
    setup_course_environ,
    setup_course_hook_environ,
    make_auth_state_dict,
    make_http_response,
    make_mock_request_handler,
    mock_nbhelper,
):
    """
    Is the data dictionary correctly initialized when properly setting the org env-var and and consistent with the
    course id value in the auth state?
    """
    local_authenticator = Authenticator(post_auth_hook=setup_course_hook)
    local_handler = make_mock_request_handler(
        RequestHandler, authenticator=local_authenticator)
    local_authentication = make_auth_state_dict()

    expected_data = {
        "org": "test-org",
        "course_id": "intro101",
        "domain": "127.0.0.1",
    }

    with patch.object(JupyterHubAPI,
                      "add_student_to_jupyterhub_group",
                      return_value=None):
        with patch.object(
                AsyncHTTPClient,
                "fetch",
                return_value=make_http_response(handler=local_handler.request),
        ):
            result = await setup_course_hook(local_authenticator,
                                             local_handler,
                                             local_authentication)
            assert expected_data["course_id"] == result["auth_state"][
                "course_id"]
            assert expected_data["org"] == os.environ.get("ORGANIZATION_NAME")
            assert expected_data["domain"] == local_handler.request.host
Beispiel #13
0
async def test_setup_course_hook_raises_json_decode_error_without_client_fetch_response(
        monkeypatch, setup_course_environ, setup_course_hook_environ):
    """
    Does the setup course hook raise a json decode error if the response form the setup course
    microservice is null or empty?
    """
    local_authenticator = Authenticator(post_auth_hook=setup_course_hook)
    local_handler = mock_handler(RequestHandler,
                                 authenticator=local_authenticator)
    local_authentication = factory_auth_state_dict()

    with patch.object(
            JupyterHubAPI, 'add_student_to_jupyterhub_group',
            return_value=None) as mock_add_student_to_jupyterhub_group:
        with patch.object(JupyterHubAPI,
                          'add_user_to_nbgrader_gradebook',
                          return_value=None):
            with patch.object(AsyncHTTPClient,
                              'fetch',
                              return_value=factory_http_response(
                                  handler=local_handler.request, body=None)):
                with pytest.raises(JSONDecodeError):
                    await setup_course_hook(local_authenticator, local_handler,
                                            local_authentication)
Beispiel #14
0
 def __init__(self, **kwargs):
     Authenticator.__init__(self, **kwargs)
     self.custom_html = '<br> <div style="text-align: center; background: black;"> <img src="http://atigeo.com/assets/imgs/xpatterns-logo.svg"> </div>'
Beispiel #15
0
 def _log_default(self):
     """wrap loggers for this application."""
     return wrap_logger_handlers(Authenticator._log_default(self))
Beispiel #16
0
 def __init__(self, **kwargs):
     Authenticator.__init__(self, **kwargs)
     self.custom_html = '<br> <div style="text-align: center; background: black;"> <img src="http://atigeo.com/assets/imgs/xpatterns-logo.svg"> </div>'