migration: establish exact preserved app baseline
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from alert_service import AlertService
|
||||
from database import ReviewDatabase
|
||||
|
||||
|
||||
class AlertServiceTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.temp = tempfile.TemporaryDirectory()
|
||||
self.database = ReviewDatabase(Path(self.temp.name) / "review.db")
|
||||
self.owner = self.database.create_user("alert_owner", "salt", "hash")
|
||||
self.other = self.database.create_user("alert_other", "salt", "hash")
|
||||
self.service = AlertService(self.database)
|
||||
|
||||
def tearDown(self) -> None:
|
||||
self.temp.cleanup()
|
||||
|
||||
def test_future_manual_alert_is_visible_but_not_unread_until_due(self):
|
||||
alert_id = self.service.create_manual(
|
||||
self.owner["id"],
|
||||
{
|
||||
"title": "复核承接",
|
||||
"content": "开盘不及预期则退出观察",
|
||||
"code": "002141",
|
||||
"remind_date": "2026-07-25",
|
||||
},
|
||||
)
|
||||
before = self.service.list_alerts(self.owner["id"], "all", "2026-07-22")
|
||||
due = self.service.list_alerts(self.owner["id"], "unread", "2026-07-25")
|
||||
|
||||
self.assertEqual(before["items"][0]["id"], alert_id)
|
||||
self.assertFalse(before["items"][0]["due"])
|
||||
self.assertEqual(before["unread_count"], 0)
|
||||
self.assertEqual(due["unread_count"], 1)
|
||||
self.assertTrue(due["items"][0]["due"])
|
||||
|
||||
def test_alert_reads_and_mutations_are_scoped_to_owner(self):
|
||||
alert_id = self.database.save_alert(
|
||||
self.owner["id"], "manual", "甲的提醒", "", "20260722", "", "owner-only"
|
||||
)
|
||||
self.assertEqual(
|
||||
self.service.list_alerts(self.other["id"], "all", "2026-07-22")["items"], []
|
||||
)
|
||||
self.assertFalse(self.database.mark_alert_read(self.other["id"], alert_id))
|
||||
self.assertFalse(self.database.delete_alert(self.other["id"], alert_id))
|
||||
self.assertTrue(self.database.mark_alert_read(self.owner["id"], alert_id))
|
||||
self.assertEqual(
|
||||
self.service.list_alerts(self.owner["id"], "all", "2026-07-22")["unread_count"], 0
|
||||
)
|
||||
self.assertTrue(self.database.delete_alert(self.owner["id"], alert_id))
|
||||
|
||||
def test_strategy_alerts_are_idempotent(self):
|
||||
tracking = {
|
||||
"batches": [
|
||||
{
|
||||
"run_id": 9,
|
||||
"strategy_name": "修复策略",
|
||||
"items": [{"code": "002141"}, {"code": "600000"}],
|
||||
"summary": {
|
||||
"observed": 2,
|
||||
"completed": 2,
|
||||
"t1_win_rate": 50.0,
|
||||
"average_t5": 3.25,
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
self.service.sync_strategy_tracking(self.owner["id"], tracking)
|
||||
self.service.sync_strategy_tracking(self.owner["id"], tracking)
|
||||
alerts = self.database.list_alerts(
|
||||
self.owner["id"], "99991231", unread_only=False
|
||||
)
|
||||
|
||||
self.assertEqual(len(alerts), 2)
|
||||
self.assertEqual({item["kind"] for item in alerts}, {"strategy_t1", "strategy_t5"})
|
||||
|
||||
def test_mark_all_only_changes_due_alerts(self):
|
||||
self.database.save_alert(
|
||||
self.owner["id"], "manual", "今日", "", "20260722", "", "due"
|
||||
)
|
||||
self.database.save_alert(
|
||||
self.owner["id"], "manual", "未来", "", "20260723", "", "future"
|
||||
)
|
||||
self.assertEqual(
|
||||
self.database.mark_all_alerts_read(self.owner["id"], "20260722"), 1
|
||||
)
|
||||
future = self.service.list_alerts(self.owner["id"], "unread", "2026-07-23")
|
||||
self.assertEqual([item["title"] for item in future["items"]], ["未来"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user