"""journal_images_lib / journal_upload_api_lib 单元测试.""" import json import os import tempfile import unittest from io import BytesIO from lib.instance.journal_images_lib import ( JOURNAL_UPLOAD_TFS, collect_journal_slot_images, enrich_journal_api_item, images_json_dumps, is_valid_preuploaded_journal_file, journal_image_paths, journal_upload_field_name, normalize_journal_draft_id, parse_images_json, primary_journal_image, save_journal_slot_uploads, uploaded_screenshot_field_name, ) from lib.instance.journal_upload_api_lib import handle_journal_upload_slot class _FakeFile: def __init__(self, filename: str, data: bytes): self.filename = filename self._data = data def save(self, path: str) -> None: with open(path, "wb") as f: f.write(self._data) class _FakeFiles: def __init__(self, mapping): self._mapping = mapping def get(self, key): return self._mapping.get(key) class _FakeForm: def __init__(self, mapping): self._mapping = mapping def get(self, key, default=None): return self._mapping.get(key, default) class _FakeRequest: def __init__(self, form=None, files=None): self.form = form self.files = files class JournalImagesLibTest(unittest.TestCase): def test_field_names(self): self.assertEqual(journal_upload_field_name("5m"), "screenshot_5m") self.assertEqual(uploaded_screenshot_field_name("5m"), "uploaded_screenshot_5m") def test_normalize_draft_id(self): good = "a" * 32 self.assertEqual(normalize_journal_draft_id(good), good) self.assertIsNone(normalize_journal_draft_id("bad")) def test_save_slot_uploads_partial(self): with tempfile.TemporaryDirectory() as tmp: files = _FakeFiles( { "screenshot_5m": _FakeFile("a.png", b"png5"), "screenshot_1h": _FakeFile("b.jpg", b"jpg1"), } ) saved = save_journal_slot_uploads( files, "abc123" + "0" * 26, tmp, secure_filename_fn=lambda x: x, ) self.assertEqual(len(saved), 2) self.assertEqual(saved[0]["tf"], "5m") self.assertTrue(os.path.isfile(os.path.join(tmp, saved[0]["file"]))) self.assertEqual(saved[1]["tf"], "1h") def test_collect_preuploaded(self): entry_id = "abc123" + "0" * 26 fname = f"journal_{entry_id}_5m.png" with tempfile.TemporaryDirectory() as tmp: with open(os.path.join(tmp, fname), "wb") as f: f.write(b"x") form = _FakeForm({uploaded_screenshot_field_name("5m"): fname}) saved = collect_journal_slot_images( form, _FakeFiles({}), entry_id, tmp, secure_filename_fn=lambda x: x, ) self.assertEqual(saved, [{"tf": "5m", "file": fname}]) def test_is_valid_preuploaded_journal_file(self): entry_id = "abc123" + "0" * 26 fname = f"journal_{entry_id}_5m.png" self.assertTrue(is_valid_preuploaded_journal_file(fname, entry_id, "5m")) self.assertFalse(is_valid_preuploaded_journal_file("../evil.png", entry_id, "5m")) self.assertFalse(is_valid_preuploaded_journal_file(fname, "b" * 32, "5m")) def test_parse_and_enrich(self): raw = images_json_dumps([{"tf": "5m", "file": "journal_x_5m.png"}]) item = enrich_journal_api_item({"images_json": raw, "image": "legacy.png"}) self.assertEqual(len(item["images"]), 1) self.assertEqual(item["images"][0]["tf"], "5m") legacy = enrich_journal_api_item({"image": "only.png"}) self.assertEqual(legacy["images"][0]["file"], "only.png") def test_journal_image_paths_dedupe(self): with tempfile.TemporaryDirectory() as tmp: path = os.path.join(tmp, "same.png") with open(path, "wb") as f: f.write(b"x") row = { "image": "same.png", "images_json": json.dumps([{"tf": "5m", "file": "same.png"}]), } paths = journal_image_paths(row, tmp) self.assertEqual(len(paths), 1) def test_primary_journal_image(self): self.assertEqual( primary_journal_image([{"tf": "5m", "file": "a.png"}]), "a.png", ) self.assertIsNone(primary_journal_image([])) def test_handle_journal_upload_slot(self): entry_id = "abc123" + "0" * 26 with tempfile.TemporaryDirectory() as tmp: req = _FakeRequest( form=_FakeForm({"journal_draft_id": entry_id, "tf": "5m"}), files=_FakeFiles({"file": _FakeFile("local.png", b"data")}), ) payload, code = handle_journal_upload_slot( req, upload_folder=tmp, secure_filename_fn=lambda x: x, ) self.assertEqual(code, 200) self.assertTrue(payload["ok"]) self.assertEqual(payload["tf"], "5m") self.assertTrue(os.path.isfile(os.path.join(tmp, payload["file"]))) if __name__ == "__main__": unittest.main()