diff --git a/scripts/briefing.py b/scripts/briefing.py index 84b250d..ac8f611 100644 --- a/scripts/briefing.py +++ b/scripts/briefing.py @@ -216,7 +216,7 @@ def show_briefing(date: str = None) -> dict: if not path.exists(): return {"status": "not_found", "message": f"No briefing found for {date}."} - with open(path) as f: + with open(path, encoding="utf-8") as f: return json.load(f) @@ -225,7 +225,7 @@ def _save_briefing(data: dict, suffix: str = ""): BRIEFS_DIR.mkdir(parents=True, exist_ok=True) date = datetime.now().strftime("%Y-%m-%d") path = BRIEFS_DIR / f"{date}{suffix}.json" - with open(path, "w") as f: + with open(path, "w", encoding="utf-8") as f: json.dump(data, f, indent=2, default=str) diff --git a/tests/test_briefing_v3.py b/tests/test_briefing_v3.py index cd1cec4..2d4f4f4 100644 --- a/tests/test_briefing_v3.py +++ b/tests/test_briefing_v3.py @@ -2,6 +2,7 @@ import sys import tempfile import unittest from pathlib import Path +from unittest import mock sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts")) @@ -30,6 +31,27 @@ class BriefingV3Tests(unittest.TestCase): store._db_override = old_db_override briefing.BRIEFS_DIR = old_briefs_dir + def test_save_briefing_uses_utf8_encoding(self): + with tempfile.TemporaryDirectory() as tmpdir: + old_briefs_dir = briefing.BRIEFS_DIR + try: + briefing.BRIEFS_DIR = Path(tmpdir) / "briefs" + payload = {"status": "ok", "message": "emoji 💬 and accents café"} + with mock.patch("briefing.open", create=True) as mock_open: + handle = mock.Mock() + handle.__enter__ = mock.Mock(return_value=handle) + handle.__exit__ = mock.Mock(return_value=False) + mock_open.return_value = handle + + briefing._save_briefing(payload) + + mock_open.assert_called_once() + _, kwargs = mock_open.call_args + self.assertEqual("w", kwargs["mode"] if "mode" in kwargs else mock_open.call_args.args[1]) + self.assertEqual("utf-8", kwargs["encoding"]) + finally: + briefing.BRIEFS_DIR = old_briefs_dir + if __name__ == "__main__": unittest.main()