init
This commit is contained in:
121 files changed
+17641
No files matched your search
@@ -0,0 +1,99 @@
|
||||
"""Metrics, achievements and the rendered report."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
from app.models import utcnow
|
||||
from app.services import pomodoro, report, settings_service, stats, tasks_service
|
||||
from app.timeutil import local_date
|
||||
|
||||
|
||||
def _run_pomodoros(session, settings, count: int, *, minutes: int = 25) -> None:
|
||||
"""Record `count` finished work intervals, backdated so they do not overlap."""
|
||||
for index in range(count):
|
||||
row = pomodoro.start(session, settings, kind="work", minutes=minutes)
|
||||
start = utcnow() - timedelta(minutes=(count - index) * (minutes + 5))
|
||||
row.started_at = start
|
||||
row.ended_at = start + timedelta(minutes=minutes)
|
||||
row.actual_seconds = minutes * 60
|
||||
row.status = "completed"
|
||||
session.commit()
|
||||
|
||||
|
||||
def test_day_metrics_counts_what_happened(session, settings):
|
||||
_run_pomodoros(session, settings, 3)
|
||||
metrics = stats.day_metrics(session, settings, local_date(settings.timezone))
|
||||
assert metrics["pomodoros"] == 3
|
||||
assert metrics["focus_minutes"] == 75
|
||||
assert metrics["goal"] == settings.pomodoro.daily_goal_pomodoros
|
||||
assert metrics["first_start"] and metrics["last_end"]
|
||||
|
||||
|
||||
def test_longest_stretch_joins_adjacent_pomodoros(session, settings):
|
||||
_run_pomodoros(session, settings, 3, minutes=25)
|
||||
metrics = stats.day_metrics(session, settings, local_date(settings.timezone))
|
||||
# 25-minute intervals five minutes apart are one unbroken stretch.
|
||||
assert metrics["longest_stretch_minutes"] >= 75
|
||||
|
||||
|
||||
def test_streak_survives_an_empty_today(session, settings):
|
||||
today = local_date(settings.timezone)
|
||||
_run_pomodoros(session, settings, 1)
|
||||
|
||||
# Move the work to yesterday and leave today empty.
|
||||
from app.models import PomodoroSession
|
||||
|
||||
for row in session.query(PomodoroSession).all():
|
||||
row.local_date = today - timedelta(days=1)
|
||||
session.commit()
|
||||
|
||||
streak = stats.streak(session, settings, until=today)
|
||||
assert streak["current"] == 1
|
||||
|
||||
|
||||
def test_report_payload_has_the_pieces_the_ui_draws(session, settings):
|
||||
settings.pomodoro.daily_goal_pomodoros = 2
|
||||
settings_service.save_settings(session, settings)
|
||||
_run_pomodoros(session, settings, 2)
|
||||
task = tasks_service.create_local_task(session, title="Ship the thing")
|
||||
tasks_service.complete_task(session, settings, task.id)
|
||||
|
||||
payload = report.build_daily(session, settings, local_date(settings.timezone))
|
||||
assert payload["metrics"]["pomodoros"] == 2
|
||||
assert payload["metrics"]["tasks_completed_count"] == 1
|
||||
assert any(item["code"] == "goal_met" for item in payload["achievements"])
|
||||
assert payload["fun_facts"]
|
||||
assert 0 <= payload["score"] <= 100
|
||||
|
||||
|
||||
def test_rendered_report_escapes_borrowed_text(session, settings):
|
||||
task = tasks_service.create_local_task(session, title="Fix <b>&</b> ship")
|
||||
tasks_service.complete_task(session, settings, task.id)
|
||||
payload = report.build_daily(session, settings, local_date(settings.timezone))
|
||||
text = report.render_daily_telegram(payload, settings)
|
||||
assert "Fix <b>&</b> ship" in text
|
||||
|
||||
|
||||
def test_russian_report_renders(session, settings):
|
||||
settings.notifications.report.language = "ru"
|
||||
settings.notifications.report.tone = "drill_sergeant"
|
||||
settings_service.save_settings(session, settings)
|
||||
_run_pomodoros(session, settings, 1)
|
||||
payload = report.build_daily(session, settings, local_date(settings.timezone))
|
||||
text = report.render_daily_telegram(payload, settings)
|
||||
assert "Отчёт за день" in text
|
||||
|
||||
|
||||
def test_weekly_review_covers_seven_days(session, settings):
|
||||
_run_pomodoros(session, settings, 2)
|
||||
payload = report.build_weekly(session, settings, local_date(settings.timezone))
|
||||
assert len(payload["days"]) == 7
|
||||
assert payload["pomodoros"] == 2
|
||||
assert "Weekly review" in report.render_weekly_telegram(payload, settings)
|
||||
|
||||
|
||||
def test_progress_bar_is_proportional():
|
||||
assert report.progress_bar(0, 8) == "░" * 10
|
||||
assert report.progress_bar(8, 8) == "█" * 10
|
||||
assert report.progress_bar(4, 8).count("█") == 5
|
||||
Reference in new issue
Block a user