diff --git a/tests/unit/base/test_version.py b/tests/unit/base/test_version.py index 1f1f6395eb..7d79ac1cdb 100644 --- a/tests/unit/base/test_version.py +++ b/tests/unit/base/test_version.py @@ -89,3 +89,60 @@ def test_fetch_redirect(self): response = self.client.messaging.v1.fetch(method="GET", uri="/Deactivations") self.assertIsNotNone(response) + + +class PatchTestCase(IntegrationTestCase): + def test_patch_success(self): + self.holodeck.mock( + Response(200, '{"status": "patched", "id": "123"}'), + Request( + method="PATCH", + url="https://api.twilio.com/2010-04-01/Accounts/AC123/Resource/123.json", + ), + ) + response = self.client.api.v2010.patch( + method="PATCH", + uri="/Accounts/AC123/Resource/123.json", + data={"field": "value"}, + ) + + self.assertIsNotNone(response) + self.assertEqual(response["status"], "patched") + self.assertEqual(response["id"], "123") + + def test_patch_server_error(self): + self.holodeck.mock( + Response(500, '{"message": "Internal Server Error"}'), + Request( + method="PATCH", + url="https://api.twilio.com/2010-04-01/Accounts/AC123/Resource/123.json", + ), + ) + + with self.assertRaises(Exception) as context: + self.client.api.v2010.patch( + method="PATCH", + uri="/Accounts/AC123/Resource/123.json", + data={"field": "value"}, + ) + + self.assertIn("Unable to patch the record", str(context.exception)) + + def test_patch_with_params(self): + self.holodeck.mock( + Response(200, '{"status": "patched", "param": "test"}'), + Request( + method="PATCH", + url="https://api.twilio.com/2010-04-01/Accounts/AC123/Resource/123.json", + ), + ) + response = self.client.api.v2010.patch( + method="PATCH", + uri="/Accounts/AC123/Resource/123.json", + params={"query": "param"}, + data={"field": "value"}, + ) + + self.assertIsNotNone(response) + self.assertEqual(response["status"], "patched") + self.assertEqual(response["param"], "test") diff --git a/twilio/base/version.py b/twilio/base/version.py index ed7e86f499..b21ec365b9 100644 --- a/twilio/base/version.py +++ b/twilio/base/version.py @@ -229,6 +229,69 @@ async def update_async( return self._parse_update(method, uri, response) + def _parse_patch(self, method: str, uri: str, response: Response) -> Any: + """ + Parses patch response JSON + """ + if response.status_code < 200 or response.status_code >= 300: + raise self.exception(method, uri, response, "Unable to patch the record") + + return json.loads(response.text) + + def patch( + self, + method: str, + uri: str, + params: Optional[Dict[str, object]] = None, + data: Optional[Dict[str, object]] = None, + headers: Optional[Dict[str, str]] = None, + auth: Optional[Tuple[str, str]] = None, + timeout: Optional[float] = None, + allow_redirects: bool = False, + ) -> Any: + """ + Patch a resource instance. + """ + response = self.request( + method, + uri, + params=params, + data=data, + headers=headers, + auth=auth, + timeout=timeout, + allow_redirects=allow_redirects, + ) + + return self._parse_patch(method, uri, response) + + async def patch_async( + self, + method: str, + uri: str, + params: Optional[Dict[str, object]] = None, + data: Optional[Dict[str, object]] = None, + headers: Optional[Dict[str, str]] = None, + auth: Optional[Tuple[str, str]] = None, + timeout: Optional[float] = None, + allow_redirects: bool = False, + ) -> Any: + """ + Asynchronously patch a resource instance. + """ + response = await self.request_async( + method, + uri, + params=params, + data=data, + headers=headers, + auth=auth, + timeout=timeout, + allow_redirects=allow_redirects, + ) + + return self._parse_patch(method, uri, response) + def _parse_delete(self, method: str, uri: str, response: Response) -> bool: """ Parses delete response JSON