from datetime import timedelta import pytest from django.utils import timezone from rest_framework.exceptions import ValidationError from apps.projects.models import Project from apps.tags.models import Tag from apps.time_entries.services.time_entries import create_time_entry, stop_time_entry, update_time_entry from apps.users.models import User from apps.workspaces.models import Workspace @pytest.fixture def workspace_owner(db): user = User.objects.create_user(mobile="09121111111", password="secret123") workspace = Workspace.objects.create(name="Core", owner=user) return user, workspace def test_create_time_entry_allows_only_one_running_timer_per_workspace(workspace_owner): user, workspace = workspace_owner create_time_entry( user=user, workspace_id=workspace.id, start_time=timezone.now(), ) with pytest.raises(ValidationError): create_time_entry( user=user, workspace_id=workspace.id, start_time=timezone.now() + timedelta(minutes=5), ) def test_stop_time_entry_sets_end_time_and_duration(workspace_owner): user, workspace = workspace_owner entry = create_time_entry( user=user, workspace_id=workspace.id, start_time=timezone.now() - timedelta(hours=1), ) stopped_entry = stop_time_entry(entry, end_time=timezone.now()) assert stopped_entry.end_time is not None assert stopped_entry.duration is not None def test_update_time_entry_preserves_deleted_project_and_tags(workspace_owner): user, workspace = workspace_owner project = Project.objects.create(workspace=workspace, name="Deleted project") tag = Tag.objects.create(workspace=workspace, name="Deleted tag", color="#0f172a") entry = create_time_entry( user=user, workspace_id=workspace.id, start_time=timezone.now() - timedelta(hours=1), end_time=timezone.now(), project=project, tags=[tag], description="Before delete", ) project.delete() tag.delete() updated_entry = update_time_entry( entry, project=Project.all_objects.get(id=project.id), tags=[Tag.all_objects.get(id=tag.id)], description="After delete", ) assert updated_entry.description == "After delete" assert updated_entry.project_id == project.id assert list(Tag.all_objects.filter(time_entries=updated_entry).values_list("id", flat=True)) == [tag.id]