Skip to content

Commit

Permalink
Merge branch 'refs/heads/develop' into 1003-admin-backend-management-…
Browse files Browse the repository at this point in the history
…with-search-and-filter-capabilities

# Conflicts:
#	BackEnd/administration/filters.py
#	BackEnd/administration/serializers.py
#	BackEnd/administration/views.py
  • Loading branch information
AlexanderSychev2005 committed Dec 19, 2024
2 parents 4194979 + cfb63a8 commit 2ca7879
Show file tree
Hide file tree
Showing 47 changed files with 1,335 additions and 861 deletions.
10 changes: 9 additions & 1 deletion BackEnd/administration/factories.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import factory.django

from authentication.models import CustomUser
from profiles.models import Profile
from profiles.models import Profile, Category


class AdminUserFactory(factory.django.DjangoModelFactory):
Expand Down Expand Up @@ -39,3 +39,11 @@ class Meta:
official_name = "Test official name"
startup_idea = "Test startup idea"
is_deleted = False


class AdminCategoryFactory(factory.django.DjangoModelFactory):
class Meta:
model = Category
django_get_or_create = ("name",)

name = factory.Sequence(lambda n: f"category {n + 1}")
23 changes: 17 additions & 6 deletions BackEnd/administration/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ class UsersFilter(FilterSet):
/?ordering=id asc or /?ordering=-id desc
"""

id = filters.CharFilter(lookup_expr="icontains")
id = filters.NumberFilter(lookup_expr="contains")
surname = filters.CharFilter(lookup_expr="icontains")
email = filters.CharFilter(lookup_expr="icontains")
is_active = filters.CharFilter(lookup_expr="icontains")
is_staff = filters.CharFilter(lookup_expr="icontains")
is_superuser = filters.CharFilter(lookup_expr="icontains")
is_deleted = filters.BooleanFilter(method="filter_is_deleted")
is_active = filters.BooleanFilter()
is_staff = filters.BooleanFilter()
is_superuser = filters.BooleanFilter()
is_deleted = filters.BooleanFilter(method="is_deleted_filter")
company_name = filters.CharFilter(
field_name="profile__name", lookup_expr="icontains"
)
registration_date = filters.DateFilter(
field_name="profile__created_at",
)

def filter_is_deleted(self, queryset, name, value):
def is_deleted_filter(self, queryset, name, value):
if value:
queryset = queryset.filter(email__startswith="is_deleted_")
return queryset
Expand Down Expand Up @@ -76,3 +76,14 @@ class ProfilesFilter(FilterSet):
("updated_at", "updated_at"),
)
)


class CategoriesFilter(FilterSet):
id = filters.NumberFilter(lookup_expr="contains")
name = filters.CharFilter(lookup_expr="icontains")
ordering = filters.OrderingFilter(
fields=(
("id", "id"),
("name", "name"),
)
)
30 changes: 30 additions & 0 deletions BackEnd/administration/serializers.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from django.contrib.auth import get_user_model
from rest_framework import serializers
from rest_framework.validators import UniqueValidator
from utils.administration.feedback_category import FeedbackCategory
from authentication.models import CustomUser
from profiles.models import (
Profile,
Region, Activity,
Category,
)
from utils.administration.profiles.profiles import format_company_type, format_representative, \
format_business_entity
Expand Down Expand Up @@ -242,3 +244,31 @@ class FeedbackSerializer(serializers.Serializer):
required=True,
error_messages={"required": "Please select a category."},
)


class CategoriesListSerializer(serializers.ModelSerializer):
name = serializers.CharField(
validators=[
UniqueValidator(
queryset=Category.objects.all(),
message="Category with this name already exists.",
)
]
)

class Meta:
model = Category
fields = ("id", "name")


class CategoryDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ("name",)


class StatisticsSerializer(serializers.Serializer):
companies_count = serializers.IntegerField()
investors_count = serializers.IntegerField()
startups_count = serializers.IntegerField()
blocked_companies_count = serializers.IntegerField()
100 changes: 100 additions & 0 deletions BackEnd/administration/tests/test_admin_category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
from rest_framework import status
from rest_framework.test import APITestCase

from administration.factories import (
AdminCategoryFactory,
AdminUserFactory,
)

from utils.dump_response import dump # noqa
from utils.unittest_helper import AnyInt, AnyStr


class TestAdminCategoryAPIUserNotStaff(APITestCase):
def setUp(self):
self.user = AdminUserFactory(
is_staff=False,
is_active=True,
)
self.category = AdminCategoryFactory()

def test_get_category_users_not_staff(self):
self.client.force_authenticate(self.user)
response = self.client.get(path="/api/admin/categories/")
self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code)

def test_get_category_id_users_not_staff(self):
self.client.force_authenticate(self.user)
response = self.client.get(path="/api/admin/categories/1/")
self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code)


class TestAdminCategoryAPIUserStaff(APITestCase):
def setUp(self):
self.user = AdminUserFactory(
is_staff=True,
is_active=True,
)
self.categories = AdminCategoryFactory.create_batch(2)

def test_get_categories_users_staff(self):
self.client.force_authenticate(self.user)
response = self.client.get(path="/api/admin/categories/")
data = [
{
"id": AnyInt(),
"name": AnyStr(),
},
{
"id": AnyInt(),
"name": AnyStr(),
},
]
self.assertEqual(data, response.json()["results"])
self.assertEqual(status.HTTP_200_OK, response.status_code)

def test_get_categories_id_users_staff(self):
self.client.force_authenticate(self.user)
response = self.client.get(path="/api/admin/categories/3/")
data = {"name": AnyStr()}
self.assertEqual(status.HTTP_200_OK, response.status_code)
self.assertEqual(data, response.json())

def test_post_new_categories_users_staff(self):
self.client.force_authenticate(self.user)
data = {"name": "some category"}
response = self.client.post(path="/api/admin/categories/", data=data)
self.assertEqual(status.HTTP_201_CREATED, response.status_code)
self.assertEqual(response.json()["name"], data["name"])
self.assertIn("id", response.json())

def test_post_unique_categories_users_staff(self):
self.existing_name = AdminCategoryFactory.create(
name="existing category"
)
self.client.force_authenticate(self.user)
data = {"name": "existing category"}
message = "Category with this name already exists."
response = self.client.post(path="/api/admin/categories/", data=data)
self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code)
self.assertEqual(response.json()["name"][0], message)

def test_put_categories_id_users_staff(self):
self.category = AdminCategoryFactory.create()
self.client.force_authenticate(self.user)
data = {"name": "category 1212"}
response = self.client.put(
path=f"/api/admin/categories/{self.category.id}/", data=data
)
self.assertEqual(status.HTTP_200_OK, response.status_code)
self.assertEqual(response.json()["name"], data["name"])

def test_patch_categories_id_users_staff(self):
self.category = AdminCategoryFactory.create()
self.client.force_authenticate(self.user)
data = {"name": "category 77"}
response = self.client.patch(
path=f"/api/admin/categories/{self.category.id}/", data=data
)
self.assertEqual(status.HTTP_200_OK, response.status_code)
self.assertEqual(response.json()["name"], data["name"])
15 changes: 8 additions & 7 deletions BackEnd/administration/tests/test_admin_profiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
AdminProfileFactory,
)

from utils.unittest_helper import AnyInt, AnyStr
from utils.dump_response import dump # noqa


Expand Down Expand Up @@ -52,14 +53,14 @@ def test_get_profiles_structure_json(self):
response = self.client.get(path="/api/admin/profiles/")
data = [
{
"id": 4,
"id": AnyInt(),
"name": "Test person",
"is_registered": True,
"is_startup": True,
"person": {
"name": "Test person 7",
"surname": "Test person 7 surname",
"email": "[email protected]",
"name": AnyStr(),
"surname": AnyStr(),
"email": AnyStr(),
"is_active": True,
"is_staff": True,
"is_superuser": False,
Expand Down Expand Up @@ -89,9 +90,9 @@ def test_get_profile_id_authenticated(self):
"categories": [],
"activities": [],
"person": {
"name": "Test person 1",
"surname": "Test person 1 surname",
"email": "[email protected]",
"name": AnyStr(),
"surname": AnyStr(),
"email": AnyStr(),
"is_active": True,
"is_staff": True,
"is_superuser": False,
Expand Down
49 changes: 49 additions & 0 deletions BackEnd/administration/tests/test_profile_statistics.py
Original file line number Diff line number Diff line change
@@ -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)
18 changes: 18 additions & 0 deletions BackEnd/administration/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
ContactsView,
ProfilesListView,
ProfileDetailView,
ProfileStatisticsView,
UsersListView,
UserDetailView,
AutoModerationHoursView,
ModerationEmailView,
FeedbackView,
CreateAdminUserView,
CategoriesListView,
CategoryDetailView,
SendMessageView,
)

Expand All @@ -19,6 +22,11 @@
path("users/", UsersListView.as_view(), name="users-list"),
path("users/<pk>/", 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/<pk>/", ProfileDetailView.as_view(), name="profile-detail"),
path(
"automoderation/",
Expand All @@ -29,6 +37,16 @@
path("contacts/", ContactsView.as_view(), name="contacts"),
path("feedback/", FeedbackView.as_view(), name="feedback"),
path("admin_create/", CreateAdminUserView.as_view(), name="admin-create"),
path(
"categories/",
CategoriesListView.as_view(),
name="categories",
),
path(
"categories/<pk>/",
CategoryDetailView.as_view(),
name="category_detail",
),
path(
"users/<pk>/send_message/",
SendMessageView.as_view(),
Expand Down
Loading

0 comments on commit 2ca7879

Please sign in to comment.