diff --git a/BackEnd/administration/serializers.py b/BackEnd/administration/serializers.py index 24cda9be..2e2eb69a 100644 --- a/BackEnd/administration/serializers.py +++ b/BackEnd/administration/serializers.py @@ -213,3 +213,10 @@ class FeedbackSerializer(serializers.Serializer): required=True, error_messages={"required": "Please select a category."}, ) + + +class StatisticsSerializer(serializers.Serializer): + companies_count = serializers.IntegerField() + investors_count = serializers.IntegerField() + startups_count = serializers.IntegerField() + blocked_companies_count = serializers.IntegerField() diff --git a/BackEnd/administration/tests/test_profile_statistics.py b/BackEnd/administration/tests/test_profile_statistics.py new file mode 100644 index 00000000..ced04d30 --- /dev/null +++ b/BackEnd/administration/tests/test_profile_statistics.py @@ -0,0 +1,49 @@ +from rest_framework.test import APITestCase +from rest_framework import status + +from administration.factories import AdminUserFactory, AdminProfileFactory + + +class TestProfileStatisticsStaff(APITestCase): + def setUp(self): + self.user = AdminUserFactory() + self.client.force_authenticate(self.user) + self.test_startup_user = AdminUserFactory(is_staff=False) + self.test_investor_user = AdminUserFactory(is_staff=False) + self.test_blocked_company_user = AdminUserFactory(is_staff=False) + self.startup_company = AdminProfileFactory( + person_id=self.test_startup_user.id, is_registered=False + ) + self.investor_company = AdminProfileFactory( + person_id=self.test_investor_user.id, is_startup=False + ) + self.blocked_company = AdminProfileFactory( + person_id=self.test_blocked_company_user.id, status="blocked" + ) + + def test_get_profile_statistics(self): + response = self.client.get("/api/admin/profiles/statistics/") + data = { + "companies_count": 3, + "investors_count": 2, + "startups_count": 2, + "blocked_companies_count": 1, + } + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data, data) + + +class TestProfileStatisticsNotStaff(APITestCase): + def setUp(self): + self.user = AdminUserFactory(is_staff=False) + self.client.force_authenticate(self.user) + + def test_get_profile_statistics(self): + response = self.client.get("/api/admin/profiles/statistics/") + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + +class TestProfileStatisticsUnauthorized(APITestCase): + def test_get_profile_statistics(self): + response = self.client.get("/api/admin/profiles/statistics/") + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) diff --git a/BackEnd/administration/urls.py b/BackEnd/administration/urls.py index b71b9695..274876da 100644 --- a/BackEnd/administration/urls.py +++ b/BackEnd/administration/urls.py @@ -4,6 +4,7 @@ ContactsView, ProfilesListView, ProfileDetailView, + ProfileStatisticsView, UsersListView, UserDetailView, AutoModerationHoursView, @@ -19,6 +20,11 @@ path("users/", UsersListView.as_view(), name="users-list"), path("users//", UserDetailView.as_view(), name="user-detail"), path("profiles/", ProfilesListView.as_view(), name="profile-list"), + path( + "profiles/statistics/", + ProfileStatisticsView.as_view(), + name="profile-statistics", + ), path("profiles//", ProfileDetailView.as_view(), name="profile-detail"), path( "automoderation/", diff --git a/BackEnd/administration/views.py b/BackEnd/administration/views.py index 52db67f0..63deee64 100644 --- a/BackEnd/administration/views.py +++ b/BackEnd/administration/views.py @@ -1,5 +1,8 @@ from django.http import JsonResponse from django.views import View +from django.db.models import Count, Q +from django_filters.rest_framework import DjangoFilterBackend + from drf_spectacular.utils import ( extend_schema, OpenApiExample, @@ -7,6 +10,7 @@ ) from rest_framework.generics import ( ListAPIView, + RetrieveAPIView, RetrieveUpdateDestroyAPIView, RetrieveUpdateAPIView, CreateAPIView, @@ -21,6 +25,7 @@ AdminUserDetailSerializer, AutoModerationHoursSerializer, ModerationEmailSerializer, + StatisticsSerializer, ) from administration.pagination import ListPagination from administration.models import AutoModeration, ModerationEmail @@ -30,8 +35,6 @@ from .serializers import FeedbackSerializer from utils.administration.send_email_feedback import send_email_feedback from utils.administration.send_email_notification import send_email_to_user - -from django_filters.rest_framework import DjangoFilterBackend from .filters import UsersFilter @@ -104,6 +107,23 @@ class ProfileDetailView(RetrieveUpdateDestroyAPIView): ) +class ProfileStatisticsView(RetrieveAPIView): + """ + Count of companies + """ + + permission_classes = [IsStaffUser] + serializer_class = StatisticsSerializer + + def get_object(self): + return Profile.objects.aggregate( + companies_count=Count("pk"), + investors_count=Count("pk", filter=Q(is_registered=True)), + startups_count=Count("pk", filter=Q(is_startup=True)), + blocked_companies_count=Count("pk", filter=Q(status="blocked")), + ) + + @extend_schema( request=AutoModerationHoursSerializer, responses={ diff --git a/BackEnd/profiles/tests/test_ordering.py b/BackEnd/profiles/tests/test_ordering.py index 0b410f0f..6bc36057 100644 --- a/BackEnd/profiles/tests/test_ordering.py +++ b/BackEnd/profiles/tests/test_ordering.py @@ -156,8 +156,8 @@ def test_get_list_of_profiles_completeness_order_asc(self): self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertEqual( [ - "Bakery", "Winery", + "Bakery", "Delivery company", "Catering service", "Retail company",