feat: carry overdue interval habits forward
ci / gitleaks (push) Successful in 55s
ci / docker (push) Successful in 6m8s

This commit is contained in:
2026-09-15 11:59:01 +08:00
parent c28dff3a5a
commit d519843a9f
2 changed files with 84 additions and 10 deletions
+54 -4
View File
@@ -443,12 +443,62 @@ def test_boolean_interval_habit_schedule(client):
boot(client)
habit = client.post(
"/api/v1/habits",
json={"name": "拉伸", "kind": "boolean", "schedule_type": "interval", "interval_days": 2},
json={
"name": "拉伸",
"kind": "boolean",
"schedule_type": "interval",
"interval_days": 3,
"start_date": "2026-09-01",
},
)
assert habit.status_code == 201
assert client.post(
f"/api/v1/habits/{habit.json()['id']}/logs", json={"day": local_today().isoformat(), "value": 1}
).json()["value"] == 1
habit_id = habit.json()["id"]
overdue_grid = client.get("/api/v1/habits/grid", params={"week": "2026-09-07"}).json()
overdue_cells = {cell["day"]: cell for cell in overdue_grid["habits"][0]["cells"]}
assert overdue_cells["2026-09-07"]["scheduled"] is True
assert overdue_cells["2026-09-08"]["scheduled"] is True
assert overdue_cells["2026-09-09"]["scheduled"] is True
completed = client.post(
f"/api/v1/habits/{habit_id}/logs", json={"day": "2026-09-09", "value": 1}
)
assert completed.status_code == 200
next_grid = client.get("/api/v1/habits/grid", params={"week": "2026-09-07"}).json()
next_cells = {cell["day"]: cell for cell in next_grid["habits"][0]["cells"]}
assert next_cells["2026-09-09"]["scheduled"] is True
assert next_cells["2026-09-10"]["scheduled"] is False
assert next_cells["2026-09-11"]["scheduled"] is False
assert next_cells["2026-09-12"]["scheduled"] is True
assert next_cells["2026-09-13"]["scheduled"] is True
def test_interval_habit_partial_progress_does_not_restart_interval(client):
boot(client)
habit = client.post(
"/api/v1/habits",
json={
"name": "喝水",
"kind": "numeric",
"target": 3,
"schedule_type": "interval",
"interval_days": 3,
"start_date": "2026-09-01",
},
).json()
assert client.put(f"/api/v1/habits/{habit['id']}/logs/2026-09-04", json={"value": 2}).status_code == 200
grid = client.get("/api/v1/habits/grid", params={"week": "2026-09-07"}).json()
cells = {cell["day"]: cell for cell in grid["habits"][0]["cells"]}
assert cells["2026-09-07"]["scheduled"] is True
assert client.put(f"/api/v1/habits/{habit['id']}/logs/2026-09-08", json={"value": 3}).status_code == 200
grid = client.get("/api/v1/habits/grid", params={"week": "2026-09-07"}).json()
cells = {cell["day"]: cell for cell in grid["habits"][0]["cells"]}
assert cells["2026-09-09"]["scheduled"] is False
assert cells["2026-09-10"]["scheduled"] is False
assert cells["2026-09-11"]["scheduled"] is True
def test_attachment_security_ownership_and_size(client, tmp_path, monkeypatch):