2023-02-21 09:47:52 +01:00
|
|
|
from unittest.mock import PropertyMock, patch
|
2022-06-03 08:09:47 -06:00
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
from django.core.cache import cache
|
2024-09-18 07:16:41 +08:00
|
|
|
from django.test import override_settings
|
2022-06-03 08:09:47 -06:00
|
|
|
from django.urls import reverse
|
|
|
|
|
from rest_framework import status
|
|
|
|
|
from rest_framework.test import APIClient
|
|
|
|
|
|
2024-09-18 21:32:16 +08:00
|
|
|
from common.api_helpers.custom_ratelimit import load_custom_ratelimits
|
|
|
|
|
|
2022-06-03 08:09:47 -06:00
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
2023-02-21 09:47:52 +01:00
|
|
|
def test_throttling(make_organization_and_user_with_token):
|
|
|
|
|
with patch("apps.public_api.throttlers.user_throttle.UserThrottle.rate", new_callable=PropertyMock) as mocked_rate:
|
|
|
|
|
mocked_rate.return_value = "1/m"
|
2022-06-03 08:09:47 -06:00
|
|
|
|
2023-02-21 09:47:52 +01:00
|
|
|
_, _, token = make_organization_and_user_with_token()
|
|
|
|
|
cache.clear()
|
2022-06-03 08:09:47 -06:00
|
|
|
|
2023-02-21 09:47:52 +01:00
|
|
|
client = APIClient()
|
2022-06-03 08:09:47 -06:00
|
|
|
|
2023-02-21 09:47:52 +01:00
|
|
|
url = reverse("api-public:alert_groups-list")
|
2022-06-03 08:09:47 -06:00
|
|
|
|
2023-02-21 09:47:52 +01:00
|
|
|
response = client.get(url, format="json", HTTP_AUTHORIZATION=f"{token}")
|
2022-06-03 08:09:47 -06:00
|
|
|
|
2023-02-21 09:47:52 +01:00
|
|
|
assert response.status_code == status.HTTP_200_OK
|
2022-06-03 08:09:47 -06:00
|
|
|
|
2023-02-21 09:47:52 +01:00
|
|
|
response = client.get(url, format="json", HTTP_AUTHORIZATION=f"{token}")
|
2022-06-03 08:09:47 -06:00
|
|
|
|
2023-02-21 09:47:52 +01:00
|
|
|
assert response.status_code == status.HTTP_429_TOO_MANY_REQUESTS
|
2022-06-03 08:09:47 -06:00
|
|
|
|
2023-02-21 09:47:52 +01:00
|
|
|
# make sure RateLimitHeadersMixin used
|
|
|
|
|
assert response.has_header("RateLimit-Reset")
|
2024-09-18 07:16:41 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db
|
|
|
|
|
def test_custom_throttling(make_organization_and_user_with_token):
|
|
|
|
|
organization_with_custom_ratelimit, _, token_with_custom_ratelimit = make_organization_and_user_with_token()
|
|
|
|
|
_, _, token_with_default_ratelimit = make_organization_and_user_with_token()
|
|
|
|
|
cache.clear()
|
|
|
|
|
|
|
|
|
|
CUSTOM_RATELIMITS_STR = (
|
|
|
|
|
'{"'
|
|
|
|
|
+ str(organization_with_custom_ratelimit.pk)
|
|
|
|
|
+ '": {"integration": "10/5m","organization": "15/5m","public_api": "1/m"}}'
|
|
|
|
|
)
|
|
|
|
|
|
2024-09-18 21:32:16 +08:00
|
|
|
with override_settings(CUSTOM_RATELIMITS=load_custom_ratelimits(CUSTOM_RATELIMITS_STR)):
|
2024-09-18 07:16:41 +08:00
|
|
|
client = APIClient()
|
|
|
|
|
|
|
|
|
|
url = reverse("api-public:alert_groups-list")
|
|
|
|
|
|
|
|
|
|
# Organization without custom ratelimit should use default ratelimit
|
|
|
|
|
for _ in range(5):
|
|
|
|
|
response = client.get(url, format="json", HTTP_AUTHORIZATION=f"{token_with_default_ratelimit}")
|
|
|
|
|
assert response.status_code == status.HTTP_200_OK
|
|
|
|
|
|
|
|
|
|
# Organization with custom ratelimit will be ratelimited after 1 request
|
|
|
|
|
response = client.get(url, format="json", HTTP_AUTHORIZATION=f"{token_with_custom_ratelimit}")
|
|
|
|
|
|
|
|
|
|
assert response.status_code == status.HTTP_200_OK
|
|
|
|
|
|
|
|
|
|
response = client.get(url, format="json", HTTP_AUTHORIZATION=f"{token_with_custom_ratelimit}")
|
|
|
|
|
|
|
|
|
|
assert response.status_code == status.HTTP_429_TOO_MANY_REQUESTS
|
|
|
|
|
|
|
|
|
|
# make sure RateLimitHeadersMixin used
|
|
|
|
|
assert response.has_header("RateLimit-Reset")
|