This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
from datetime import date
|
||||
|
||||
from backend.lunar_support import (
|
||||
lunar_label_with_year,
|
||||
lunar_to_solar_safe,
|
||||
next_lunar_occurrence,
|
||||
solar_to_lunar_text,
|
||||
)
|
||||
from backend.mvp import countdown_occurrence, countdown_status
|
||||
|
||||
|
||||
@@ -23,6 +29,17 @@ def create_countdown(client, **overrides):
|
||||
return client.post("/api/v1/countdowns", json=payload)
|
||||
|
||||
|
||||
def test_lunar_date_math_labels_leap_month_and_finds_next_occurrence():
|
||||
assert lunar_to_solar_safe(2025, -6, 1) == date(2025, 7, 25)
|
||||
assert lunar_to_solar_safe(2026, -6, 1) is None
|
||||
assert solar_to_lunar_text(date(2026, 9, 14)) == "农历八月初四"
|
||||
assert solar_to_lunar_text(date(2025, 7, 25)) == "农历闰六月初一"
|
||||
assert lunar_label_with_year(date(2025, 7, 25)) == "农历二〇二五年闰六月初一"
|
||||
assert next_lunar_occurrence(8, 4, True, "none", date(2026, 9, 1)) == date(2026, 9, 14)
|
||||
assert next_lunar_occurrence(8, 4, True, "none", date(2026, 9, 15)) == date(2027, 9, 4)
|
||||
assert next_lunar_occurrence(-6, 1, True, "yearly", date(2026, 1, 1)) == date(2036, 7, 23)
|
||||
|
||||
|
||||
def test_countdown_date_math_uses_date_only_recurrence_semantics():
|
||||
assert countdown_status(date(2026, 9, 10), date(2026, 9, 6)) == (4, "还有 4 天")
|
||||
assert countdown_status(date(2026, 9, 6), date(2026, 9, 6)) == (0, "就是今天")
|
||||
@@ -32,6 +49,41 @@ def test_countdown_date_math_uses_date_only_recurrence_semantics():
|
||||
assert countdown_occurrence(date(2026, 9, 1), "weekly", date(2026, 9, 8)) == date(2026, 9, 8)
|
||||
|
||||
|
||||
def test_lunar_countdown_crud_validation_and_display(client):
|
||||
boot(client)
|
||||
created = create_countdown(
|
||||
client,
|
||||
title="农历生日",
|
||||
event_date="2026-01-01",
|
||||
kind="birthday",
|
||||
calendar_mode="lunar",
|
||||
lunar_month=8,
|
||||
lunar_day=4,
|
||||
ignore_year=True,
|
||||
)
|
||||
assert created.status_code == 201
|
||||
item = created.json()
|
||||
assert item["event_date"] == "2026-09-14"
|
||||
assert item["calendar_mode"] == "lunar"
|
||||
assert item["lunar_month"] == 8
|
||||
assert item["lunar_day"] == 4
|
||||
assert item["ignore_year"] is True
|
||||
assert item["lunar_text"] == "农历八月初四"
|
||||
|
||||
updated = client.patch(
|
||||
f"/api/v1/countdowns/{item['id']}",
|
||||
json={"lunar_month": -6, "lunar_day": 1, "event_date": "2025-01-01"},
|
||||
)
|
||||
assert updated.status_code == 200
|
||||
assert updated.json()["event_date"] == "2025-07-25"
|
||||
assert updated.json()["lunar_text"] == "农历闰六月初一"
|
||||
|
||||
assert create_countdown(client, calendar_mode="lunar", lunar_month=8).status_code == 422
|
||||
assert create_countdown(client, calendar_mode="lunar", lunar_month=0, lunar_day=1).status_code == 422
|
||||
assert create_countdown(client, calendar_mode="lunar", lunar_month=-6, lunar_day=1, event_date="2026-01-01").status_code == 422
|
||||
assert create_countdown(client, calendar_mode="solar", lunar_month=8, lunar_day=4).status_code == 422
|
||||
|
||||
|
||||
def test_countdown_crud_single_pin_archive_restore_and_purge(client):
|
||||
boot(client)
|
||||
first = create_countdown(client).json()
|
||||
@@ -96,19 +148,38 @@ def test_countdown_validation_and_user_isolation(client):
|
||||
|
||||
def test_countdowns_backup_replace_and_merge_round_trip(client):
|
||||
boot(client)
|
||||
active = create_countdown(client, title="周年", kind="anniversary", repeat_rule="yearly", pinned=True).json()
|
||||
active = create_countdown(
|
||||
client,
|
||||
title="周年",
|
||||
event_date="2025-01-01",
|
||||
kind="anniversary",
|
||||
repeat_rule="yearly",
|
||||
pinned=True,
|
||||
calendar_mode="lunar",
|
||||
lunar_month=-6,
|
||||
lunar_day=1,
|
||||
ignore_year=True,
|
||||
).json()
|
||||
archived = create_countdown(client, title="旧日", event_date="2020-01-02").json()
|
||||
client.delete(f"/api/v1/countdowns/{archived['id']}")
|
||||
|
||||
exported = client.get("/api/v1/export").json()
|
||||
assert {item["title"] for item in exported["countdowns"]} == {"周年", "旧日"}
|
||||
assert next(item for item in exported["countdowns"] if item["title"] == "周年")["pinned"] is True
|
||||
exported_lunar = next(item for item in exported["countdowns"] if item["title"] == "周年")
|
||||
assert exported_lunar["pinned"] is True
|
||||
assert exported_lunar["calendar_mode"] == "lunar"
|
||||
assert exported_lunar["lunar_month"] == -6
|
||||
assert exported_lunar["lunar_day"] == 1
|
||||
assert exported_lunar["ignore_year"] is True
|
||||
assert next(item for item in exported["countdowns"] if item["title"] == "旧日")["archived_at"]
|
||||
|
||||
create_countdown(client, title="干扰数据")
|
||||
restored = client.post("/api/v1/restore", params={"mode": "replace"}, json=exported)
|
||||
assert restored.status_code == 200
|
||||
assert {item["title"] for item in client.get("/api/v1/countdowns").json()} == {"周年"}
|
||||
restored_active = next(item for item in client.get("/api/v1/countdowns").json() if item["title"] == "周年")
|
||||
assert restored_active["calendar_mode"] == "lunar"
|
||||
assert restored_active["lunar_month"] == -6
|
||||
assert restored_active["ignore_year"] is True
|
||||
assert {item["title"] for item in client.get("/api/v1/countdowns", params={"archived": True}).json()} == {"旧日"}
|
||||
|
||||
merged = client.post("/api/v1/restore", params={"mode": "merge"}, json=exported)
|
||||
|
||||
Reference in New Issue
Block a user