|
24 | 24 | from knock_mapi import KnockMgmt, AsyncKnockMgmt, APIResponseValidationError |
25 | 25 | from knock_mapi._types import Omit |
26 | 26 | from knock_mapi._models import BaseModel, FinalRequestOptions |
27 | | -from knock_mapi._exceptions import KnockMgmtError, APIResponseValidationError |
| 27 | +from knock_mapi._exceptions import APIStatusError, KnockMgmtError, APIResponseValidationError |
28 | 28 | from knock_mapi._base_client import ( |
29 | 29 | DEFAULT_TIMEOUT, |
30 | 30 | HTTPX_DEFAULT_TIMEOUT, |
@@ -821,6 +821,33 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: |
821 | 821 |
|
822 | 822 | assert response.http_request.headers.get("x-stainless-retry-count") == "42" |
823 | 823 |
|
| 824 | + @pytest.mark.respx(base_url=base_url) |
| 825 | + def test_follow_redirects(self, respx_mock: MockRouter) -> None: |
| 826 | + # Test that the default follow_redirects=True allows following redirects |
| 827 | + respx_mock.post("/redirect").mock( |
| 828 | + return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"}) |
| 829 | + ) |
| 830 | + respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"})) |
| 831 | + |
| 832 | + response = self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response) |
| 833 | + assert response.status_code == 200 |
| 834 | + assert response.json() == {"status": "ok"} |
| 835 | + |
| 836 | + @pytest.mark.respx(base_url=base_url) |
| 837 | + def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None: |
| 838 | + # Test that follow_redirects=False prevents following redirects |
| 839 | + respx_mock.post("/redirect").mock( |
| 840 | + return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"}) |
| 841 | + ) |
| 842 | + |
| 843 | + with pytest.raises(APIStatusError) as exc_info: |
| 844 | + self.client.post( |
| 845 | + "/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response |
| 846 | + ) |
| 847 | + |
| 848 | + assert exc_info.value.response.status_code == 302 |
| 849 | + assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected" |
| 850 | + |
824 | 851 |
|
825 | 852 | class TestAsyncKnockMgmt: |
826 | 853 | client = AsyncKnockMgmt(base_url=base_url, service_token=service_token, _strict_response_validation=True) |
@@ -1648,3 +1675,30 @@ async def test_main() -> None: |
1648 | 1675 | raise AssertionError("calling get_platform using asyncify resulted in a hung process") |
1649 | 1676 |
|
1650 | 1677 | time.sleep(0.1) |
| 1678 | + |
| 1679 | + @pytest.mark.respx(base_url=base_url) |
| 1680 | + async def test_follow_redirects(self, respx_mock: MockRouter) -> None: |
| 1681 | + # Test that the default follow_redirects=True allows following redirects |
| 1682 | + respx_mock.post("/redirect").mock( |
| 1683 | + return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"}) |
| 1684 | + ) |
| 1685 | + respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"})) |
| 1686 | + |
| 1687 | + response = await self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response) |
| 1688 | + assert response.status_code == 200 |
| 1689 | + assert response.json() == {"status": "ok"} |
| 1690 | + |
| 1691 | + @pytest.mark.respx(base_url=base_url) |
| 1692 | + async def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None: |
| 1693 | + # Test that follow_redirects=False prevents following redirects |
| 1694 | + respx_mock.post("/redirect").mock( |
| 1695 | + return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"}) |
| 1696 | + ) |
| 1697 | + |
| 1698 | + with pytest.raises(APIStatusError) as exc_info: |
| 1699 | + await self.client.post( |
| 1700 | + "/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response |
| 1701 | + ) |
| 1702 | + |
| 1703 | + assert exc_info.value.response.status_code == 302 |
| 1704 | + assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected" |
0 commit comments