From 03322cffe8f0c0a1b3d6ff8b6156a9f2506bc398 Mon Sep 17 00:00:00 2001 From: Julia Date: Wed, 11 Feb 2026 20:08:36 +0400 Subject: [PATCH 1/3] Add subscription alerts --- .../subscriptions/alert_client.py | 27 +++ lago_python_client/subscriptions/clients.py | 6 + tests/fixtures/subscription_alert.json | 45 ++++ tests/fixtures/subscription_alert_index.json | 54 +++++ tests/test_subscription_alert_client.py | 192 ++++++++++++++++++ 5 files changed, 324 insertions(+) create mode 100644 lago_python_client/subscriptions/alert_client.py create mode 100644 tests/fixtures/subscription_alert.json create mode 100644 tests/fixtures/subscription_alert_index.json create mode 100644 tests/test_subscription_alert_client.py diff --git a/lago_python_client/subscriptions/alert_client.py b/lago_python_client/subscriptions/alert_client.py new file mode 100644 index 00000000..2176fd8c --- /dev/null +++ b/lago_python_client/subscriptions/alert_client.py @@ -0,0 +1,27 @@ +from typing import ClassVar, Type + +from ..base_client import BaseClient +from ..mixins import ( + NestedCreateCommandMixin, + NestedDestroyCommandMixin, + NestedFindAllCommandMixin, + NestedFindCommandMixin, + NestedUpdateCommandMixin, +) +from ..models.alert import AlertResponse + + +class SubscriptionAlertClient( + NestedCreateCommandMixin[AlertResponse], + NestedUpdateCommandMixin[AlertResponse], + NestedDestroyCommandMixin[AlertResponse], + NestedFindCommandMixin[AlertResponse], + NestedFindAllCommandMixin[AlertResponse], + BaseClient, +): + API_RESOURCE: ClassVar[str] = "alerts" + RESPONSE_MODEL: ClassVar[Type[AlertResponse]] = AlertResponse + ROOT_NAME: ClassVar[str] = "alert" + + def api_resource(self, subscription_id: str) -> tuple[str]: + return ("subscriptions", subscription_id, "alerts") diff --git a/lago_python_client/subscriptions/clients.py b/lago_python_client/subscriptions/clients.py index 505a945a..e9fa222a 100644 --- a/lago_python_client/subscriptions/clients.py +++ b/lago_python_client/subscriptions/clients.py @@ -2,6 +2,7 @@ from ..base_client import BaseClient from ..base_model import BaseModel +from ..functools_ext import callable_cached_property from ..mixins import ( CreateCommandMixin, DestroyCommandMixin, @@ -29,6 +30,7 @@ prepare_object_response, verify_response, ) +from .alert_client import SubscriptionAlertClient class SubscriptionClient( @@ -43,6 +45,10 @@ class SubscriptionClient( RESPONSE_MODEL: ClassVar[Type[SubscriptionResponse]] = SubscriptionResponse ROOT_NAME: ClassVar[str] = "subscription" + @callable_cached_property + def alerts(self) -> SubscriptionAlertClient: + return SubscriptionAlertClient(self.base_url, self.api_key) + def lifetime_usage(self, resource_id: str) -> LifetimeUsageResponse: api_response: Response = send_get_request( url=make_url( diff --git a/tests/fixtures/subscription_alert.json b/tests/fixtures/subscription_alert.json new file mode 100644 index 00000000..f7a8a0a0 --- /dev/null +++ b/tests/fixtures/subscription_alert.json @@ -0,0 +1,45 @@ +{ + "alert": { + "lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90", + "lago_organization_id": "1a901a90-1a90-1a90-1a90-1a901a901a90", + "external_subscription_id": "subscription_id", + "lago_wallet_id": null, + "wallet_code": null, + "alert_type": "billable_metric_current_usage_amount", + "code": "storage_threshold_alert", + "name": "Storage Usage Alert", + "billable_metric": { + "lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90", + "name": "Storage", + "code": "storage", + "description": "GB of storage used in my application", + "recurring": false, + "rounding_function": "round", + "rounding_precision": 2, + "created_at": "2022-09-14T16:35:31Z", + "expression": "round((ended_at - started_at) * units)", + "field_name": "gb", + "aggregation_type": "sum_agg", + "weighted_interval": "seconds", + "filters": [ + { + "key": "region", + "values": [ + "us-east-1" + ] + } + ] + }, + "previous_value": 1000, + "direction": "increasing", + "thresholds": [ + { + "code": "warn", + "recurring": false, + "value": "99.0" + } + ], + "created_at": "2025-03-20T10:00:00Z", + "last_processed_at": "2025-05-19T10:04:21Z" + } +} diff --git a/tests/fixtures/subscription_alert_index.json b/tests/fixtures/subscription_alert_index.json new file mode 100644 index 00000000..c57e2e77 --- /dev/null +++ b/tests/fixtures/subscription_alert_index.json @@ -0,0 +1,54 @@ +{ + "alerts": [ + { + "lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90", + "lago_organization_id": "1a901a90-1a90-1a90-1a90-1a901a901a90", + "external_subscription_id": "subscription_id", + "lago_wallet_id": null, + "wallet_code": null, + "alert_type": "billable_metric_current_usage_amount", + "code": "storage_threshold_alert", + "name": "Storage Usage Alert", + "billable_metric": { + "lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90", + "name": "Storage", + "code": "storage", + "description": "GB of storage used in my application", + "recurring": false, + "rounding_function": "round", + "rounding_precision": 2, + "created_at": "2022-09-14T16:35:31Z", + "expression": "round((ended_at - started_at) * units)", + "field_name": "gb", + "aggregation_type": "sum_agg", + "weighted_interval": "seconds", + "filters": [ + { + "key": "region", + "values": [ + "us-east-1" + ] + } + ] + }, + "previous_value": 1000, + "direction": "increasing", + "thresholds": [ + { + "code": "warn", + "recurring": false, + "value": "99.0" + } + ], + "created_at": "2025-03-20T10:00:00Z", + "last_processed_at": "2025-05-19T10:04:21Z" + } + ], + "meta": { + "current_page": 1, + "next_page": 2, + "prev_page": null, + "total_pages": 4, + "total_count": 70 + } +} diff --git a/tests/test_subscription_alert_client.py b/tests/test_subscription_alert_client.py new file mode 100644 index 00000000..9d6e5939 --- /dev/null +++ b/tests/test_subscription_alert_client.py @@ -0,0 +1,192 @@ +import pytest +from pytest_httpx import HTTPXMock + +from lago_python_client.client import Client +from lago_python_client.exceptions import LagoApiError +from lago_python_client.models import ( + Alert, + AlertThreshold, + AlertThresholdList, +) + +from .utils.mixin import mock_response + + +def alert_object(): + threshold = AlertThreshold(code="warn", value=10000, recurring=False) + + return Alert( + alert_type="billable_metric_current_usage_amount", + code="storage_threshold_alert", + name="Storage Usage Alert", + billable_metric_code="storage", + thresholds=AlertThresholdList(__root__=[threshold]), + ) + + +def test_valid_create_subscription_alert_request(httpx_mock: HTTPXMock): + client = Client(api_key="886fe239-927d-4072-ab72-6dd345e8dd0d") + + httpx_mock.add_response( + method="POST", + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts", + content=mock_response("subscription_alert"), + ) + response = client.subscriptions.alerts.create("subscription_id", alert_object()) + + assert response.lago_id == "1a901a90-1a90-1a90-1a90-1a901a901a90" + assert response.lago_organization_id == "1a901a90-1a90-1a90-1a90-1a901a901a90" + assert response.external_subscription_id == "subscription_id" + assert response.lago_wallet_id is None + assert response.wallet_code is None + assert response.code == "storage_threshold_alert" + assert response.name == "Storage Usage Alert" + assert response.alert_type == "billable_metric_current_usage_amount" + assert response.previous_value == "1000" + assert response.billable_metric.code == "storage" + assert response.thresholds == AlertThresholdList( + __root__=[AlertThreshold(code="warn", value=99.0, recurring=False)] + ) + + +def test_invalid_create_subscription_alert_request(httpx_mock: HTTPXMock): + client = Client(api_key="invalid") + + httpx_mock.add_response( + method="POST", + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts", + status_code=401, + content=b"", + ) + + with pytest.raises(LagoApiError): + client.subscriptions.alerts.create("subscription_id", alert_object()) + + +def test_valid_update_subscription_alert_request(httpx_mock: HTTPXMock): + client = Client(api_key="886fe239-927d-4072-ab72-6dd345e8dd0d") + code = "alert-code" + + httpx_mock.add_response( + method="PUT", + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts/" + code, + content=mock_response("subscription_alert"), + ) + response = client.subscriptions.alerts.update("subscription_id", code, alert_object()) + + assert response.lago_id == "1a901a90-1a90-1a90-1a90-1a901a901a90" + + +def test_invalid_update_subscription_alert_request(httpx_mock: HTTPXMock): + client = Client(api_key="invalid") + code = "invalid" + + httpx_mock.add_response( + method="PUT", + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts/" + code, + status_code=401, + content=b"", + ) + + with pytest.raises(LagoApiError): + client.subscriptions.alerts.update("subscription_id", code, alert_object()) + + +def test_valid_find_subscription_alert_request(httpx_mock: HTTPXMock): + client = Client(api_key="886fe239-927d-4072-ab72-6dd345e8dd0d") + code = "alert-code" + + httpx_mock.add_response( + method="GET", + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts/" + code, + content=mock_response("subscription_alert"), + ) + response = client.subscriptions.alerts.find("subscription_id", code) + + assert response.lago_id == "1a901a90-1a90-1a90-1a90-1a901a901a90" + + +def test_invalid_find_subscription_alert_request(httpx_mock: HTTPXMock): + client = Client(api_key="invalid") + code = "invalid" + + httpx_mock.add_response( + method="GET", + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts/" + code, + status_code=404, + content=b"", + ) + + with pytest.raises(LagoApiError): + client.subscriptions.alerts.find("subscription_id", code) + + +def test_valid_destroy_subscription_alert_request(httpx_mock: HTTPXMock): + client = Client(api_key="886fe239-927d-4072-ab72-6dd345e8dd0d") + code = "alert-code" + + httpx_mock.add_response( + method="DELETE", + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts/" + code, + content=mock_response("subscription_alert"), + ) + response = client.subscriptions.alerts.destroy("subscription_id", code) + + assert response.lago_id == "1a901a90-1a90-1a90-1a90-1a901a901a90" + + +def test_invalid_destroy_subscription_alert_request(httpx_mock: HTTPXMock): + client = Client(api_key="invalid") + code = "invalid" + + httpx_mock.add_response( + method="DELETE", + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts/" + code, + status_code=404, + content=b"", + ) + + with pytest.raises(LagoApiError): + client.subscriptions.alerts.destroy("subscription_id", code) + + +def test_valid_find_all_subscription_alerts_request(httpx_mock: HTTPXMock): + client = Client(api_key="886fe239-927d-4072-ab72-6dd345e8dd0d") + + httpx_mock.add_response( + method="GET", + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts", + content=mock_response("subscription_alert_index"), + ) + response = client.subscriptions.alerts.find_all("subscription_id") + + assert response["alerts"][0].lago_id == "1a901a90-1a90-1a90-1a90-1a901a901a90" + assert response["meta"]["current_page"] == 1 + + +def test_valid_find_all_subscription_alerts_request_with_options(httpx_mock: HTTPXMock): + client = Client(api_key="886fe239-927d-4072-ab72-6dd345e8dd0d") + + httpx_mock.add_response( + method="GET", + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts?page=1&per_page=2", + content=mock_response("subscription_alert_index"), + ) + response = client.subscriptions.alerts.find_all("subscription_id", options={"per_page": 2, "page": 1}) + + assert response["alerts"][0].lago_id == "1a901a90-1a90-1a90-1a90-1a901a901a90" + assert response["meta"]["current_page"] == 1 + + +def test_invalid_find_all_subscription_alerts_request(httpx_mock: HTTPXMock): + client = Client(api_key="invalid") + + httpx_mock.add_response( + method="GET", + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts", + status_code=404, + content=b"", + ) + + with pytest.raises(LagoApiError): + client.subscriptions.alerts.find_all("subscription_id") From ab48e68dc810d1dd04634e42d62829add5c5f09b Mon Sep 17 00:00:00 2001 From: Vincent Pochet Date: Tue, 27 Oct 2026 17:04:19 +0100 Subject: [PATCH 2/3] test(alerts): Cover notify_on in subscription alert tests Co-Authored-By: Claude Opus 5.5 --- tests/fixtures/subscription_alert.json | 3 ++- tests/fixtures/subscription_alert_index.json | 3 ++- tests/test_subscription_alert_client.py | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/fixtures/subscription_alert.json b/tests/fixtures/subscription_alert.json index f7a8a0a0..eb32900b 100644 --- a/tests/fixtures/subscription_alert.json +++ b/tests/fixtures/subscription_alert.json @@ -36,7 +36,8 @@ { "code": "warn", "recurring": false, - "value": "99.0" + "value": "99.0", + "notify_on": ["triggered", "resolved"] } ], "created_at": "2025-03-20T10:00:00Z", diff --git a/tests/fixtures/subscription_alert_index.json b/tests/fixtures/subscription_alert_index.json index c57e2e77..afe2c419 100644 --- a/tests/fixtures/subscription_alert_index.json +++ b/tests/fixtures/subscription_alert_index.json @@ -37,7 +37,8 @@ { "code": "warn", "recurring": false, - "value": "99.0" + "value": "99.0", + "notify_on": ["triggered", "resolved"] } ], "created_at": "2025-03-20T10:00:00Z", diff --git a/tests/test_subscription_alert_client.py b/tests/test_subscription_alert_client.py index 9d6e5939..b00bcb2a 100644 --- a/tests/test_subscription_alert_client.py +++ b/tests/test_subscription_alert_client.py @@ -13,7 +13,7 @@ def alert_object(): - threshold = AlertThreshold(code="warn", value=10000, recurring=False) + threshold = AlertThreshold(code="warn", value=10000, recurring=False, notify_on=["triggered", "resolved"]) return Alert( alert_type="billable_metric_current_usage_amount", @@ -45,7 +45,7 @@ def test_valid_create_subscription_alert_request(httpx_mock: HTTPXMock): assert response.previous_value == "1000" assert response.billable_metric.code == "storage" assert response.thresholds == AlertThresholdList( - __root__=[AlertThreshold(code="warn", value=99.0, recurring=False)] + __root__=[AlertThreshold(code="warn", value=99.0, recurring=False, notify_on=["triggered", "resolved"])] ) From 6414b638887f04e2723b49ad3c16479129b70537 Mon Sep 17 00:00:00 2001 From: Vincent Pochet Date: Tue, 27 Oct 2026 17:27:18 +0100 Subject: [PATCH 3/3] fix(alerts): Accept subscription_status on subscription alert calls The API only finds active subscriptions unless subscription_status is given, so alerts of pending or terminated subscriptions were out of reach. The nested mixins now take an optional options query, and the subscription alerts client exposes subscription_status like the batch alert methods. The client also inherits the rate-limit settings of its parent, and the tests check the create and update payloads. Co-Authored-By: Claude Opus 5.5 --- lago_python_client/mixins.py | 9 ++- .../subscriptions/alert_client.py | 63 +++++++++++++++- lago_python_client/subscriptions/clients.py | 4 +- tests/test_subscription_alert_client.py | 73 +++++++++++++++++++ 4 files changed, 145 insertions(+), 4 deletions(-) diff --git a/lago_python_client/mixins.py b/lago_python_client/mixins.py index 5c4d7df6..33ea7586 100644 --- a/lago_python_client/mixins.py +++ b/lago_python_client/mixins.py @@ -395,6 +395,7 @@ class NestedCreateCommandMixin(Generic[_M]): def create( self: _ClientMixin[_M], *args: Union[str, BaseModel], + options: QueryPairs = None, timeout: Optional[httpx.Timeout] = None, ) -> Optional[_M]: """Execute `create` command.""" @@ -402,7 +403,7 @@ def create( # Send request and save response api_response: Response = send_post_request( - url=make_url(origin=self.base_url, path_parts=self.api_resource(*parent_ids)), + url=make_url(origin=self.base_url, path_parts=self.api_resource(*parent_ids), query_pairs=options), content=to_json( { self.ROOT_NAME: input_object.dict(exclude_none=True), @@ -430,6 +431,7 @@ class NestedUpdateCommandMixin(Generic[_M]): def update( self: _ClientMixin[_M], *args: Union[str, BaseModel], + options: QueryPairs = None, timeout: Optional[httpx.Timeout] = None, ) -> _M: """Execute `update` command.""" @@ -440,6 +442,7 @@ def update( url=make_url( origin=self.base_url, path_parts=self.api_resource(*parent_ids) + (resource_id,), + query_pairs=options, ), content=to_json( { @@ -464,6 +467,7 @@ class NestedDestroyCommandMixin(Generic[_M]): def destroy( self: _ClientMixin[_M], *args: str, + options: QueryPairs = None, timeout: Optional[httpx.Timeout] = None, ) -> BaseModel: """Execute `destroy` command.""" @@ -474,6 +478,7 @@ def destroy( url=make_url( origin=self.base_url, path_parts=self.api_resource(*parent_ids) + (resource_id,), + query_pairs=options, ), headers=make_headers(api_key=self.api_key), timeout=timeout, @@ -493,6 +498,7 @@ class NestedFindCommandMixin(Generic[_M]): def find( self: _ClientMixin[_M], *args: str, + options: QueryPairs = None, timeout: Optional[httpx.Timeout] = None, ) -> _M: """Execute `find` command.""" @@ -503,6 +509,7 @@ def find( url=make_url( origin=self.base_url, path_parts=self.api_resource(*parent_ids) + (resource_id,), + query_pairs=options, ), headers=make_headers(api_key=self.api_key), timeout=timeout, diff --git a/lago_python_client/subscriptions/alert_client.py b/lago_python_client/subscriptions/alert_client.py index 2176fd8c..6a1934b8 100644 --- a/lago_python_client/subscriptions/alert_client.py +++ b/lago_python_client/subscriptions/alert_client.py @@ -1,4 +1,6 @@ -from typing import ClassVar, Type +from typing import Any, ClassVar, Mapping, Optional, Type + +import httpx from ..base_client import BaseClient from ..mixins import ( @@ -8,7 +10,8 @@ NestedFindCommandMixin, NestedUpdateCommandMixin, ) -from ..models.alert import AlertResponse +from ..models.alert import Alert, AlertResponse +from ..services.request import QueryPairs class SubscriptionAlertClient( @@ -25,3 +28,59 @@ class SubscriptionAlertClient( def api_resource(self, subscription_id: str) -> tuple[str]: return ("subscriptions", subscription_id, "alerts") + + # The API only looks up active subscriptions unless `subscription_status` is given. + def create( + self, + subscription_id: str, + input_object: Alert, + subscription_status: Optional[str] = None, + timeout: Optional[httpx.Timeout] = None, + ) -> Optional[AlertResponse]: + return super().create( + subscription_id, input_object, options=_status_query(subscription_status), timeout=timeout + ) + + def update( + self, + subscription_id: str, + code: str, + input_object: Alert, + subscription_status: Optional[str] = None, + timeout: Optional[httpx.Timeout] = None, + ) -> AlertResponse: + return super().update( + subscription_id, code, input_object, options=_status_query(subscription_status), timeout=timeout + ) + + def destroy( + self, + subscription_id: str, + code: str, + subscription_status: Optional[str] = None, + timeout: Optional[httpx.Timeout] = None, + ) -> AlertResponse: + return super().destroy(subscription_id, code, options=_status_query(subscription_status), timeout=timeout) + + def find( + self, + subscription_id: str, + code: str, + subscription_status: Optional[str] = None, + timeout: Optional[httpx.Timeout] = None, + ) -> AlertResponse: + return super().find(subscription_id, code, options=_status_query(subscription_status), timeout=timeout) + + def find_all( + self, + subscription_id: str, + options: QueryPairs = None, + subscription_status: Optional[str] = None, + timeout: Optional[httpx.Timeout] = None, + ) -> Mapping[str, Any]: + query = {**dict(options or {}), **_status_query(subscription_status)} + return super().find_all(subscription_id, options=query, timeout=timeout) + + +def _status_query(subscription_status: Optional[str]) -> dict: + return {} if subscription_status is None else {"subscription_status": subscription_status} diff --git a/lago_python_client/subscriptions/clients.py b/lago_python_client/subscriptions/clients.py index e9fa222a..810dfeaa 100644 --- a/lago_python_client/subscriptions/clients.py +++ b/lago_python_client/subscriptions/clients.py @@ -47,7 +47,9 @@ class SubscriptionClient( @callable_cached_property def alerts(self) -> SubscriptionAlertClient: - return SubscriptionAlertClient(self.base_url, self.api_key) + return SubscriptionAlertClient( + self.base_url, self.api_key, rate_limit_retry_config=self.rate_limit_retry_config + ) def lifetime_usage(self, resource_id: str) -> LifetimeUsageResponse: api_response: Response = send_get_request( diff --git a/tests/test_subscription_alert_client.py b/tests/test_subscription_alert_client.py index b00bcb2a..e19b4fc5 100644 --- a/tests/test_subscription_alert_client.py +++ b/tests/test_subscription_alert_client.py @@ -24,12 +24,24 @@ def alert_object(): ) +ALERT_PAYLOAD = { + "alert": { + "alert_type": "billable_metric_current_usage_amount", + "code": "storage_threshold_alert", + "name": "Storage Usage Alert", + "billable_metric_code": "storage", + "thresholds": [{"code": "warn", "value": "10000", "recurring": False, "notify_on": ["triggered", "resolved"]}], + } +} + + def test_valid_create_subscription_alert_request(httpx_mock: HTTPXMock): client = Client(api_key="886fe239-927d-4072-ab72-6dd345e8dd0d") httpx_mock.add_response( method="POST", url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts", + match_json=ALERT_PAYLOAD, content=mock_response("subscription_alert"), ) response = client.subscriptions.alerts.create("subscription_id", alert_object()) @@ -70,6 +82,7 @@ def test_valid_update_subscription_alert_request(httpx_mock: HTTPXMock): httpx_mock.add_response( method="PUT", url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts/" + code, + match_json=ALERT_PAYLOAD, content=mock_response("subscription_alert"), ) response = client.subscriptions.alerts.update("subscription_id", code, alert_object()) @@ -190,3 +203,63 @@ def test_invalid_find_all_subscription_alerts_request(httpx_mock: HTTPXMock): with pytest.raises(LagoApiError): client.subscriptions.alerts.find_all("subscription_id") + + +@pytest.mark.parametrize( + "method,url_suffix,call", + [ + ("POST", "", lambda alerts: alerts.create("subscription_id", alert_object(), subscription_status="pending")), + ( + "PUT", + "/alert-code", + lambda alerts: alerts.update( + "subscription_id", "alert-code", alert_object(), subscription_status="pending" + ), + ), + ( + "GET", + "/alert-code", + lambda alerts: alerts.find("subscription_id", "alert-code", subscription_status="pending"), + ), + ( + "DELETE", + "/alert-code", + lambda alerts: alerts.destroy("subscription_id", "alert-code", subscription_status="pending"), + ), + ], +) +def test_subscription_alert_request_with_subscription_status(httpx_mock: HTTPXMock, method, url_suffix, call): + client = Client(api_key="886fe239-927d-4072-ab72-6dd345e8dd0d") + + httpx_mock.add_response( + method=method, + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts" + + url_suffix + + "?subscription_status=pending", + content=mock_response("subscription_alert"), + ) + response = call(client.subscriptions.alerts) + + assert response.lago_id == "1a901a90-1a90-1a90-1a90-1a901a901a90" + + +def test_find_all_subscription_alerts_request_with_subscription_status(httpx_mock: HTTPXMock): + client = Client(api_key="886fe239-927d-4072-ab72-6dd345e8dd0d") + + httpx_mock.add_response( + method="GET", + url="https://api.getlago.com/api/v1/subscriptions/subscription_id/alerts?page=1&subscription_status=terminated", + content=mock_response("subscription_alert_index"), + ) + response = client.subscriptions.alerts.find_all( + "subscription_id", options={"page": 1}, subscription_status="terminated" + ) + + assert response["alerts"][0].lago_id == "1a901a90-1a90-1a90-1a90-1a901a901a90" + + +def test_subscription_alerts_client_uses_client_rate_limit_config(): + client = Client(api_key="886fe239-927d-4072-ab72-6dd345e8dd0d", max_retries=0) + + assert client.subscriptions.alerts.rate_limit_retry_config is client.subscriptions.rate_limit_retry_config + assert client.subscriptions.alerts.rate_limit_retry_config.max_retries == 0