Skip to content
2 changes: 1 addition & 1 deletion api/organisations/task_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def handle_api_usage_notification_for_organisation(organisation: Organisation) -
month_delta = _get_total_months(relativedelta(now, billing_starts_at))
period_starts_at = relativedelta(months=month_delta) + billing_starts_at

allowed_api_calls = subscription_cache.allowed_30d_api_calls
allowed_api_calls = organisation.subscription.max_api_calls

Comment thread
srijantrpth marked this conversation as resolved.
openfeature_client = get_openfeature_client()
# TODO: Default to get_total_events_count — https://github.com/Flagsmith/flagsmith/issues/6985
Expand Down
2 changes: 1 addition & 1 deletion api/organisations/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def handle_api_usage_notifications() -> None:
# threshold in the last 30d, it must be below it for the current billing period
# (which by definition is <30d).
subscription_information_cache__api_calls_30d__gte=F(
"subscription_information_cache__allowed_30d_api_calls"
"subscription__max_api_calls"
)
* threshold_percentage,
).select_related("subscription", "subscription_information_cache"):
Expand Down
60 changes: 60 additions & 0 deletions api/tests/unit/organisations/test_unit_organisations_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ def test_handle_api_usage_notifications__usage_below_100_percent__sends_90_perce
now = timezone.now()
organisation.subscription.plan = SCALE_UP
organisation.subscription.subscription_id = "fancy_id"
organisation.subscription.max_api_calls = 100
organisation.subscription.save()
OrganisationSubscriptionInformationCache.objects.create(
organisation=organisation,
Expand Down Expand Up @@ -530,6 +531,61 @@ def test_handle_api_usage_notifications__usage_below_100_percent__sends_90_perce
)


@pytest.mark.freeze_time("2023-01-19T09:09:47.325132+00:00")
def test_handle_api_usage_notifications__stale_cache_lower_than_subscription_limit__sends_no_email(
mocker: MockerFixture,
organisation: Organisation,
mailoutbox: list[EmailMultiAlternatives],
enable_features: EnableFeaturesFixture,
) -> None:
# Given
now = timezone.now()
usage = 95
stale_cache_allowance = 100
true_subscription_allowance = 50_000

# 1. Set the TRUE subscription limit to 50,000
organisation.subscription.plan = SCALE_UP
organisation.subscription.subscription_id = "fancy_id"
organisation.subscription.max_api_calls = true_subscription_allowance
organisation.subscription.save()

# 2. Set the STALE cache limit to 100
OrganisationSubscriptionInformationCache.objects.create(
organisation=organisation,
allowed_30d_api_calls=stale_cache_allowance,
current_billing_term_starts_at=now - timedelta(days=45),
current_billing_term_ends_at=now + timedelta(days=320),
api_calls_30d=usage,
)

mock_api_usage = mocker.patch(
"organisations.task_helpers.get_current_api_usage",
)
mock_api_usage.return_value = usage
enable_features("api_usage_alerting")

assert not OrganisationAPIUsageNotification.objects.filter(
organisation=organisation,
).exists()

# When
handle_api_usage_notifications()

# Then
# Because usage (95) is evaluated against the true allowance (50,000),
# it is < 1%, so no notification should be sent.
mock_api_usage.assert_not_called()
assert len(mailoutbox) == 0

assert (
OrganisationAPIUsageNotification.objects.filter(
organisation=organisation,
).count()
== 0
)


@pytest.mark.freeze_time("2023-01-19T09:09:47.325132+00:00")
def test_handle_api_usage_notifications__usage_below_alert_thresholds__sends_no_email(
mocker: MockerFixture,
Expand Down Expand Up @@ -592,6 +648,7 @@ def test_handle_api_usage_notifications__usage_above_100_percent__sends_limit_no
now = timezone.now()
organisation.subscription.plan = SCALE_UP
organisation.subscription.subscription_id = "fancy_id"
organisation.subscription.max_api_calls = allowance
organisation.subscription.save()
OrganisationSubscriptionInformationCache.objects.create(
organisation=organisation,
Expand Down Expand Up @@ -680,6 +737,7 @@ def test_handle_api_usage_notifications__processing_error__logs_error_message(
now = timezone.now()
organisation.subscription.plan = SCALE_UP
organisation.subscription.subscription_id = "fancy_id"
organisation.subscription.max_api_calls = 100
organisation.subscription.save()
OrganisationSubscriptionInformationCache.objects.create(
organisation=organisation,
Expand Down Expand Up @@ -735,6 +793,8 @@ def test_handle_api_usage_notifications__free_account_over_limit__sends_limit_no
assert organisation.is_paid is False
assert organisation.subscription.is_free_plan is True
assert organisation.subscription.max_api_calls == MAX_API_CALLS_IN_FREE_PLAN
organisation.subscription.max_api_calls = MAX_API_CALLS_IN_FREE_PLAN
organisation.subscription.save()

OrganisationSubscriptionInformationCache.objects.create(
organisation=organisation,
Expand Down
Loading