def test_should_default_to_none_role(self, MockRecommendReviewers): config = dict_to_config({}) with _api_test_client(config, {}) as test_client: test_client.get('/recommend-reviewers?' + urlencode({'manuscript_no': MANUSCRIPT_NO_1})) _assert_partial_called_with( MockRecommendReviewers.return_value.recommend, role=None)
def test_should_allow_search_type_and_not_check_person_role_if_no_role_is_required( self, MockRecommendReviewers, MockFlaskAuth0): _setup_flask_auth0_mock_email(MockFlaskAuth0, email=EMAIL_1) config = dict_to_config({ 'auth': { 'allowed_ips': '' }, 'client': { 'auth0_domain': DOMAIN_1 }, SEARCH_SECTION_PREFIX + SEARCH_TYPE_1: { 'required_role': '' } }) with _api_test_client(config, {}) as test_client: user_has_role_by_email = MockRecommendReviewers.return_value.user_has_role_by_email response = test_client.get( '/recommend-reviewers?' + urlencode({ 'manuscript_no': MANUSCRIPT_NO_1, 'search_type': SEARCH_TYPE_1 })) user_has_role_by_email.assert_not_called() assert response.status_code == 200
def test_should_return_all_search_types_if_authorisation_is_not_required( self, MockFlaskAuth0, email, required_role, auth0_domain): _setup_flask_auth0_mock_email(MockFlaskAuth0, email=email) config = dict_to_config({ 'auth': { 'allowed_ips': '', 'valid_email_domains': 'science.org' }, 'client': { 'auth0_domain': auth0_domain } if auth0_domain else {}, SEARCH_SECTION_PREFIX + SEARCH_TYPE_1: { 'required_role': required_role or '', 'title': SEARCH_TYPE_TITLE_1 }, SEARCH_SECTION_PREFIX + SEARCH_TYPE_2: { 'required_role': required_role or '', 'title': SEARCH_TYPE_TITLE_2 } }) with _api_test_client(config, {}) as test_client: response = test_client.get('/search-types') assert _get_ok_json(response) == [{ 'search_type': SEARCH_TYPE_1, 'title': SEARCH_TYPE_TITLE_1 }, { 'search_type': SEARCH_TYPE_2, 'title': SEARCH_TYPE_TITLE_2 }]
def _dict_to_cfg_content(d): config = dict_to_config(d) fp = StringIO() config.write(fp) content = fp.getvalue() LOGGER.debug('content: %s', content) return content
def test_should_parse_default_limit_as_int(self): config = dict_to_config( {_search_section_name(SEARCH_TYPE_1): { 'default_limit': '123' }}) search_config = parse_search_config(config) assert search_config.keys() == {SEARCH_TYPE_1} assert search_config[SEARCH_TYPE_1]['default_limit'] == 123
def test_should_parse_single_search_config(self): config = dict_to_config({ _search_section_name(SEARCH_TYPE_1): { PARAM_KEY_1: PARAM_VALUE_1 } }) search_config = parse_search_config(config) assert search_config.keys() == {SEARCH_TYPE_1} assert search_config[SEARCH_TYPE_1][PARAM_KEY_1] == PARAM_VALUE_1
def test_should_return_client_config(self, MockRecommendReviewers): client_config = {'some key': VALUE_1} config = dict_to_config({'client': client_config}) with _api_test_client(config, {}) as test_client: MockRecommendReviewers.return_value.get_all_subject_areas.return_value = [ VALUE_1, VALUE_2 ] response = test_client.get('/config') assert _get_ok_json(response) == client_config
def test_should_pass_expire_after_secs_to_cache(self, create_str_cache_mock, mock_f): cache_dir = '.cache/dir' decorate_get_request_handler(mock_f, dict_to_config( {}), cache_dir=cache_dir, expire_after_secs=123) create_str_cache_mock.assert_called_with( ANY, cache_dir=cache_dir, suffix='.json', expire_after_secs=123 )
def test_should_parse_recommend_relationship_types_as_list(self): config = dict_to_config({ _search_section_name(SEARCH_TYPE_1): { 'recommend_relationship_types': ' %s , %s ' % (PARAM_VALUE_1, PARAM_VALUE_2) } }) search_config = parse_search_config(config) assert search_config.keys() == {SEARCH_TYPE_1} assert search_config[SEARCH_TYPE_1][ 'recommend_relationship_types'] == [PARAM_VALUE_1, PARAM_VALUE_2]
def test_should_wrap_with_auth_if_auth0_domain_is_present( self, MockFlaskAuth0): _setup_flask_auth0_mock_email(MockFlaskAuth0, email=None) api_auth = ApiAuth(dict_to_config({}), {'auth0_domain': VALUE_1}) _assert_partial_called_with(MockFlaskAuth0, domain=VALUE_1) f = _named_mock(name='f') wrapped_f = api_auth.wrap_search(f) assert wrapped_f != f assert wrapped_f() == f.return_value
def test_should_return_manuscript_details_if_manuscript_was_found( self, MockRecommendReviewers): config = dict_to_config({}) with _api_test_client(config, {}) as test_client: get_manuscript_details = MockRecommendReviewers.return_value.get_manuscript_details get_manuscript_details.return_value = SOME_RESPONSE response = test_client.get('/manuscript/version/%s' % VERSION_ID_1) assert _get_ok_json(response) == SOME_RESPONSE get_manuscript_details.assert_called_with(VERSION_ID_1)
def test_should_return_404_if_manuscript_not_found( self, MockRecommendReviewers): config = dict_to_config({}) with _api_test_client(config, {}) as test_client: get_manuscript_details = MockRecommendReviewers.return_value.get_manuscript_details get_manuscript_details.return_value = None MockRecommendReviewers.return_value.get_manuscript_details.return_value = None response = test_client.get('/manuscript/version/%s' % VERSION_ID_1) assert response.status_code == 404
def test_should_handle_slash_in_version_id(self, MockRecommendReviewers): config = dict_to_config({}) with _api_test_client(config, {}) as test_client: get_manuscript_details = MockRecommendReviewers.return_value.get_manuscript_details get_manuscript_details.return_value = SOME_RESPONSE version_id = 'v/123' response = test_client.get('/manuscript/version/%s' % version_id) assert _get_ok_json(response) == SOME_RESPONSE get_manuscript_details.assert_called_with(version_id)
def test_should_reject_unknown_search_type(self): config = dict_to_config({ SEARCH_SECTION_PREFIX + SEARCH_TYPE_1: { 'filter_by_role': VALUE_1 } }) with _api_test_client(config, {}) as test_client: response = test_client.get( '/recommend-reviewers?' + urlencode({ 'manuscript_no': MANUSCRIPT_NO_1, 'search_type': SEARCH_TYPE_2 })) assert response.status_code == 400
def test_should_parse_roles_and_pass_to_get_persons_to_enrich( self, get_app_config_mock, get_persons_to_enrich_mock): get_app_config_mock.return_value = dict_to_config({ 'enrich-data': { 'include_roles': '%s, %s' % (ROLE_1, ROLE_2) } }) main() get_persons_to_enrich_mock.assert_called_with( ANY, include_early_career_researchers=ANY, include_roles=[ROLE_1, ROLE_2] )
def test_should_parse_true_early_career_researcher_and_pass_to_get_persons_to_enrich( self, get_app_config_mock, get_persons_to_enrich_mock): get_app_config_mock.return_value = dict_to_config({ 'enrich-data': { 'include_early_career_researcher': 'true' } }) main() get_persons_to_enrich_mock.assert_called_with( ANY, include_early_career_researchers=True, include_roles=ANY )
def test_should_parse_expire_after_secs_and_pass_to_decorate_get_request_handler( self, get_app_config_mock, decorate_get_request_handler_mock): get_app_config_mock.return_value = dict_to_config({ 'crossref': { 'expire_after_secs': '123' } }) main() decorate_get_request_handler_mock.assert_called_with( ANY, ANY, cache_dir=ANY, expire_after_secs=123 )
def test_should_return_manuscript_details_with_auth_enabled( self, MockRecommendReviewers, MockFlaskAuth0): _setup_flask_auth0_mock_email(MockFlaskAuth0, email=EMAIL_1) config = dict_to_config({ 'auth': { 'allowed_ips': '', 'valid_email_domains': 'science.org' }, 'client': { 'auth0_domain': DOMAIN_1 } }) with _api_test_client(config, {}) as test_client: get_manuscript_details = MockRecommendReviewers.return_value.get_manuscript_details get_manuscript_details.return_value = SOME_RESPONSE response = test_client.get('/manuscript/version/%s' % VERSION_ID_1) assert _get_ok_json(response) == SOME_RESPONSE get_manuscript_details.assert_called_with(VERSION_ID_1)
def test_should_allow_search_types_for_emails_part_of_configured_domain( self, MockFlaskAuth0): _setup_flask_auth0_mock_email(MockFlaskAuth0, email='*****@*****.**') user_has_role_by_email = Mock(name='user_has_role_by_email') user_has_role_by_email.return_value = False api_auth = ApiAuth( dict_to_config( {'auth': { 'valid_email_domains': 'science.org' }}), {'auth0_domain': DOMAIN_1}, search_config={SEARCH_TYPE_1: { 'required_role': ROLE_1 }}, user_has_role_by_email=user_has_role_by_email, get_search_type=lambda: SEARCH_TYPE_1) f = _named_mock(name='f') wrapped_f = api_auth.wrap_search(f) assert wrapped_f != f assert wrapped_f() == f.return_value
def test_should_filter_search_types_by_required_role( self, MockRecommendReviewers, MockFlaskAuth0): _setup_flask_auth0_mock_email(MockFlaskAuth0, email=EMAIL_1) config = dict_to_config({ 'auth': { 'allowed_ips': '' }, 'client': { 'auth0_domain': DOMAIN_1 }, SEARCH_SECTION_PREFIX + SEARCH_TYPE_1: { 'required_role': ROLE_1, 'title': SEARCH_TYPE_TITLE_1 }, SEARCH_SECTION_PREFIX + SEARCH_TYPE_2: { 'required_role': ROLE_2, 'title': SEARCH_TYPE_TITLE_2 }, SEARCH_SECTION_PREFIX + SEARCH_TYPE_3: { 'required_role': '', 'title': SEARCH_TYPE_TITLE_3 } }) with _api_test_client(config, {}) as test_client: get_user_roles_by_email = (MockRecommendReviewers.return_value. get_user_roles_by_email) get_user_roles_by_email.return_value = {ROLE_1} response = test_client.get('/search-types') assert _get_ok_json(response) == [{ 'search_type': SEARCH_TYPE_1, 'title': SEARCH_TYPE_TITLE_1 }, { 'search_type': SEARCH_TYPE_3, 'title': SEARCH_TYPE_TITLE_3 }]
def test_should_reject_search_types_for_emails_not_associated_with_required_role( self, MockFlaskAuth0): _setup_flask_auth0_mock_email(MockFlaskAuth0, email=EMAIL_1) user_has_role_by_email = Mock(name='user_has_role_by_email') user_has_role_by_email.return_value = False api_auth = ApiAuth( dict_to_config({'auth': { 'valid_email_domains': 'other.org' }}), {'auth0_domain': DOMAIN_1}, search_config={SEARCH_TYPE_1: { 'required_role': ROLE_1 }}, user_has_role_by_email=user_has_role_by_email, get_search_type=lambda: SEARCH_TYPE_1) f = _named_mock(name='f') wrapped_f = api_auth.wrap_search(f) assert wrapped_f != f with pytest.raises(Forbidden): wrapped_f() user_has_role_by_email.assert_called_with(email=EMAIL_1, role=ROLE_1)
def test_should_pass_search_params_from_search_config_to_recommend_method( self, MockRecommendReviewers): config = dict_to_config({ SEARCH_SECTION_PREFIX + SEARCH_TYPE_1: { 'filter_by_role': VALUE_1, 'recommend_relationship_types': VALUE_2, 'recommend_stage_names': VALUE_3, 'default_limit': str(LIMIT_1) } }) with _api_test_client(config, {}) as test_client: MockRecommendReviewers.return_value.recommend.return_value = SOME_RESPONSE test_client.get('/recommend-reviewers?' + urlencode({ 'manuscript_no': MANUSCRIPT_NO_1, 'search_type': SEARCH_TYPE_1 })) _assert_partial_called_with( MockRecommendReviewers.return_value.recommend, role=VALUE_1, recommend_relationship_types=[VALUE_2], recommend_stage_names=[VALUE_3], limit=LIMIT_1)
def _get_app_config(self): with patch.object(enrich_data_module, 'get_app_config') as get_app_config_mock: get_app_config_mock.return_value = dict_to_config({}) yield get_app_config_mock
def test_should_not_wrap_with_auth_if_no_auth0_domain_is_present(self): config = dict_to_config({}) client_config = {} api_auth = ApiAuth(config, client_config) f = Mock() assert api_auth.wrap_search(f) == f
def test_should_allow_local_ips_by_default(self, MockFlaskAuth0): ApiAuth(dict_to_config({}), {'auth0_domain': VALUE_1}) _assert_partial_called_with(MockFlaskAuth0, allowed_ips={'127.0.0.1'})
def test_should_fallback_to_model_config(self): config = dict_to_config({'model': {PARAM_KEY_1: PARAM_VALUE_1}}) search_config = parse_search_config(config) assert search_config.keys() == {DEFAULT_SEARCH_TYPE} assert search_config[SEARCH_TYPE_1][PARAM_KEY_1] == PARAM_VALUE_1
def test_should_fallback_to_empty_config_if_no_model_config_is_present( self): config = dict_to_config({}) search_config = parse_search_config(config) assert search_config.keys() == {DEFAULT_SEARCH_TYPE}