This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
from datetime import UTC, datetime, timedelta
|
||||
|
||||
from sqlalchemy import event
|
||||
|
||||
|
||||
def boot(client):
|
||||
response = client.post(
|
||||
@@ -16,6 +18,14 @@ def test_recurring_calendar_exceptions_and_scopes(client):
|
||||
"/api/v1/tasks",
|
||||
json={"title": "站会", "list_id": inbox["id"], "due_at": "2026-09-01T09:00:00Z"},
|
||||
).json()
|
||||
normal_task = client.post(
|
||||
"/api/v1/tasks",
|
||||
json={"title": "月内普通任务", "list_id": inbox["id"], "due_at": "2026-09-12T09:00:00Z"},
|
||||
).json()
|
||||
client.post(
|
||||
"/api/v1/tasks",
|
||||
json={"title": "月外普通任务", "list_id": inbox["id"], "due_at": "2026-10-02T09:00:00Z"},
|
||||
)
|
||||
recurrence = client.post(
|
||||
"/api/v1/recurrences", json={"task_id": task["id"], "rrule": "FREQ=WEEKLY;BYDAY=TU,TH;COUNT=5"}
|
||||
)
|
||||
@@ -24,6 +34,8 @@ def test_recurring_calendar_exceptions_and_scopes(client):
|
||||
calendar = client.get(
|
||||
"/api/v1/calendar", params={"start": "2026-09-01", "end": "2026-09-30"}
|
||||
).json()
|
||||
assert any(row.get("id") == normal_task["id"] for row in calendar)
|
||||
assert not any(row["title"] == "月外普通任务" for row in calendar)
|
||||
occurrences = [row for row in calendar if row["recurrence_id"] == recurrence_id]
|
||||
assert len(occurrences) == 5
|
||||
assert occurrences[0]["title"] == "站会"
|
||||
@@ -45,9 +57,50 @@ def test_recurring_calendar_exceptions_and_scopes(client):
|
||||
f"/api/v1/recurrences/{recurrence_id}",
|
||||
params={"scope": "this", "occurrence_at": occurrences[2]["occurrence_at"]},
|
||||
).status_code == 204
|
||||
assert len(client.get(
|
||||
remaining = client.get(
|
||||
"/api/v1/calendar", params={"start": "2026-09-01", "end": "2026-09-30"}
|
||||
).json()) == 4
|
||||
).json()
|
||||
assert len([row for row in remaining if row["recurrence_id"] == recurrence_id]) == 4
|
||||
assert any(row.get("id") == normal_task["id"] for row in remaining)
|
||||
|
||||
|
||||
def test_habit_logs_support_date_range_filter(client):
|
||||
boot(client)
|
||||
habit = client.post("/api/v1/habits", json={"name": "跑步", "kind": "boolean", "schedule_type": "daily"}).json()
|
||||
hid = habit["id"]
|
||||
for day in ("2026-08-01", "2026-08-15", "2026-09-01"):
|
||||
client.post(f"/api/v1/habits/{hid}/logs", json={"day": day, "value": 1})
|
||||
|
||||
all_logs = client.get(f"/api/v1/habits/{hid}/logs").json()
|
||||
ranged = client.get(f"/api/v1/habits/{hid}/logs", params={"from": "2026-08-10", "to": "2026-08-31"}).json()
|
||||
|
||||
assert len(all_logs) == 3
|
||||
assert [row["day"] for row in ranged] == ["2026-08-15"]
|
||||
|
||||
|
||||
def test_habit_grid_uses_a_bounded_number_of_queries(client, monkeypatch):
|
||||
boot(client)
|
||||
for index in range(6):
|
||||
client.post("/api/v1/habits", json={"name": f"习惯 {index}", "kind": "boolean", "schedule_type": "daily"})
|
||||
|
||||
from backend.db import get_engine
|
||||
|
||||
statement_count = 0
|
||||
engine = get_engine().sync_engine
|
||||
|
||||
def count_queries(*_):
|
||||
nonlocal statement_count
|
||||
statement_count += 1
|
||||
|
||||
event.listen(engine, "before_cursor_execute", count_queries)
|
||||
try:
|
||||
response = client.get("/api/v1/habits/grid", params={"week": "2026-09-01"})
|
||||
finally:
|
||||
event.remove(engine, "before_cursor_execute", count_queries)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert len(response.json()["habits"]) == 6
|
||||
assert statement_count <= 5
|
||||
|
||||
|
||||
def test_habits_numeric_accumulation_pause_archive_grid_and_stats(client):
|
||||
@@ -67,6 +120,11 @@ def test_habits_numeric_accumulation_pause_archive_grid_and_stats(client):
|
||||
assert client.post(f"/api/v1/habits/{habit_id}/pauses", json={"start_date": yesterday, "end_date": today}).status_code == 201
|
||||
grid = client.get("/api/v1/habits/grid", params={"week": yesterday}).json()
|
||||
assert len(grid["days"]) == 7 and grid["habits"][0]["cells"]
|
||||
assert grid["habits"][0]["kind"] == "numeric"
|
||||
assert grid["habits"][0]["target"] == 8
|
||||
assert grid["habits"][0]["max_value"] == 10
|
||||
assert grid["habits"][0]["stats"]["total"] == 8
|
||||
assert grid["habits"][0]["stats"]["completed_days"] == 1
|
||||
stats = client.get(f"/api/v1/habits/{habit_id}/stats").json()
|
||||
assert stats["total"] == 8 and stats["completed_days"] == 1
|
||||
assert client.delete(f"/api/v1/habits/{habit_id}").status_code == 204
|
||||
|
||||
Reference in New Issue
Block a user