️(api) add missing cache for stats endpoint

Add cache to display stats for anonymous
and improve some code.
This commit is contained in:
Sabrina Demagny
2025-01-23 17:57:35 +01:00
parent e09e1d1b80
commit c48957612b
3 changed files with 36 additions and 10 deletions

View File

@@ -12,6 +12,10 @@ and this project adheres to
- ✨(scripts) adapts release script after moving the deployment part
### Fixed
- ⚡️(api) add missing cache for stats endpoint
## [1.10.0] - 2025-01-21
### Added

View File

@@ -7,6 +7,8 @@ from functools import reduce
from django.conf import settings
from django.db.models import OuterRef, Q, Subquery, Value
from django.db.models.functions import Coalesce
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
from rest_framework import (
decorators,
@@ -28,8 +30,6 @@ from core.utils.raw_sql import gen_sql_filter_json_array
from mailbox_manager import models as domains_models
SIMILARITY_THRESHOLD = 0.04
class NestedGenericViewSet(viewsets.GenericViewSet):
"""
@@ -596,19 +596,20 @@ class StatView(views.APIView):
permission_classes = [AllowAny]
@method_decorator(cache_page(3600))
def get(self, request):
"""
GET /api/v1.0/stats/
Return a dictionary of public metrics.
"""
context = {
"total_users": models.User.objects.all().count(),
"total_users": models.User.objects.count(),
"mau": models.User.objects.filter(
last_login__gte=datetime.datetime.now() - datetime.timedelta(30)
).count(),
"teams": models.Team.objects.all().count(),
"domains": domains_models.MailDomain.objects.all().count(),
"mailboxes": domains_models.Mailbox.objects.all().count(),
"teams": models.Team.objects.count(),
"domains": domains_models.MailDomain.objects.count(),
"mailboxes": domains_models.Mailbox.objects.count(),
}
return response.Response(context)

View File

@@ -2,6 +2,8 @@
Test stats endpoint
"""
from django.core.cache import cache
import pytest
from rest_framework import status
from rest_framework.test import APIClient
@@ -14,17 +16,34 @@ from mailbox_manager import models as domains_models
pytestmark = pytest.mark.django_db
def test_api_stats__anonymous():
def test_api_stats__anonymous(django_assert_num_queries):
"""Stats endpoint should be available even when not connected."""
domains_factories.MailDomainFactory.create_batch(5)
core_factories.TeamFactory.create_batch(3)
# clear cache to allow stats count
cache.clear()
with django_assert_num_queries(5):
response = APIClient().get("/api/v1.0/stats/")
assert response.status_code == status.HTTP_200_OK
assert response.json() == {
"total_users": 0,
"mau": 0,
"domains": 0,
"domains": 5,
"mailboxes": 0,
"teams": 0,
"teams": 3,
}
# no new request made due to caching
with django_assert_num_queries(0):
response = APIClient().get("/api/v1.0/stats/")
assert response.status_code == status.HTTP_200_OK
assert response.json() == {
"total_users": 0,
"mau": 0,
"domains": 5,
"mailboxes": 0,
"teams": 3,
}
@@ -43,6 +62,8 @@ def test_api_stats__expected_count():
10, domain=domains_models.MailDomain.objects.all()[1]
)
# clear cache to allow stats count
cache.clear()
response = APIClient().get("/api/v1.0/stats/")
assert response.status_code == status.HTTP_200_OK
assert response.json() == {