Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/tasks signals #51

Merged
merged 17 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,4 @@ Thumbs.db
/collected_static/
.vscode
/static/
# Миграции убраны из git. Т.к. до существования БД проще без них.
# Миграции убраны из git. Т.к. до существования БД проще без них.
2 changes: 1 addition & 1 deletion api/v1/serializers/api/ipr_serializers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from django.contrib.auth import get_user_model
from rest_framework import serializers

from api.v1.serializers.api.task_serializer import TaskSerializer
from api.v1.serializers.api.users_serializer import CustomUserSerializer
from api.v1.serializers.task import TaskSerializer
from core.statuses import Status
from ipr.models import IPR

Expand Down
43 changes: 43 additions & 0 deletions api/v1/serializers/api/task_serializer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from django.contrib.auth import get_user_model
from rest_framework import serializers

from tasks.models import Task

User = get_user_model()


class TaskSerializer(serializers.ModelSerializer):
class Meta:
fields = (
"id",
"name",
"description",
"creator",
"creation_date",
"start_date",
"end_date",
"status",
"ipr",
"skill",
)
model = Task


class TaskSerializerPost(serializers.ModelSerializer):
creator = serializers.PrimaryKeyRelatedField(read_only=True)

class Meta:
fields = (
"id",
"name",
"description",
"creator",
"executor",
"creation_date",
"start_date",
"end_date",
"status",
"ipr",
"skill",
)
model = Task
24 changes: 0 additions & 24 deletions api/v1/serializers/task.py

This file was deleted.

113 changes: 113 additions & 0 deletions api/v1/tests/test_tasks_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
from django.contrib.auth import get_user_model
from django.urls import reverse
from django.utils import timezone
from rest_framework import status
from rest_framework.test import APIClient, APITestCase

from ipr.models import IPR
from tasks.models import Task

User = get_user_model()


class TaskAPITests(APITestCase):
def setUp(self):
self.user1 = User.objects.create_user(
username="user1",
email="[email protected]",
password="password",
)
self.user2 = User.objects.create_user(
username="user2",
email="[email protected]",
password="password",
)
self.client = APIClient()
self.client.force_authenticate(user=self.user2)
self.ipr = IPR.objects.create(
title="Test IPR",
creation_date=timezone.now().date(),
start_date=(timezone.now() + timezone.timedelta(days=1)).date(),
end_date=(timezone.now() + timezone.timedelta(days=2)).date(),
creator=self.user1,
executor=self.user2,
)
self.task1 = Task.objects.create(
name="Task 1",
description="Description 1",
creator=self.user1,
executor=self.user2,
creation_date=timezone.now().date(),
start_date=(timezone.now() + timezone.timedelta(days=1)).date(),
end_date=(timezone.now() + timezone.timedelta(days=2)).date(),
ipr=self.ipr,
)
self.task2 = Task.objects.create(
name="Task 2",
description="Description 2",
creator=self.user1,
executor=self.user2,
creation_date=timezone.now().date(),
start_date=(timezone.now() + timezone.timedelta(days=1)).date(),
end_date=(timezone.now() + timezone.timedelta(days=2)).date(),
ipr=self.ipr,
)

def test_get_tasks_list(self):
"""
Проверка получения списка задач (GET)
"""
url = reverse("tasks-list")
response = self.client.get(url)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data), Task.objects.count())

def test_create_task(self):
"""
Проверка создания новой задачи (POST)
"""
url = reverse("tasks-list")
data = {
"name": "New Task",
"description": "New Description",
"creator": self.user1.id,
"creation_date": timezone.now().date(),
"start_date": (timezone.now() + timezone.timedelta(days=1)).date(),
"end_date": (timezone.now() + timezone.timedelta(days=2)).date(),
"executor": self.user2.id,
"ipr": self.ipr.id,
}
response = self.client.post(url, data, format="json")

self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Task.objects.count(), 3)

def test_update_task(self):
"""
Проверка обновления задачи (PATCH)
"""
task_id = self.task2.pk
url = reverse("tasks-detail", kwargs={"pk": task_id})
data = {
"name": "Updated Task",
"description": "Updated Description",
"start_date": (timezone.now() + timezone.timedelta(days=4)).date(),
"end_date": (timezone.now() + timezone.timedelta(days=6)).date(),
}
response = self.client.patch(url, data, format="json")

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.task2.refresh_from_db()
self.assertEqual(self.task2.name, "Updated Task")

def test_delete_task(self):
"""
Проверка удаления задачи (DELETE)
"""
task_id = self.task2.pk
url = reverse("tasks-detail", kwargs={"pk": task_id})
response = self.client.delete(url)

self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
self.assertEqual(Task.objects.count(), 1)
12 changes: 6 additions & 6 deletions api/v1/tests/tests_notifications_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ def setUp(self):
self.ipr1 = IPR.objects.create(
title="Test IPR",
creator=self.creator,
creation_date=timezone.now(),
start_date=timezone.now() + timezone.timedelta(days=1),
end_date=timezone.now() + timezone.timedelta(days=2),
creation_date=timezone.now().date(),
start_date=(timezone.now() + timezone.timedelta(days=1)).date(),
end_date=(timezone.now() + timezone.timedelta(days=2)).date(),
status=Status.IN_PROGRESS,
executor=self.executor,
)
Expand All @@ -49,9 +49,9 @@ def setUp(self):
self.ipr2 = IPR.objects.create(
title="Test IPR",
creator=self.creator,
creation_date=timezone.now(),
start_date=timezone.now() + timezone.timedelta(days=1),
end_date=timezone.now() + timezone.timedelta(days=2),
creation_date=timezone.now().date(),
start_date=(timezone.now() + timezone.timedelta(days=1)).date(),
end_date=(timezone.now() + timezone.timedelta(days=2)).date(),
status=Status.IN_PROGRESS,
executor=self.executor,
)
Expand Down
2 changes: 1 addition & 1 deletion api/v1/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from api.v1.views.ipr_views import IPRViewSet
from api.v1.views.notifications_view import NotificationViewSet
from api.v1.views.ratings_view import IPRRatingCreateView, TaskRatingCreateView
from api.v1.views.task import TaskViewSet
from api.v1.views.task_views import TaskViewSet
from api.v1.views.users_view import UserViewSet

v1_router = routers.DefaultRouter()
Expand Down
12 changes: 0 additions & 12 deletions api/v1/views/task.py

This file was deleted.

55 changes: 55 additions & 0 deletions api/v1/views/task_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from django.contrib.auth import get_user_model
from drf_spectacular.utils import extend_schema, extend_schema_view
from rest_framework import viewsets

from api.v1.serializers.api.task_serializer import (
TaskSerializer,
TaskSerializerPost,
)
from tasks.models import Task

User = get_user_model()


@extend_schema(tags=["Задачи"])
@extend_schema_view(
list=extend_schema(
summary="Список задач", description="Описание списка задач."
),
retrieve=extend_schema(
summary="Получение задачи", description="Описание получения задачи."
),
create=extend_schema(
summary="Создание задачи", description="Описание создания задачи."
),
partial_update=extend_schema(
summary="Частичное обновление задачи",
description="Описание частичного обновления задачи.",
),
)
class TaskViewSet(viewsets.ModelViewSet):
queryset = Task.objects.all()
serializer_class = TaskSerializer
http_method_names = [
"get",
"post",
"patch",
"delete",
"head",
"options",
]

def get_queryset(self):
if self.request.query_params.get("user_id"):
return Task.objects.filter(
executor=self.request.query_params.get("user_id")
)
return self.request.user.tasks.all()

def get_serializer_class(self):
if self.request.method in ("POST", "PATCH"):
return TaskSerializerPost
return TaskSerializer

def perform_create(self, serializer):
serializer.save(creator=self.request.user)
15 changes: 14 additions & 1 deletion core/signals.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.db.models.signals import post_save
from django.db.models.signals import post_init, post_save
from django.dispatch import receiver
from django.utils import timezone
from notifications.signals import notify

from core.statuses import Status
Expand Down Expand Up @@ -71,3 +72,15 @@ def created_task_notification(sender, instance: Task, created, **kwargs):
verb=text,
target=instance,
)


@receiver(post_init, sender=Task)
@receiver(post_init, sender=IPR)
def set_delayed_status(sender, instance, **kwargs):
if (
instance.end_date
and instance.end_date < timezone.localdate()
and instance.status != Status.TRAIL
):
instance.status = Status.TRAIL
instance.save()
5 changes: 5 additions & 0 deletions core/statuses.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ class Status(models.TextChoices):
IN_PROGRESS = "in_progress", "В работе"
CANCEL = "cancel", "Отменен"
TRAIL = "trail", "Отстает"


class Skill(models.TextChoices):
HARD = "hard", "Hard skill"
SOFT = "soft", "Soft skill"
Loading
Loading