feat(reports): refine exports and restore project access

This commit is contained in:
2026-05-14 17:06:35 +03:30
parent 77c07adec8
commit d4a52d6f3b
16 changed files with 1594 additions and 136 deletions

View File

@@ -3,10 +3,11 @@ from datetime import datetime
from django.utils import timezone
from rest_framework.test import APITestCase
from apps.projects.models import Project, ProjectAccess
from apps.tags.models import Tag
from apps.time_entries.models import TimeEntry
from apps.users.models import User
from apps.workspaces.models import Workspace
from apps.workspaces.models import Workspace, WorkspaceMembership
def make_aware(year, month, day, hour=9, minute=0, second=0):
@@ -139,3 +140,62 @@ class TimeEntryViewTests(APITestCase):
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data["tags"], [])
def test_member_cannot_create_time_entry_for_inaccessible_project(self):
owner = User.objects.create_user(mobile="09120000001", password="secret123")
member = User.objects.create_user(mobile="09120000002", password="secret123")
workspace = Workspace.objects.create(name="Core", owner=owner)
WorkspaceMembership.objects.create(
workspace=workspace,
user=member,
role=WorkspaceMembership.Role.MEMBER,
is_active=True,
)
project = Project.objects.create(workspace=workspace, name="Restricted")
self.client.force_authenticate(user=member)
response = self.client.post(
"/api/time-entries/",
{
"workspace_id": str(workspace.id),
"project_id": str(project.id),
"description": "Blocked",
"start_time": make_aware(2026, 4, 24, 9, 0, 0).isoformat(),
"end_time": make_aware(2026, 4, 24, 10, 0, 0).isoformat(),
},
format="json",
)
self.assertEqual(response.status_code, 400)
self.assertTrue(
any("Selected project is unavailable." in item["message"] for item in response.data["messages"])
)
def test_member_can_create_time_entry_after_project_access_is_granted(self):
owner = User.objects.create_user(mobile="09120000011", password="secret123")
member = User.objects.create_user(mobile="09120000012", password="secret123")
workspace = Workspace.objects.create(name="Core", owner=owner)
WorkspaceMembership.objects.create(
workspace=workspace,
user=member,
role=WorkspaceMembership.Role.MEMBER,
is_active=True,
)
project = Project.objects.create(workspace=workspace, name="Accessible")
ProjectAccess.objects.create(project=project, user=member)
self.client.force_authenticate(user=member)
response = self.client.post(
"/api/time-entries/",
{
"workspace_id": str(workspace.id),
"project_id": str(project.id),
"description": "Allowed",
"start_time": make_aware(2026, 4, 24, 9, 0, 0).isoformat(),
"end_time": make_aware(2026, 4, 24, 10, 0, 0).isoformat(),
},
format="json",
)
self.assertEqual(response.status_code, 201)
self.assertEqual(response.data["project"], str(project.id))