From 740357289c79b6ce1d5329f0e190df7f52677965 Mon Sep 17 00:00:00 2001 From: Paul Abumov Date: Tue, 15 Aug 2023 20:29:16 -0400 Subject: [PATCH] Added unittests for prolific_utils and base_api_resource --- .../prolific/api/base_api_resource.py | 5 + .../providers/prolific/api/status.py | 1 + .../providers/prolific/__init__.py | 5 + .../providers/prolific/api/__init__.py | 5 + .../prolific/api/test_base_api_resourse.py | 362 +++++++++++++++ .../providers/prolific/test_prolific_utils.py | 412 +++++++++--------- 6 files changed, 574 insertions(+), 216 deletions(-) create mode 100644 test/abstractions/providers/prolific/api/__init__.py create mode 100644 test/abstractions/providers/prolific/api/test_base_api_resourse.py diff --git a/mephisto/abstractions/providers/prolific/api/base_api_resource.py b/mephisto/abstractions/providers/prolific/api/base_api_resource.py index 85ec0bcde..959144051 100644 --- a/mephisto/abstractions/providers/prolific/api/base_api_resource.py +++ b/mephisto/abstractions/providers/prolific/api/base_api_resource.py @@ -89,6 +89,7 @@ def _base_request( elif method == HTTPMethod.DELETE: response = requests.delete(url, headers=headers, json=params) + else: raise ProlificException("Invalid HTTP method.") @@ -102,6 +103,10 @@ def _base_request( return result + except ProlificException: + # Reraise these errors further to avoid catching them in the latest `except` condition + raise + except requests.exceptions.HTTPError as err: logger.error(f"{log_prefix} Request error: {err}. Response text: `{err.response.text}`") if err.response.status_code == status.HTTP_401_UNAUTHORIZED: diff --git a/mephisto/abstractions/providers/prolific/api/status.py b/mephisto/abstractions/providers/prolific/api/status.py index 12d1156e1..d746c5e23 100644 --- a/mephisto/abstractions/providers/prolific/api/status.py +++ b/mephisto/abstractions/providers/prolific/api/status.py @@ -5,6 +5,7 @@ # LICENSE file in the root directory of this source tree. # 2xx +HTTP_200_OK = 200 HTTP_204_NO_CONTENT = 204 # 4xx diff --git a/test/abstractions/providers/prolific/__init__.py b/test/abstractions/providers/prolific/__init__.py index e69de29bb..240697e32 100644 --- a/test/abstractions/providers/prolific/__init__.py +++ b/test/abstractions/providers/prolific/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# Copyright (c) Facebook, Inc. and its affiliates. +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. diff --git a/test/abstractions/providers/prolific/api/__init__.py b/test/abstractions/providers/prolific/api/__init__.py new file mode 100644 index 000000000..240697e32 --- /dev/null +++ b/test/abstractions/providers/prolific/api/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# Copyright (c) Facebook, Inc. and its affiliates. +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. diff --git a/test/abstractions/providers/prolific/api/test_base_api_resourse.py b/test/abstractions/providers/prolific/api/test_base_api_resourse.py new file mode 100644 index 000000000..164cefadd --- /dev/null +++ b/test/abstractions/providers/prolific/api/test_base_api_resourse.py @@ -0,0 +1,362 @@ +#!/usr/bin/env python3 + +# Copyright (c) Facebook, Inc. and its affiliates. +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import json +import unittest +from unittest.mock import patch +from urllib.parse import urljoin + +import pytest +from requests import Response +from requests.exceptions import HTTPError + +from mephisto.abstractions.providers.prolific.api import status +from mephisto.abstractions.providers.prolific.api.base_api_resource import BaseAPIResource +from mephisto.abstractions.providers.prolific.api.base_api_resource import HTTPMethod +from mephisto.abstractions.providers.prolific.api.exceptions import ProlificAPIKeyError +from mephisto.abstractions.providers.prolific.api.exceptions import ProlificAuthenticationError +from mephisto.abstractions.providers.prolific.api.exceptions import ProlificException +from mephisto.abstractions.providers.prolific.api.exceptions import ProlificRequestError + + +API_KEY_PATH = "mephisto.abstractions.providers.prolific.api.base_api_resource.PROLIFIC_API_KEY" +API_KEY = "test" + + +class TestApiResource(BaseAPIResource): + pass + + +@pytest.mark.prolific +class TestBaseAPIResource(unittest.TestCase): + @patch("requests.get") + def test__base_request_success(self, mock_requests_get, *args): + method = HTTPMethod.GET + api_endpoint = "test/" + params = { + "param": "test", + } + headers = { + "header": "test", + } + content = b'{"id": "60d9aadeb86739de712faee0","name": "Study"}' + + mock_response = Response() + mock_response.raise_for_status = lambda: None + mock_response.status_code = status.HTTP_200_OK + mock_response._content = content + + mock_requests_get.return_value = mock_response + + result = TestApiResource._base_request( + method=method, + api_endpoint=api_endpoint, + params=params, + headers=headers, + api_key=API_KEY, + ) + + self.assertEqual(json.loads(content), result) + mock_requests_get.called_once_with( + urljoin("https://api.prolific.co/api/v1/", api_endpoint), + headers={**headers, **{"Authorization": f"Token {API_KEY}"}}, + params=params, + ) + + @patch("requests.get") + def test__base_request_success_no_content(self, mock_requests_get, *args): + method = HTTPMethod.GET + api_endpoint = "test/" + params = { + "param": "test", + } + headers = { + "header": "test", + } + content = None + + mock_response = Response() + mock_response.raise_for_status = lambda: None + mock_response.status_code = status.HTTP_204_NO_CONTENT + mock_response._content = content + + mock_requests_get.return_value = mock_response + + result = TestApiResource._base_request( + method=method, + api_endpoint=api_endpoint, + params=params, + headers=headers, + api_key=API_KEY, + ) + + self.assertEqual(None, result) + mock_requests_get.called_once_with( + urljoin("https://api.prolific.co/api/v1/", api_endpoint), + headers={**headers, **{"Authorization": f"Token {API_KEY}"}}, + params=params, + ) + + @patch(API_KEY_PATH, "") + @patch("requests.get") + def test__base_request_no_api_key(self, mock_requests_get, *args): + method = HTTPMethod.GET + api_endpoint = "test/" + params = { + "param": "test", + } + headers = { + "header": "test", + } + + with self.assertRaises(ProlificAPIKeyError) as cm: + TestApiResource._base_request( + method=method, + api_endpoint=api_endpoint, + params=params, + headers=headers, + ) + + self.assertEqual(cm.exception.message, ProlificAPIKeyError.default_message) + mock_requests_get.assert_not_called() + + @patch("requests.get") + def test__base_request_incorrect_request_method(self, mock_requests_get, *args): + method = "unreal_method" + api_endpoint = "test/" + params = { + "param": "test", + } + headers = { + "header": "test", + } + + with self.assertRaises(ProlificException) as cm: + TestApiResource._base_request( + method=method, + api_endpoint=api_endpoint, + params=params, + headers=headers, + api_key=API_KEY, + ) + + self.assertEqual(cm.exception.message, "Invalid HTTP method.") + mock_requests_get.assert_not_called() + + @patch("requests.get") + def test__base_request_request_httperror(self, mock_requests_get, *args): + method = HTTPMethod.GET + api_endpoint = "test/" + params = { + "param": "test", + } + headers = { + "header": "test", + } + content = b"test" + + mock_response = Response() + mock_response.raise_for_status = lambda: None + mock_response.status_code = status.HTTP_204_NO_CONTENT + mock_response._content = content + + error_message = "Error" + exception = HTTPError(error_message) + exception.response = mock_response + + mock_requests_get.side_effect = exception + + with self.assertRaises(ProlificRequestError) as cm: + TestApiResource._base_request( + method=method, + api_endpoint=api_endpoint, + params=params, + headers=headers, + api_key=API_KEY, + ) + + self.assertEqual(cm.exception.message, f'{error_message}. {content.decode("utf8")}') + mock_requests_get.called_once_with( + urljoin("https://api.prolific.co/api/v1/", api_endpoint), + headers={**headers, **{"Authorization": f"Token {API_KEY}"}}, + params=params, + ) + + @patch("requests.get") + def test__base_request_request_httperror_unauthorized(self, mock_requests_get, *args): + method = HTTPMethod.GET + api_endpoint = "test/" + params = { + "param": "test", + } + headers = { + "header": "test", + } + content = b"test" + + mock_response = Response() + mock_response.raise_for_status = lambda: None + mock_response.status_code = status.HTTP_401_UNAUTHORIZED + mock_response._content = content + + error_message = "Error" + exception = HTTPError(error_message) + exception.response = mock_response + + mock_requests_get.side_effect = exception + + with self.assertRaises(ProlificAuthenticationError) as cm: + TestApiResource._base_request( + method=method, + api_endpoint=api_endpoint, + params=params, + headers=headers, + api_key=API_KEY, + ) + + self.assertEqual(cm.exception.message, ProlificAuthenticationError.default_message) + self.assertEqual(cm.exception.status_code, ProlificAuthenticationError.status_code) + mock_requests_get.called_once_with( + urljoin("https://api.prolific.co/api/v1/", api_endpoint), + headers={**headers, **{"Authorization": f"Token {API_KEY}"}}, + params=params, + ) + + @patch("requests.get") + def test__base_request_unexpected_exception(self, mock_requests_get, *args): + method = HTTPMethod.GET + api_endpoint = "test/" + params = { + "param": "test", + } + headers = { + "header": "test", + } + + error_message = "Error" + exception = ValueError(error_message) + + mock_requests_get.side_effect = exception + + with self.assertRaises(ProlificException) as cm: + TestApiResource._base_request( + method=method, + api_endpoint=api_endpoint, + params=params, + headers=headers, + api_key=API_KEY, + ) + + self.assertEqual(cm.exception.message, ProlificException.default_message) + mock_requests_get.called_once_with( + urljoin("https://api.prolific.co/api/v1/", api_endpoint), + headers={**headers, **{"Authorization": f"Token {API_KEY}"}}, + params=params, + ) + + @patch(API_KEY_PATH, API_KEY) + @patch("requests.get") + def test_get(self, mock_requests_get, *args): + api_endpoint = "test-get/" + params = { + "param": "test", + } + content = b'{"id": "60d9aadeb86739de712faee0","name": "Study"}' + + mock_response = Response() + mock_response.raise_for_status = lambda: None + mock_response.status_code = status.HTTP_200_OK + mock_response._content = content + + mock_requests_get.return_value = mock_response + + result = TestApiResource.get(api_endpoint=api_endpoint, params=params) + + self.assertEqual(json.loads(content), result) + mock_requests_get.called_once_with( + urljoin("https://api.prolific.co/api/v1/", api_endpoint), + headers={"Authorization": f"Token {API_KEY}"}, + params=params, + ) + + @patch(API_KEY_PATH, API_KEY) + @patch("requests.post") + def test_post(self, mock_requests_post, *args): + api_endpoint = "test-post/" + params = { + "param": "test", + } + content = b'{"id": "60d9aadeb86739de712faee0","name": "Study"}' + + mock_response = Response() + mock_response.raise_for_status = lambda: None + mock_response.status_code = status.HTTP_200_OK + mock_response._content = content + + mock_requests_post.return_value = mock_response + + result = TestApiResource.post(api_endpoint=api_endpoint, params=params) + + self.assertEqual(json.loads(content), result) + mock_requests_post.called_once_with( + urljoin("https://api.prolific.co/api/v1/", api_endpoint), + headers={"Authorization": f"Token {API_KEY}"}, + params=params, + ) + + @patch(API_KEY_PATH, API_KEY) + @patch("requests.patch") + def test_patch(self, mock_requests_patch, *args): + api_endpoint = "test-patch/" + params = { + "param": "test", + } + content = b'{"id": "60d9aadeb86739de712faee0","name": "Study"}' + + mock_response = Response() + mock_response.raise_for_status = lambda: None + mock_response.status_code = status.HTTP_200_OK + mock_response._content = content + + mock_requests_patch.return_value = mock_response + + result = TestApiResource.patch(api_endpoint=api_endpoint, params=params) + + self.assertEqual(json.loads(content), result) + mock_requests_patch.called_once_with( + urljoin("https://api.prolific.co/api/v1/", api_endpoint), + headers={"Authorization": f"Token {API_KEY}"}, + params=params, + ) + + @patch(API_KEY_PATH, API_KEY) + @patch("requests.delete") + def test_delete(self, mock_requests_delete, *args): + api_endpoint = "test-delete/" + params = { + "param": "test", + } + content = b'{"id": "60d9aadeb86739de712faee0","name": "Study"}' + + mock_response = Response() + mock_response.raise_for_status = lambda: None + mock_response.status_code = status.HTTP_200_OK + mock_response._content = content + + mock_requests_delete.return_value = mock_response + + result = TestApiResource.delete(api_endpoint=api_endpoint, params=params) + + self.assertEqual(json.loads(content), result) + mock_requests_delete.called_once_with( + urljoin("https://api.prolific.co/api/v1/", api_endpoint), + headers={"Authorization": f"Token {API_KEY}"}, + params=params, + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/abstractions/providers/prolific/test_prolific_utils.py b/test/abstractions/providers/prolific/test_prolific_utils.py index 1650019e7..da8d8881c 100644 --- a/test/abstractions/providers/prolific/test_prolific_utils.py +++ b/test/abstractions/providers/prolific/test_prolific_utils.py @@ -959,83 +959,71 @@ def test_is_study_expired(self, *args): self.assertFalse(result_just_with_awaiting_review_status) self.assertTrue(result_with_completed_status_and_internal_name) - @patch( - 'mephisto.abstractions.providers.prolific.api.' - 'participant_groups.ParticipantGroups.add_participants_to_group' - ) + @patch(f"{API_PATH}.participant_groups.ParticipantGroups.add_participants_to_group") def test_add_workers_to_qualification_success(self, *args): - worker_ids = ['test', 'test2'] - participant_group_id = 'test3' + worker_ids = ["test", "test2"] + participant_group_id = "test3" result = add_workers_to_qualification(self.client, worker_ids, participant_group_id) self.assertIsNone(result) - @patch( - 'mephisto.abstractions.providers.prolific.api.' - 'participant_groups.ParticipantGroups.add_participants_to_group' - ) + @patch(f"{API_PATH}.participant_groups.ParticipantGroups.add_participants_to_group") def test_add_workers_to_qualification_exception(self, mock_add_participants_to_group, *args): - worker_ids = ['test', 'test2'] - participant_group_id = 'test3' + worker_ids = ["test", "test2"] + participant_group_id = "test3" - exception_message = 'Error' + exception_message = "Error" mock_add_participants_to_group.side_effect = ProlificRequestError(exception_message) with self.assertRaises(ProlificRequestError) as cm: add_workers_to_qualification(self.client, worker_ids, participant_group_id) self.assertEqual(cm.exception.message, exception_message) - @patch( - 'mephisto.abstractions.providers.prolific.api.' - 'participant_groups.ParticipantGroups.add_participants_to_group' - ) + @patch(f"{API_PATH}.participant_groups.ParticipantGroups.add_participants_to_group") def test_give_worker_qualification_success(self, mock_add_participants_to_group, *args): - worker_id = 'test' - participant_group_id = 'test3' + worker_id = "test" + participant_group_id = "test3" result = give_worker_qualification(self.client, worker_id, participant_group_id) mock_add_participants_to_group.assert_called_once_with( - id=participant_group_id, participant_ids=[worker_id], + id=participant_group_id, + participant_ids=[worker_id], ) self.assertIsNone(result) - @patch( - 'mephisto.abstractions.providers.prolific.api.' - 'participant_groups.ParticipantGroups.remove_participants_from_group' - ) + @patch(f"{API_PATH}.participant_groups.ParticipantGroups.remove_participants_from_group") def test_remove_worker_qualification_success(self, *args): - worker_id = 'test' - participant_group_id = 'test2' + worker_id = "test" + participant_group_id = "test2" result = remove_worker_qualification(self.client, worker_id, participant_group_id) self.assertIsNone(result) - @patch( - 'mephisto.abstractions.providers.prolific.api.' - 'participant_groups.ParticipantGroups.remove_participants_from_group' - ) + @patch(f"{API_PATH}.participant_groups.ParticipantGroups.remove_participants_from_group") def test_remove_worker_qualification_exception( - self, mock_remove_participants_from_group, *args, + self, + mock_remove_participants_from_group, + *args, ): - worker_id = 'test' - participant_group_id = 'test2' + worker_id = "test" + participant_group_id = "test2" - exception_message = 'Error' + exception_message = "Error" mock_remove_participants_from_group.side_effect = ProlificRequestError(exception_message) with self.assertRaises(ProlificRequestError) as cm: remove_worker_qualification(self.client, worker_id, participant_group_id) self.assertEqual(cm.exception.message, exception_message) - @patch('mephisto.abstractions.providers.prolific.api.bonuses.Bonuses.pay') - @patch('mephisto.abstractions.providers.prolific.api.bonuses.Bonuses.set_up') - @patch('mephisto.abstractions.providers.prolific.prolific_utils.check_balance') + @patch(f"{API_PATH}.bonuses.Bonuses.pay") + @patch(f"{API_PATH}.bonuses.Bonuses.set_up") + @patch(f"{UTILS_PATH}.check_balance") def test_pay_bonus_empty_balance(self, mock_check_balance, mock_set_up, mock_pay, *args): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" bonus_amount = 1000 mock_check_balance.return_value = False @@ -1046,12 +1034,12 @@ def test_pay_bonus_empty_balance(self, mock_check_balance, mock_set_up, mock_pay mock_pay.assert_not_called() self.assertFalse(result) - @patch('mephisto.abstractions.providers.prolific.api.bonuses.Bonuses.pay') - @patch('mephisto.abstractions.providers.prolific.api.bonuses.Bonuses.set_up') - @patch('mephisto.abstractions.providers.prolific.prolific_utils.check_balance') + @patch(f"{API_PATH}.bonuses.Bonuses.pay") + @patch(f"{API_PATH}.bonuses.Bonuses.set_up") + @patch(f"{UTILS_PATH}.check_balance") def test_pay_bonus_empty_balance(self, mock_check_balance, mock_set_up, mock_pay, *args): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" bonus_amount = 1000 mock_check_balance.return_value = False @@ -1062,13 +1050,13 @@ def test_pay_bonus_empty_balance(self, mock_check_balance, mock_set_up, mock_pay mock_pay.assert_not_called() self.assertFalse(result) - @patch('mephisto.abstractions.providers.prolific.api.bonuses.Bonuses.pay') - @patch('mephisto.abstractions.providers.prolific.api.bonuses.Bonuses.set_up') - @patch('mephisto.abstractions.providers.prolific.prolific_utils.check_balance') + @patch(f"{API_PATH}.bonuses.Bonuses.pay") + @patch(f"{API_PATH}.bonuses.Bonuses.set_up") + @patch(f"{UTILS_PATH}.check_balance") def test_pay_bonus_success(self, mock_check_balance, mock_set_up, mock_pay, *args): - worker_id = 'test' - study_id = 'test2' - bonus_payments_id = 'test3' + worker_id = "test" + study_id = "test2" + bonus_payments_id = "test3" bonus_amount = 1000 mock_bonus_payments = BonusPayments() @@ -1078,36 +1066,36 @@ def test_pay_bonus_success(self, mock_check_balance, mock_set_up, mock_pay, *arg result = pay_bonus(self.client, mock_task_run_args, worker_id, bonus_amount, study_id) - mock_set_up.assert_called_once_with(study_id, f'{worker_id},{bonus_amount / 100}') + mock_set_up.assert_called_once_with(study_id, f"{worker_id},{bonus_amount / 100}") mock_pay.assert_called_once_with(mock_bonus_payments.id) self.assertTrue(result) - @patch('mephisto.abstractions.providers.prolific.api.bonuses.Bonuses.pay') - @patch('mephisto.abstractions.providers.prolific.api.bonuses.Bonuses.set_up') - @patch('mephisto.abstractions.providers.prolific.prolific_utils.check_balance') + @patch(f"{API_PATH}.bonuses.Bonuses.pay") + @patch(f"{API_PATH}.bonuses.Bonuses.set_up") + @patch(f"{UTILS_PATH}.check_balance") def test_pay_bonus_set_up_exception(self, mock_check_balance, mock_set_up, mock_pay, *args): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" bonus_amount = 1000 mock_check_balance.return_value = True - exception_message = 'Error' + exception_message = "Error" mock_set_up.side_effect = ProlificRequestError(exception_message) with self.assertRaises(ProlificRequestError) as cm: pay_bonus(self.client, mock_task_run_args, worker_id, bonus_amount, study_id) self.assertEqual(cm.exception.message, exception_message) - mock_set_up.assert_called_once_with(study_id, f'{worker_id},{bonus_amount / 100}') + mock_set_up.assert_called_once_with(study_id, f"{worker_id},{bonus_amount / 100}") mock_pay.assert_not_called() - @patch('mephisto.abstractions.providers.prolific.api.bonuses.Bonuses.pay') - @patch('mephisto.abstractions.providers.prolific.api.bonuses.Bonuses.set_up') - @patch('mephisto.abstractions.providers.prolific.prolific_utils.check_balance') + @patch(f"{API_PATH}.bonuses.Bonuses.pay") + @patch(f"{API_PATH}.bonuses.Bonuses.set_up") + @patch(f"{UTILS_PATH}.check_balance") def test_pay_bonus_pay_exception(self, mock_check_balance, mock_set_up, mock_pay, *args): - worker_id = 'test' - study_id = 'test2' - bonus_payments_id = 'test3' + worker_id = "test" + study_id = "test2" + bonus_payments_id = "test3" bonus_amount = 1000 mock_bonus_payments = BonusPayments() @@ -1115,22 +1103,18 @@ def test_pay_bonus_pay_exception(self, mock_check_balance, mock_set_up, mock_pay mock_check_balance.return_value = True mock_set_up.return_value = mock_bonus_payments - exception_message = 'Error' + exception_message = "Error" mock_pay.side_effect = ProlificRequestError(exception_message) with self.assertRaises(ProlificRequestError) as cm: pay_bonus(self.client, mock_task_run_args, worker_id, bonus_amount, study_id) self.assertEqual(cm.exception.message, exception_message) - mock_set_up.assert_called_once_with(study_id, f'{worker_id},{bonus_amount / 100}') + mock_set_up.assert_called_once_with(study_id, f"{worker_id},{bonus_amount / 100}") mock_pay.assert_called_once_with(mock_bonus_payments.id) - @patch('mephisto.abstractions.providers.prolific.prolific_utils.find_or_create_qualification') - @patch( - 'mephisto.abstractions.providers.prolific.prolific_utils.find_or_create_prolific_project' - ) - @patch( - 'mephisto.abstractions.providers.prolific.prolific_utils.find_or_create_prolific_workspace' - ) + @patch(f"{UTILS_PATH}.find_or_create_qualification") + @patch(f"{UTILS_PATH}.find_or_create_prolific_project") + @patch(f"{UTILS_PATH}.find_or_create_prolific_workspace") def test__get_block_list_qualification( self, mock_find_or_create_prolific_workspace, @@ -1139,13 +1123,13 @@ def test__get_block_list_qualification( *args, ): mock_workspace = Workspace() - mock_workspace.id = 'test' + mock_workspace.id = "test" mock_project = Project() - mock_project.id = 'test2' - mock_project.title = 'test2_title' + mock_project.id = "test2" + mock_project.title = "test2_title" mock_participant_group = ParticipantGroup() - mock_participant_group.id = 'test3' - mock_participant_group.name = 'test3_name' + mock_participant_group.id = "test3" + mock_participant_group.name = "test3_name" mock_find_or_create_prolific_workspace.return_value = mock_workspace mock_find_or_create_prolific_project.return_value = mock_project @@ -1155,15 +1139,18 @@ def test__get_block_list_qualification( self.assertEqual(mock_participant_group, result) - @patch('mephisto.abstractions.providers.prolific.prolific_utils.add_workers_to_qualification') - @patch('mephisto.abstractions.providers.prolific.prolific_utils._get_block_list_qualification') + @patch(f"{UTILS_PATH}.add_workers_to_qualification") + @patch(f"{UTILS_PATH}._get_block_list_qualification") def test_block_worker_success( - self, mock__get_block_list_qualification, mock_add_workers_to_qualification, *args, + self, + mock__get_block_list_qualification, + mock_add_workers_to_qualification, + *args, ): - worker_id = 'test' + worker_id = "test" mock_participant_group = ParticipantGroup() - mock_participant_group.id = 'test2' + mock_participant_group.id = "test2" mock__get_block_list_qualification.return_value = mock_participant_group @@ -1171,21 +1158,23 @@ def test_block_worker_success( self.assertIsNone(result) mock_add_workers_to_qualification.called_once_with( - self.client, workers_ids=[worker_id], qualification_id=mock_participant_group.id, + self.client, + workers_ids=[worker_id], + qualification_id=mock_participant_group.id, ) - @patch( - 'mephisto.abstractions.providers.prolific.api.' - 'participant_groups.ParticipantGroups.remove_participants_from_group' - ) - @patch('mephisto.abstractions.providers.prolific.prolific_utils._get_block_list_qualification') + @patch(f"{API_PATH}.participant_groups.ParticipantGroups.remove_participants_from_group") + @patch(f"{UTILS_PATH}._get_block_list_qualification") def test_unblock_worker_success( - self, mock__get_block_list_qualification, mock_remove_participants_from_group, *args, + self, + mock__get_block_list_qualification, + mock_remove_participants_from_group, + *args, ): - worker_id = 'test' + worker_id = "test" mock_participant_group = ParticipantGroup() - mock_participant_group.id = 'test2' + mock_participant_group.id = "test2" mock__get_block_list_qualification.return_value = mock_participant_group @@ -1193,24 +1182,21 @@ def test_unblock_worker_success( self.assertIsNone(result) mock_remove_participants_from_group.called_once_with( - id=mock_participant_group.id, participant_ids=[worker_id], + id=mock_participant_group.id, + participant_ids=[worker_id], ) - @patch( - 'mephisto.abstractions.providers.prolific.prolific_utils.find_or_create_prolific_project' - ) - @patch( - 'mephisto.abstractions.providers.prolific.prolific_utils.find_or_create_prolific_workspace' - ) - @patch( - 'mephisto.abstractions.providers.prolific.api.' - 'participant_groups.ParticipantGroups.list_participants_for_group' - ) - @patch('mephisto.abstractions.providers.prolific.prolific_utils._find_qualification') + @patch(f"{UTILS_PATH}.find_or_create_prolific_project") + @patch(f"{UTILS_PATH}.find_or_create_prolific_workspace") + @patch(f"{API_PATH}.participant_groups.ParticipantGroups.list_participants_for_group") + @patch(f"{UTILS_PATH}._find_qualification") def test_is_worker_blocked_no_block_list_qualification( - self, mock__find_qualification, mock_list_participants_for_group, *args, + self, + mock__find_qualification, + mock_list_participants_for_group, + *args, ): - worker_id = 'test' + worker_id = "test" mock__find_qualification.return_value = (False, None) @@ -1219,24 +1205,20 @@ def test_is_worker_blocked_no_block_list_qualification( self.assertFalse(result) mock_list_participants_for_group.assert_not_called() - @patch( - 'mephisto.abstractions.providers.prolific.prolific_utils.find_or_create_prolific_project' - ) - @patch( - 'mephisto.abstractions.providers.prolific.prolific_utils.find_or_create_prolific_workspace' - ) - @patch( - 'mephisto.abstractions.providers.prolific.api.' - 'participant_groups.ParticipantGroups.list_participants_for_group' - ) - @patch('mephisto.abstractions.providers.prolific.prolific_utils._find_qualification') + @patch(f"{UTILS_PATH}.find_or_create_prolific_project") + @patch(f"{UTILS_PATH}.find_or_create_prolific_workspace") + @patch(f"{API_PATH}.participant_groups.ParticipantGroups.list_participants_for_group") + @patch(f"{UTILS_PATH}._find_qualification") def test_is_worker_blocked_success_true( - self, mock__find_qualification, mock_list_participants_for_group, *args, + self, + mock__find_qualification, + mock_list_participants_for_group, + *args, ): - worker_id = 'test' + worker_id = "test" mock_participant_group = ParticipantGroup() - mock_participant_group.id = 'test2' + mock_participant_group.id = "test2" mock_participant = Participant() mock_participant.participant_id = worker_id @@ -1248,26 +1230,22 @@ def test_is_worker_blocked_success_true( self.assertTrue(result) mock_list_participants_for_group.assert_called_once() - @patch( - 'mephisto.abstractions.providers.prolific.prolific_utils.find_or_create_prolific_project' - ) - @patch( - 'mephisto.abstractions.providers.prolific.prolific_utils.find_or_create_prolific_workspace' - ) - @patch( - 'mephisto.abstractions.providers.prolific.api.' - 'participant_groups.ParticipantGroups.list_participants_for_group' - ) - @patch('mephisto.abstractions.providers.prolific.prolific_utils._find_qualification') + @patch(f"{UTILS_PATH}.find_or_create_prolific_project") + @patch(f"{UTILS_PATH}.find_or_create_prolific_workspace") + @patch(f"{API_PATH}.participant_groups.ParticipantGroups.list_participants_for_group") + @patch(f"{UTILS_PATH}._find_qualification") def test_is_worker_blocked_success_false( - self, mock__find_qualification, mock_list_participants_for_group, *args, + self, + mock__find_qualification, + mock_list_participants_for_group, + *args, ): - worker_id = 'test' + worker_id = "test" mock_participant_group = ParticipantGroup() - mock_participant_group.id = 'test2' + mock_participant_group.id = "test2" mock_participant = Participant() - mock_participant.participant_id = 'test3' + mock_participant.participant_id = "test3" mock__find_qualification.return_value = (True, mock_participant_group) mock_list_participants_for_group.return_value = [mock_participant] @@ -1277,30 +1255,26 @@ def test_is_worker_blocked_success_false( self.assertFalse(result) mock_list_participants_for_group.assert_called_once() - @patch( - 'mephisto.abstractions.providers.prolific.prolific_utils.find_or_create_prolific_project' - ) - @patch( - 'mephisto.abstractions.providers.prolific.prolific_utils.find_or_create_prolific_workspace' - ) - @patch( - 'mephisto.abstractions.providers.prolific.api.' - 'participant_groups.ParticipantGroups.list_participants_for_group' - ) - @patch('mephisto.abstractions.providers.prolific.prolific_utils._find_qualification') + @patch(f"{UTILS_PATH}.find_or_create_prolific_project") + @patch(f"{UTILS_PATH}.find_or_create_prolific_workspace") + @patch(f"{API_PATH}.participant_groups.ParticipantGroups.list_participants_for_group") + @patch(f"{UTILS_PATH}._find_qualification") def test_is_worker_blocked_exception( - self, mock__find_qualification, mock_list_participants_for_group, *args, + self, + mock__find_qualification, + mock_list_participants_for_group, + *args, ): - worker_id = 'test' + worker_id = "test" mock_participant_group = ParticipantGroup() - mock_participant_group.id = 'test2' + mock_participant_group.id = "test2" mock_participant = Participant() mock_participant.participant_id = worker_id mock__find_qualification.return_value = (True, mock_participant_group) - exception_message = 'Error' + exception_message = "Error" mock_list_participants_for_group.side_effect = ProlificRequestError(exception_message) with self.assertRaises(ProlificRequestError) as cm: is_worker_blocked(self.client, mock_task_run_args, worker_id) @@ -1308,7 +1282,7 @@ def test_is_worker_blocked_exception( self.assertEqual(cm.exception.message, exception_message) mock_list_participants_for_group.assert_called_once() - @patch('mephisto.abstractions.providers.prolific.api.studies.Studies.calculate_cost') + @patch(f"{API_PATH}.studies.Studies.calculate_cost") def test_calculate_pay_amount_success(self, mock_calculate_cost, *args): task_amount = 1000 total_available_places = 2 @@ -1319,25 +1293,25 @@ def test_calculate_pay_amount_success(self, mock_calculate_cost, *args): self.assertEqual(task_amount * total_available_places, result) - @patch('mephisto.abstractions.providers.prolific.api.studies.Studies.calculate_cost') + @patch(f"{API_PATH}.studies.Studies.calculate_cost") def test_calculate_pay_amount_exception(self, mock_calculate_cost, *args): task_amount = 1000 total_available_places = 2 - exception_message = 'Error' + exception_message = "Error" mock_calculate_cost.side_effect = ProlificRequestError(exception_message) with self.assertRaises(ProlificRequestError) as cm: calculate_pay_amount(self.client, task_amount, total_available_places) self.assertEqual(cm.exception.message, exception_message) - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.list') + @patch(f"{API_PATH}.submissions.Submissions.list") def test__find_submission_success_found(self, mock_list, *args): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" mock_list_submission = ListSubmission() - mock_list_submission.id = 'test3' + mock_list_submission.id = "test3" mock_list_submission.participant_id = worker_id mock_list.return_value = [mock_list_submission] @@ -1346,14 +1320,14 @@ def test__find_submission_success_found(self, mock_list, *args): self.assertEqual(mock_list_submission, result) - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.list') + @patch(f"{API_PATH}.submissions.Submissions.list") def test__find_submission_success_not_found(self, mock_list, *args): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" mock_list_submission = ListSubmission() - mock_list_submission.id = 'test3' - mock_list_submission.participant_id = 'test4' + mock_list_submission.id = "test3" + mock_list_submission.participant_id = "test4" mock_list.return_value = [mock_list_submission] @@ -1361,24 +1335,24 @@ def test__find_submission_success_not_found(self, mock_list, *args): self.assertEqual(None, result) - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.list') + @patch(f"{API_PATH}.submissions.Submissions.list") def test__find_submission_exception(self, mock_list, *args): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" - exception_message = 'Error' + exception_message = "Error" mock_list.side_effect = ProlificRequestError(exception_message) with self.assertRaises(ProlificRequestError) as cm: _find_submission(self.client, study_id, worker_id) self.assertEqual(cm.exception.message, exception_message) - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.retrieve') + @patch(f"{API_PATH}.submissions.Submissions.retrieve") def test_get_submission_success(self, mock_retrieve, *args): - submission_id = 'test' + submission_id = "test" mock_submission = Submission() - mock_submission.id = 'test2' + mock_submission.id = "test2" mock_retrieve.return_value = mock_submission @@ -1386,22 +1360,22 @@ def test_get_submission_success(self, mock_retrieve, *args): self.assertEqual(mock_submission, result) - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.retrieve') + @patch(f"{API_PATH}.submissions.Submissions.retrieve") def test_get_submission_exception(self, mock_retrieve, *args): - submission_id = 'test' + submission_id = "test" - exception_message = 'Error' + exception_message = "Error" mock_retrieve.side_effect = ProlificRequestError(exception_message) with self.assertRaises(ProlificRequestError) as cm: get_submission(self.client, submission_id) self.assertEqual(cm.exception.message, exception_message) - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.approve') - @patch('mephisto.abstractions.providers.prolific.prolific_utils._find_submission') + @patch(f"{API_PATH}.submissions.Submissions.approve") + @patch(f"{UTILS_PATH}._find_submission") def test_approve_work_submission_not_found(self, mock__find_submission, mock_approve, *args): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" mock__find_submission.return_value = False @@ -1410,18 +1384,18 @@ def test_approve_work_submission_not_found(self, mock__find_submission, mock_app self.assertIsNone(result) mock_approve.assert_not_called() - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.approve') - @patch('mephisto.abstractions.providers.prolific.prolific_utils._find_submission') + @patch(f"{API_PATH}.submissions.Submissions.approve") + @patch(f"{UTILS_PATH}._find_submission") def test_approve_work_success(self, mock__find_submission, mock_approve, *args): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" mock_submission = Submission() - mock_submission.id = 'test3' + mock_submission.id = "test3" mock_submission.status = constants.SubmissionStatus.AWAITING_REVIEW mock_submission_approved = Submission() - mock_submission_approved.id = 'test4' + mock_submission_approved.id = "test4" mock_submission_approved.status = constants.SubmissionStatus.APPROVED mock__find_submission.return_value = mock_submission @@ -1432,16 +1406,19 @@ def test_approve_work_success(self, mock__find_submission, mock_approve, *args): self.assertEqual(mock_submission_approved, result) mock_approve.assert_called_once() - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.approve') - @patch('mephisto.abstractions.providers.prolific.prolific_utils._find_submission') + @patch(f"{API_PATH}.submissions.Submissions.approve") + @patch(f"{UTILS_PATH}._find_submission") def test_approve_work_incorrect_submission_status( - self, mock__find_submission, mock_approve, *args, + self, + mock__find_submission, + mock_approve, + *args, ): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" mock_submission = Submission() - mock_submission.id = 'test3' + mock_submission.id = "test3" mock_submission.status = constants.SubmissionStatus.ACTIVE mock__find_submission.return_value = mock_submission @@ -1451,30 +1428,30 @@ def test_approve_work_incorrect_submission_status( self.assertIsNone(result) mock_approve.assert_not_called() - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.approve') - @patch('mephisto.abstractions.providers.prolific.prolific_utils._find_submission') + @patch(f"{API_PATH}.submissions.Submissions.approve") + @patch(f"{UTILS_PATH}._find_submission") def test_approve_work_exception(self, mock__find_submission, mock_approve, *args): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" mock_submission = Submission() - mock_submission.id = 'test3' + mock_submission.id = "test3" mock_submission.status = constants.SubmissionStatus.AWAITING_REVIEW mock__find_submission.return_value = mock_submission - exception_message = 'Error' + exception_message = "Error" mock_approve.side_effect = ProlificRequestError(exception_message) with self.assertRaises(ProlificRequestError) as cm: approve_work(self.client, study_id, worker_id) self.assertEqual(cm.exception.message, exception_message) - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.reject') - @patch('mephisto.abstractions.providers.prolific.prolific_utils._find_submission') + @patch(f"{API_PATH}.submissions.Submissions.reject") + @patch(f"{UTILS_PATH}._find_submission") def test_reject_work_submission_not_found(self, mock__find_submission, mock_reject, *args): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" mock__find_submission.return_value = False @@ -1483,18 +1460,18 @@ def test_reject_work_submission_not_found(self, mock__find_submission, mock_reje self.assertIsNone(result) mock_reject.assert_not_called() - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.reject') - @patch('mephisto.abstractions.providers.prolific.prolific_utils._find_submission') + @patch(f"{API_PATH}.submissions.Submissions.reject") + @patch(f"{UTILS_PATH}._find_submission") def test_reject_work_success(self, mock__find_submission, mock_reject, *args): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" mock_submission = Submission() - mock_submission.id = 'test3' + mock_submission.id = "test3" mock_submission.status = constants.SubmissionStatus.AWAITING_REVIEW mock_submission_rejected = Submission() - mock_submission_rejected.id = 'test4' + mock_submission_rejected.id = "test4" mock_submission_rejected.status = constants.SubmissionStatus.REJECTED mock__find_submission.return_value = mock_submission @@ -1505,16 +1482,19 @@ def test_reject_work_success(self, mock__find_submission, mock_reject, *args): self.assertEqual(mock_submission_rejected, result) mock_reject.assert_called_once() - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.reject') - @patch('mephisto.abstractions.providers.prolific.prolific_utils._find_submission') + @patch(f"{API_PATH}.submissions.Submissions.reject") + @patch(f"{UTILS_PATH}._find_submission") def test_reject_work_incorrect_submission_status( - self, mock__find_submission, mock_reject, *args, + self, + mock__find_submission, + mock_reject, + *args, ): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" mock_submission = Submission() - mock_submission.id = 'test3' + mock_submission.id = "test3" mock_submission.status = constants.SubmissionStatus.ACTIVE mock__find_submission.return_value = mock_submission @@ -1524,19 +1504,19 @@ def test_reject_work_incorrect_submission_status( self.assertIsNone(result) mock_reject.assert_not_called() - @patch('mephisto.abstractions.providers.prolific.api.submissions.Submissions.reject') - @patch('mephisto.abstractions.providers.prolific.prolific_utils._find_submission') + @patch(f"{API_PATH}.submissions.Submissions.reject") + @patch(f"{UTILS_PATH}._find_submission") def test_reject_work_exception(self, mock__find_submission, mock_reject, *args): - worker_id = 'test' - study_id = 'test2' + worker_id = "test" + study_id = "test2" mock_submission = Submission() - mock_submission.id = 'test3' + mock_submission.id = "test3" mock_submission.status = constants.SubmissionStatus.AWAITING_REVIEW mock__find_submission.return_value = mock_submission - exception_message = 'Error' + exception_message = "Error" mock_reject.side_effect = ProlificRequestError(exception_message) with self.assertRaises(ProlificRequestError) as cm: reject_work(self.client, study_id, worker_id)