Files
timerr/apps/tasks/test_tasks.py
T

99 lines
5.1 KiB
Python

from datetime import date
from decimal import Decimal
from django.test import TestCase
from django.urls import reverse
from django.utils import timezone
from apps.accounts.models import User
from apps.companies.models import Company
from apps.projects.models import Project, ProjectMember
from .models import Task
class TaskAccessTests(TestCase):
def setUp(self):
self.worker = User.objects.create_user(username="worker", password="password123", must_change_password=False)
self.other = User.objects.create_user(username="other", password="password123", must_change_password=False)
self.admin = User.objects.create_user(username="admin", password="password123", role=User.Role.ADMIN, must_change_password=False)
self.company = Company.objects.create(name="Клиент")
self.project = Project.objects.create(company=self.company, name="Проект")
ProjectMember.objects.create(project=self.project, user=self.worker, hourly_rate=Decimal("1000.00"))
ProjectMember.objects.create(project=self.project, user=self.other, hourly_rate=Decimal("1200.00"))
self.task = Task.objects.create(
project=self.project, assignee=self.other, title="Чужая задача", description="Описание",
work_date=date(2026, 7, 14), duration_minutes=60, hourly_rate=Decimal("1200.00"),
amount=Decimal("1200.00"), created_by=self.other,
)
def test_worker_sees_only_own_tasks(self):
self.client.force_login(self.worker)
response = self.client.get(reverse("task-list"))
self.assertNotContains(response, "Чужая задача")
def test_worker_cannot_edit_another_users_task(self):
self.client.force_login(self.worker)
response = self.client.get(reverse("task-edit", args=(self.task.pk,)))
self.assertEqual(response.status_code, 403)
def test_create_copies_rate_and_calculates_rounded_amount(self):
self.client.force_login(self.worker)
response = self.client.post(reverse("task-create"), {
"project": self.project.pk, "assignee": self.worker.pk, "title": "Работа",
"description": "Сделано", "work_date": "2026-07-14", "duration_hours": 1,
"duration_minutes_input": 1,
"status": Task.Status.COMPLETED,
})
self.assertRedirects(response, reverse("task-list"))
task = Task.objects.get(title="Работа")
self.assertEqual(task.hourly_rate, Decimal("1000.00"))
self.assertEqual(task.amount, Decimal("1016.67"))
def test_admin_can_see_all_tasks(self):
self.client.force_login(self.admin)
response = self.client.get(reverse("task-list"))
self.assertContains(response, "Чужая задача")
def test_new_task_defaults_to_current_date(self):
self.client.force_login(self.worker)
response = self.client.get(reverse("task-create"))
self.assertEqual(response.context["form"].fields["work_date"].initial, timezone.localdate())
self.assertContains(response, f'value="{timezone.localdate():%Y-%m-%d}"')
def test_existing_task_renders_work_date_in_browser_format(self):
self.client.force_login(self.other)
response = self.client.get(reverse("task-edit", args=(self.task.pk,)))
self.assertContains(response, 'value="2026-07-14"')
def test_duration_must_be_greater_than_zero(self):
self.client.force_login(self.worker)
response = self.client.post(reverse("task-create"), {
"project": self.project.pk, "assignee": self.worker.pk, "title": "Работа",
"description": "Сделано", "work_date": "2026-07-14", "duration_hours": 0,
"duration_minutes_input": 0, "status": Task.Status.COMPLETED,
})
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Укажите продолжительность больше нуля")
def test_duration_edit_keeps_rate_snapshot(self):
own_task = Task.objects.create(
project=self.project, assignee=self.worker, title="Старая работа", description="Описание",
work_date=date(2026, 7, 14), duration_minutes=60, hourly_rate=Decimal("1000.00"),
amount=Decimal("1000.00"), created_by=self.worker,
)
membership = ProjectMember.objects.get(project=self.project, user=self.worker)
membership.hourly_rate = Decimal("2000.00")
membership.save()
self.client.force_login(self.worker)
response = self.client.post(reverse("task-edit", args=(own_task.pk,)), {
"project": self.project.pk, "assignee": self.worker.pk, "title": own_task.title,
"description": own_task.description, "work_date": "2026-07-14", "duration_hours": 2,
"duration_minutes_input": 0,
"status": Task.Status.COMPLETED,
})
self.assertRedirects(response, reverse("task-list"))
own_task.refresh_from_db()
self.assertEqual(own_task.hourly_rate, Decimal("1000.00"))
self.assertEqual(own_task.amount, Decimal("2000.00"))