from django.test import TestCase from rest_framework.exceptions import PermissionDenied, ValidationError from apps.clients.models import Client from apps.projects.models import Project from apps.projects.services.projects import ( create_project, toggle_project_archive, update_project, ) from apps.users.models import User from apps.workspaces.models import Workspace, WorkspaceMembership class ProjectServiceTests(TestCase): @classmethod def setUpTestData(cls): cls.owner = User.objects.create_user(mobile="09120000041", password="secret123") cls.member = User.objects.create_user(mobile="09120000042", password="secret123") cls.outsider = User.objects.create_user(mobile="09120000043", password="secret123") cls.workspace = Workspace.objects.create(name="Projects Services", owner=cls.owner) WorkspaceMembership.objects.create( workspace=cls.workspace, user=cls.member, role=WorkspaceMembership.Role.MEMBER, is_active=True, ) cls.account_client = Client.objects.create(workspace=cls.workspace, name="Acme") def test_create_project_creates_workspace_shared_project(self): project = create_project( user=self.member, workspace=self.workspace, name="Alpha", client=self.account_client, description="Desc", color="#123456", ) self.assertEqual(project.name, "Alpha") self.assertEqual(project.client, self.account_client) self.assertEqual(project.description, "Desc") def test_create_project_rejects_non_member(self): with self.assertRaises(PermissionDenied): create_project(self.outsider, self.workspace, "Alpha") def test_create_project_rejects_duplicate_name(self): Project.objects.create(workspace=self.workspace, name="Alpha") with self.assertRaises(ValidationError) as exc: create_project(self.owner, self.workspace, "Alpha") self.assertIn("name", exc.exception.detail) def test_update_project_updates_client_and_fields(self): second_client = Client.objects.create(workspace=self.workspace, name="Globex") project = Project.objects.create( workspace=self.workspace, name="Alpha", client=self.account_client, ) updated = update_project( project, name="Beta", client=str(second_client.id), description="Updated", color="#abcdef", ) self.assertEqual(updated.name, "Beta") self.assertEqual(updated.client, second_client) self.assertEqual(updated.description, "Updated") self.assertEqual(updated.color, "#abcdef") def test_update_project_rejects_duplicate_name(self): Project.objects.create(workspace=self.workspace, name="Beta") project = Project.objects.create( workspace=self.workspace, name="Alpha", client=self.account_client, ) with self.assertRaises(ValidationError) as exc: update_project(project, name="Beta", client=str(self.account_client.id)) self.assertIn("name", exc.exception.detail) def test_toggle_project_archive_flips_state(self): project = Project.objects.create(workspace=self.workspace, name="Alpha") toggle_project_archive(project) self.assertTrue(Project.objects.get(id=project.id).is_archived) toggle_project_archive(project) self.assertFalse(Project.objects.get(id=project.id).is_archived)