diff --git a/.gitignore b/.gitignore index 49c1170..4ff761c 100644 --- a/.gitignore +++ b/.gitignore @@ -89,3 +89,4 @@ credentials.json VERSION.txt git_push.sh +setup.local.cfg diff --git a/openfga_sdk/client/client.py b/openfga_sdk/client/client.py index e271037..861940d 100644 --- a/openfga_sdk/client/client.py +++ b/openfga_sdk/client/client.py @@ -34,7 +34,11 @@ construct_write_single_response, ) from openfga_sdk.client.models.write_transaction_opts import WriteTransactionOpts -from openfga_sdk.exceptions import FgaValidationException +from openfga_sdk.exceptions import ( + AuthenticationError, + FgaValidationException, + UnauthorizedException, +) from openfga_sdk.models.assertion import Assertion from openfga_sdk.models.check_request import CheckRequest from openfga_sdk.models.contextual_tuple_keys import ContextualTupleKeys @@ -178,16 +182,6 @@ def get_authorization_model_id(self): """ return self._client_configuration.authorization_model_id - async def _check_valid_api_connection(self, options: dict[str, int | str]): - """ - Checks that a connection with the given configuration can be established - """ - authorization_model_id = self._get_authorization_model_id(options) - if authorization_model_id is not None and authorization_model_id != "": - await self.read_authorization_model(options) - else: - await self.read_latest_authorization_model(options) - ################# # Stores ################# @@ -412,6 +406,8 @@ async def _write_single_batch( ClientWriteRequest(writes=write_batch, deletes=delete_batch), options ) return [construct_write_single_response(i, True, None) for i in batch] + except (AuthenticationError, UnauthorizedException) as err: + raise err except Exception as err: return [construct_write_single_response(i, False, err) for i in batch] @@ -496,8 +492,6 @@ async def write(self, body: ClientWriteRequest, options: dict[str, str] = None): options = set_heading_if_not_set( options, CLIENT_BULK_REQUEST_ID_HEADER, str(uuid.uuid4()) ) - # TODO: this should be run in parallel - await self._check_valid_api_connection(options) # otherwise, it is not a transaction and it is a batch write requests writes_response = None @@ -595,6 +589,8 @@ async def _single_batch_check( response=api_response, error=None, ) + except (AuthenticationError, UnauthorizedException) as err: + raise err except Exception as err: return BatchCheckResponse( allowed=False, request=body, response=None, error=err @@ -620,9 +616,6 @@ async def batch_check( options, CLIENT_BULK_REQUEST_ID_HEADER, str(uuid.uuid4()) ) - # TODO: this should be run in parallel - await self._check_valid_api_connection(options) - max_parallel_requests = 10 if options is not None and "max_parallel_requests" in options: max_parallel_requests = options["max_parallel_requests"] diff --git a/openfga_sdk/sync/client/client.py b/openfga_sdk/sync/client/client.py index 17605b7..e4de694 100644 --- a/openfga_sdk/sync/client/client.py +++ b/openfga_sdk/sync/client/client.py @@ -32,7 +32,11 @@ construct_write_single_response, ) from openfga_sdk.client.models.write_transaction_opts import WriteTransactionOpts -from openfga_sdk.exceptions import FgaValidationException +from openfga_sdk.exceptions import ( + AuthenticationError, + FgaValidationException, + UnauthorizedException, +) from openfga_sdk.models.assertion import Assertion from openfga_sdk.models.check_request import CheckRequest from openfga_sdk.models.contextual_tuple_keys import ContextualTupleKeys @@ -178,16 +182,6 @@ def get_authorization_model_id(self): """ return self._client_configuration.authorization_model_id - def _check_valid_api_connection(self, options: dict[str, int | str]): - """ - Checks that a connection with the given configuration can be established - """ - authorization_model_id = self._get_authorization_model_id(options) - if authorization_model_id is not None and authorization_model_id != "": - self.read_authorization_model(options) - else: - self.read_latest_authorization_model(options) - ################# # Stores ################# @@ -410,6 +404,8 @@ def _write_single_batch( ClientWriteRequest(writes=write_batch, deletes=delete_batch), options ) return [construct_write_single_response(i, True, None) for i in batch] + except (AuthenticationError, UnauthorizedException) as err: + raise err except Exception as err: return [construct_write_single_response(i, False, err) for i in batch] @@ -493,8 +489,6 @@ def write(self, body: ClientWriteRequest, options: dict[str, str] = None): options = set_heading_if_not_set( options, CLIENT_BULK_REQUEST_ID_HEADER, str(uuid.uuid4()) ) - # TODO: this should be run in parallel - self._check_valid_api_connection(options) # otherwise, it is not a transaction and it is a batch write requests writes_response = None @@ -584,6 +578,8 @@ def _single_batch_check( response=api_response, error=None, ) + except (AuthenticationError, UnauthorizedException) as err: + raise err except Exception as err: return BatchCheckResponse( allowed=False, request=body, response=None, error=err @@ -607,9 +603,6 @@ def batch_check( options, CLIENT_BULK_REQUEST_ID_HEADER, str(uuid.uuid4()) ) - # TODO: this should be run in parallel - self._check_valid_api_connection(options) - max_parallel_requests = 10 if options is not None and "max_parallel_requests" in options: max_parallel_requests = options["max_parallel_requests"] diff --git a/test/test_client.py b/test/test_client.py index 9834954..4228171 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -974,7 +974,6 @@ async def test_write_batch(self, mock_request): mock_response("{}", 200), mock_response("{}", 200), mock_response("{}", 200), - mock_response("{}", 200), ] configuration = self.configuration configuration.store_id = store_id @@ -1043,15 +1042,7 @@ async def test_write_batch(self, mock_request): ), ], ) - self.assertEqual(mock_request.call_count, 4) - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01G5JAVJ41T49E9TT3SKVS7X1J", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) + self.assertEqual(mock_request.call_count, 3) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/write", @@ -1126,7 +1117,6 @@ async def test_write_batch_min_parallel(self, mock_request): mock_response("{}", 200), mock_response("{}", 200), mock_response("{}", 200), - mock_response("{}", 200), ] configuration = self.configuration configuration.store_id = store_id @@ -1195,15 +1185,7 @@ async def test_write_batch_min_parallel(self, mock_request): ), ], ) - self.assertEqual(mock_request.call_count, 4) - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01G5JAVJ41T49E9TT3SKVS7X1J", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) + self.assertEqual(mock_request.call_count, 3) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/write", @@ -1277,7 +1259,6 @@ async def test_write_batch_larger_chunk(self, mock_request): mock_request.side_effect = [ mock_response("{}", 200), mock_response("{}", 200), - mock_response("{}", 200), ] configuration = self.configuration configuration.store_id = store_id @@ -1346,15 +1327,7 @@ async def test_write_batch_larger_chunk(self, mock_request): ), ], ) - self.assertEqual(mock_request.call_count, 3) - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01G5JAVJ41T49E9TT3SKVS7X1J", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) + self.assertEqual(mock_request.call_count, 2) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/write", @@ -1417,7 +1390,6 @@ async def test_write_batch_failed(self, mock_request): """ mock_request.side_effect = [ - mock_response("{}", 200), mock_response("{}", 200), ValidationException(http_resp=http_mock_response(response_body, 400)), mock_response("{}", 200), @@ -1496,15 +1468,7 @@ async def test_write_batch_failed(self, mock_request): error=None, ), ) - self.assertEqual(mock_request.call_count, 4) - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01G5JAVJ41T49E9TT3SKVS7X1J", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) + self.assertEqual(mock_request.call_count, 3) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/write", @@ -1577,7 +1541,6 @@ async def test_delete_batch(self, mock_request): """ mock_request.side_effect = [ mock_response("{}", 200), - mock_response("{}", 200), ] configuration = self.configuration configuration.store_id = store_id @@ -1603,14 +1566,6 @@ async def test_delete_batch(self, mock_request): "transaction": transaction, }, ) - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01G5JAVJ41T49E9TT3SKVS7X1J", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/write", @@ -1771,7 +1726,7 @@ async def test_write_batch_unauthorized(self, mock_request): configuration = self.configuration configuration.store_id = store_id async with OpenFgaClient(configuration) as api_client: - with self.assertRaises(UnauthorizedException) as api_exception: + with self.assertRaises(UnauthorizedException): body = ClientWriteRequest( writes=[ ClientTuple( @@ -1792,17 +1747,29 @@ async def test_write_batch_unauthorized(self, mock_request): }, ) - self.assertIsInstance(api_exception.exception, UnauthorizedException) mock_request.assert_called() self.assertEqual(mock_request.call_count, 1) mock_request.assert_called_once_with( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01G5JAVJ41T49E9TT3SKVS7X1J", + "POST", + "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/write", headers=ANY, query_params=[], + post_params=[], + body={ + "writes": { + "tuple_keys": [ + { + "user": "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + "relation": "reader", + "object": "document:2021-budget", + } + ] + }, + "authorization_model_id": "01G5JAVJ41T49E9TT3SKVS7X1J", + }, _preload_content=ANY, - _request_timeout=None, + _request_timeout=ANY, ) await api_client.close() @@ -1918,7 +1885,6 @@ async def test_batch_check_single_request(self, mock_request): # First, mock the response response_body = '{"allowed": true, "resolution": "1234"}' mock_request.side_effect = [ - mock_response("{}", 200), mock_response(response_body, 200), ] body = ClientCheckRequest( @@ -1939,14 +1905,6 @@ async def test_batch_check_single_request(self, mock_request): self.assertTrue(api_response[0].allowed) self.assertEqual(api_response[0].request, body) # Make sure the API was called with the right data - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01GXSA8YR785C4FYS3C0RTG7B1", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/check", @@ -1975,7 +1933,6 @@ async def test_batch_check_multiple_request(self, mock_request): # First, mock the response mock_request.side_effect = [ - mock_response("{}", 200), mock_response('{"allowed": true, "resolution": "1234"}', 200), mock_response('{"allowed": false, "resolution": "1234"}', 200), mock_response('{"allowed": true, "resolution": "1234"}', 200), @@ -2017,14 +1974,6 @@ async def test_batch_check_multiple_request(self, mock_request): self.assertTrue(api_response[2].allowed) self.assertEqual(api_response[2].request, body3) # Make sure the API was called with the right data - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01GXSA8YR785C4FYS3C0RTG7B1", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/check", @@ -2093,7 +2042,6 @@ async def test_batch_check_multiple_request_fail(self, mock_request): # First, mock the response mock_request.side_effect = [ - mock_response("{}", 200), mock_response('{"allowed": true, "resolution": "1234"}', 200), ValidationException(http_resp=http_mock_response(response_body, 400)), mock_response('{"allowed": false, "resolution": "1234"}', 200), @@ -2138,14 +2086,6 @@ async def test_batch_check_multiple_request_fail(self, mock_request): self.assertFalse(api_response[2].allowed) self.assertEqual(api_response[2].request, body3) # Make sure the API was called with the right data - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01GXSA8YR785C4FYS3C0RTG7B1", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/check", @@ -2357,7 +2297,6 @@ async def test_list_relations(self, mock_request): # First, mock the response mock_request.side_effect = [ - mock_response("{}", 200), mock_response('{"allowed": true, "resolution": "1234"}', 200), mock_response('{"allowed": false, "resolution": "1234"}', 200), mock_response('{"allowed": true, "resolution": "1234"}', 200), @@ -2376,14 +2315,6 @@ async def test_list_relations(self, mock_request): self.assertEqual(api_response, ["reader", "viewer"]) # Make sure the API was called with the right data - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01GXSA8YR785C4FYS3C0RTG7B1", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/check", @@ -2447,7 +2378,7 @@ async def test_list_relations_unauthorized(self, mock_request): configuration = self.configuration configuration.store_id = store_id async with OpenFgaClient(configuration) as api_client: - with self.assertRaises(UnauthorizedException) as api_exception: + with self.assertRaises(UnauthorizedException): await api_client.list_relations( body=ClientListRelationsRequest( user="user:81684243-9356-4421-8fbf-a4f8d36aa31b", @@ -2457,18 +2388,9 @@ async def test_list_relations_unauthorized(self, mock_request): options={"authorization_model_id": "01GXSA8YR785C4FYS3C0RTG7B1"}, ) - self.assertIsInstance(api_exception.exception, UnauthorizedException) mock_request.assert_called() - self.assertEqual(mock_request.call_count, 1) + self.assertEqual(mock_request.call_count, 3) - mock_request.assert_called_once_with( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01GXSA8YR785C4FYS3C0RTG7B1", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) await api_client.close() @patch.object(rest.RESTClientObject, "request") diff --git a/test/test_client_sync.py b/test/test_client_sync.py index 5fbeb3e..3fcb593 100644 --- a/test/test_client_sync.py +++ b/test/test_client_sync.py @@ -974,7 +974,6 @@ def test_write_batch(self, mock_request): mock_response("{}", 200), mock_response("{}", 200), mock_response("{}", 200), - mock_response("{}", 200), ] configuration = self.configuration configuration.store_id = store_id @@ -1043,15 +1042,7 @@ def test_write_batch(self, mock_request): ), ], ) - self.assertEqual(mock_request.call_count, 4) - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01G5JAVJ41T49E9TT3SKVS7X1J", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) + self.assertEqual(mock_request.call_count, 3) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/write", @@ -1126,7 +1117,6 @@ def test_write_batch_min_parallel(self, mock_request): mock_response("{}", 200), mock_response("{}", 200), mock_response("{}", 200), - mock_response("{}", 200), ] configuration = self.configuration configuration.store_id = store_id @@ -1195,15 +1185,7 @@ def test_write_batch_min_parallel(self, mock_request): ), ], ) - self.assertEqual(mock_request.call_count, 4) - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01G5JAVJ41T49E9TT3SKVS7X1J", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) + self.assertEqual(mock_request.call_count, 3) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/write", @@ -1346,15 +1328,7 @@ def test_write_batch_larger_chunk(self, mock_request): ), ], ) - self.assertEqual(mock_request.call_count, 3) - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01G5JAVJ41T49E9TT3SKVS7X1J", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) + self.assertEqual(mock_request.call_count, 2) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/write", @@ -1417,7 +1391,6 @@ def test_write_batch_failed(self, mock_request): """ mock_request.side_effect = [ - mock_response("{}", 200), mock_response("{}", 200), ValidationException(http_resp=http_mock_response(response_body, 400)), mock_response("{}", 200), @@ -1496,15 +1469,7 @@ def test_write_batch_failed(self, mock_request): error=None, ), ) - self.assertEqual(mock_request.call_count, 4) - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01G5JAVJ41T49E9TT3SKVS7X1J", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) + self.assertEqual(mock_request.call_count, 3) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/write", @@ -1577,7 +1542,6 @@ def test_delete_batch(self, mock_request): """ mock_request.side_effect = [ mock_response("{}", 200), - mock_response("{}", 200), ] configuration = self.configuration configuration.store_id = store_id @@ -1603,14 +1567,6 @@ def test_delete_batch(self, mock_request): "transaction": transaction, }, ) - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01G5JAVJ41T49E9TT3SKVS7X1J", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/write", @@ -1771,7 +1727,7 @@ def test_write_batch_unauthorized(self, mock_request): configuration = self.configuration configuration.store_id = store_id with OpenFgaClient(configuration) as api_client: - with self.assertRaises(UnauthorizedException) as api_exception: + with self.assertRaises(UnauthorizedException): body = ClientWriteRequest( writes=[ ClientTuple( @@ -1792,19 +1748,31 @@ def test_write_batch_unauthorized(self, mock_request): }, ) - self.assertIsInstance(api_exception.exception, UnauthorizedException) - mock_request.assert_called() - self.assertEqual(mock_request.call_count, 1) - - mock_request.assert_called_once_with( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01G5JAVJ41T49E9TT3SKVS7X1J", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) - api_client.close() + mock_request.assert_called() + self.assertEqual(mock_request.call_count, 1) + + mock_request.assert_called_once_with( + "POST", + "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/write", + headers=ANY, + query_params=[], + post_params=[], + body={ + "writes": { + "tuple_keys": [ + { + "user": "user:81684243-9356-4421-8fbf-a4f8d36aa31b", + "relation": "reader", + "object": "document:2021-budget", + } + ] + }, + "authorization_model_id": "01G5JAVJ41T49E9TT3SKVS7X1J", + }, + _preload_content=ANY, + _request_timeout=ANY, + ) + api_client.close() @patch.object(rest.RESTClientObject, "request") def test_check(self, mock_request): @@ -1918,7 +1886,6 @@ def test_batch_check_single_request(self, mock_request): # First, mock the response response_body = '{"allowed": true, "resolution": "1234"}' mock_request.side_effect = [ - mock_response("{}", 200), mock_response(response_body, 200), ] body = ClientCheckRequest( @@ -1939,14 +1906,6 @@ def test_batch_check_single_request(self, mock_request): self.assertTrue(api_response[0].allowed) self.assertEqual(api_response[0].request, body) # Make sure the API was called with the right data - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01GXSA8YR785C4FYS3C0RTG7B1", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/check", @@ -1975,7 +1934,6 @@ def test_batch_check_multiple_request(self, mock_request): # First, mock the response mock_request.side_effect = [ - mock_response("{}", 200), mock_response('{"allowed": true, "resolution": "1234"}', 200), mock_response('{"allowed": false, "resolution": "1234"}', 200), mock_response('{"allowed": true, "resolution": "1234"}', 200), @@ -2017,14 +1975,6 @@ def test_batch_check_multiple_request(self, mock_request): self.assertTrue(api_response[2].allowed) self.assertEqual(api_response[2].request, body3) # Make sure the API was called with the right data - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01GXSA8YR785C4FYS3C0RTG7B1", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/check", @@ -2093,7 +2043,6 @@ def test_batch_check_multiple_request_fail(self, mock_request): # First, mock the response mock_request.side_effect = [ - mock_response("{}", 200), mock_response('{"allowed": true, "resolution": "1234"}', 200), ValidationException(http_resp=http_mock_response(response_body, 400)), mock_response('{"allowed": false, "resolution": "1234"}', 200), @@ -2138,14 +2087,6 @@ def test_batch_check_multiple_request_fail(self, mock_request): self.assertFalse(api_response[2].allowed) self.assertEqual(api_response[2].request, body3) # Make sure the API was called with the right data - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01GXSA8YR785C4FYS3C0RTG7B1", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/check", @@ -2357,7 +2298,6 @@ def test_list_relations(self, mock_request): # First, mock the response mock_request.side_effect = [ - mock_response("{}", 200), mock_response('{"allowed": true, "resolution": "1234"}', 200), mock_response('{"allowed": false, "resolution": "1234"}', 200), mock_response('{"allowed": true, "resolution": "1234"}', 200), @@ -2376,14 +2316,6 @@ def test_list_relations(self, mock_request): self.assertEqual(api_response, ["reader", "viewer"]) # Make sure the API was called with the right data - mock_request.assert_any_call( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01GXSA8YR785C4FYS3C0RTG7B1", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) mock_request.assert_any_call( "POST", "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/check", @@ -2459,16 +2391,7 @@ def test_list_relations_unauthorized(self, mock_request): self.assertIsInstance(api_exception.exception, UnauthorizedException) mock_request.assert_called() - self.assertEqual(mock_request.call_count, 1) - - mock_request.assert_called_once_with( - "GET", - "http://api.fga.example/stores/01YCP46JKYM8FJCQ37NMBYHE5X/authorization-models/01GXSA8YR785C4FYS3C0RTG7B1", - headers=ANY, - query_params=[], - _preload_content=ANY, - _request_timeout=None, - ) + self.assertEqual(mock_request.call_count, 3) api_client.close() @patch.object(rest.RESTClientObject, "request")