добавил объединение повторных активностей Clockify

This commit is contained in:
2026-07-14 15:23:02 +03:00
parent 9352a84723
commit 5dca3ae446
4 changed files with 181 additions and 14 deletions

110
tests/test_tracking.py Normal file
View File

@@ -0,0 +1,110 @@
"""Тесты агрегации активностей Clockify перед переносом в Redmine."""
from datetime import datetime
from unittest import TestCase
from unittest.mock import Mock
from classes import Activity
from services.tracking import TrackingService, aggregate_activities
class TrackingServiceTestCase(TestCase):
"""Проверяет объединение и сохранение активностей Clockify."""
def create_activity(self, activity_id: str, description: str, **changes) -> Activity:
"""Создаёт активность с типовыми значениями для теста."""
values = {
"id": activity_id,
"author_id": 1,
"vetro_project_id": "vetro-project",
"task_id": 51906,
"tag_id": "tag",
"description": description,
"project_id": "project",
"time_spent": 0.5,
"date_start": datetime(2026, 7, 14, 9),
"date_end": datetime(2026, 7, 14, 9, 30),
}
values.update(changes)
return Activity(**values)
def test_fully_matching_activities_are_merged(self):
"""Полностью одинаковые активности образуют одну запись без повтора описания."""
activities = [
self.create_activity("first", "Доработки"),
self.create_activity(
"second",
"Доработки",
date_start=datetime(2026, 7, 14, 10),
date_end=datetime(2026, 7, 14, 10, 30),
),
]
result = aggregate_activities(activities)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].time_spent, 1)
self.assertEqual(result[0].description, "Доработки")
self.assertEqual(result[0].source_activities, tuple(activities))
def test_descriptions_are_joined_for_otherwise_matching_activities(self):
"""Разные описания одинаковых активностей объединяются через точку."""
result = aggregate_activities(
[
self.create_activity("first", "Доработки"),
self.create_activity("second", "Влил в тест.", time_spent=0.25),
self.create_activity("third", "Доработки", time_spent=0.25),
]
)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].time_spent, 1)
self.assertEqual(result[0].description, "Доработки. Влил в тест")
def test_activities_for_different_dates_are_not_merged(self):
"""Активности за разные даты остаются отдельными записями Redmine."""
result = aggregate_activities(
[
self.create_activity("first", "Доработки"),
self.create_activity(
"second",
"Доработки",
date_start=datetime(2026, 7, 15, 9),
date_end=datetime(2026, 7, 15, 9, 30),
),
]
)
self.assertEqual(len(result), 2)
def test_all_source_activities_are_marked_as_tracked(self):
"""После успешной отправки сохраняются все исходные таймеры Clockify."""
activities = [
self.create_activity("first", "Доработки"),
self.create_activity("second", "Влил в тест"),
]
aggregated_activity = aggregate_activities(activities)[0]
db = Mock()
service = TrackingService(
clock=Mock(),
red=Mock(),
db=db,
is_debug=False,
)
service._save_tracked_activity(aggregated_activity)
self.assertTrue(all(activity.is_tracked for activity in activities))
db.insert_activities.assert_called_once_with(activities)
db.insert_time_entries.assert_called_once_with(activities)
def test_activities_for_different_tasks_are_not_merged(self):
"""Активности разных задач остаются отдельными записями Redmine."""
result = aggregate_activities(
[
self.create_activity("first", "Доработки"),
self.create_activity("second", "Доработки", task_id=60130),
]
)
self.assertEqual(len(result), 2)