133 lines
5.0 KiB
Python
133 lines
5.0 KiB
Python
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
if str(PROJECT_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
|
from journal.core import storage
|
|
|
|
|
|
class StorageHybridBridgeTests(unittest.TestCase):
|
|
def test_save_entry_content_uses_entries_save_in_hybrid_mode(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
target = Path(tmp) / "2026-02-22.md"
|
|
with (
|
|
patch("journal.core.storage.BACKEND_MODE", "csharp-hybrid"),
|
|
patch("journal.core.storage.call_sidecar_action", return_value={"FilePath": str(target)}) as mock_call,
|
|
):
|
|
storage.save_entry_content("hello world", file_path=target, mode="Daily")
|
|
|
|
mock_call.assert_called_once_with(
|
|
"entries.save",
|
|
payload={
|
|
"content": "hello world",
|
|
"filePath": str(target),
|
|
"mode": "Daily",
|
|
},
|
|
)
|
|
|
|
def test_load_entry_content_uses_entries_load_in_hybrid_mode(self):
|
|
fake_path = "E:/tmp/2026-02-22.md"
|
|
with (
|
|
patch("journal.core.storage.BACKEND_MODE", "csharp-hybrid"),
|
|
patch(
|
|
"journal.core.storage.call_sidecar_action",
|
|
return_value={"RawContent": "entry content"},
|
|
) as mock_call,
|
|
):
|
|
result = storage.load_entry_content(fake_path)
|
|
|
|
self.assertEqual(result, "entry content")
|
|
mock_call.assert_called_once_with(
|
|
"entries.load",
|
|
payload={"filePath": fake_path},
|
|
)
|
|
|
|
def test_save_entry_content_strips_rich_html_before_hybrid_save(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
target = Path(tmp) / "2026-02-22.md"
|
|
nasty_html = (
|
|
'<p style="font-family: Times New Roman;">Hello <b>World</b></p>'
|
|
"<ul><li>A</li><li>B</li></ul>"
|
|
)
|
|
with (
|
|
patch("journal.core.storage.BACKEND_MODE", "csharp-hybrid"),
|
|
patch("journal.core.storage.call_sidecar_action", return_value={"FilePath": str(target)}) as mock_call,
|
|
):
|
|
storage.save_entry_content(nasty_html, file_path=target, mode="Overwrite")
|
|
|
|
sent_payload = mock_call.call_args.kwargs["payload"]
|
|
sent_content = sent_payload["content"]
|
|
self.assertNotIn("<p", sent_content.lower())
|
|
self.assertNotIn("style=", sent_content.lower())
|
|
self.assertIn("Hello World", sent_content)
|
|
self.assertIn("- A", sent_content)
|
|
|
|
def test_load_entry_content_strips_rich_html_in_hybrid_mode(self):
|
|
fake_path = "E:/tmp/2026-02-22.md"
|
|
nasty_html = (
|
|
'<p style="font-family: Times New Roman;">Top</p>'
|
|
'<p><span>Body</span></p>'
|
|
)
|
|
with (
|
|
patch("journal.core.storage.BACKEND_MODE", "csharp-hybrid"),
|
|
patch(
|
|
"journal.core.storage.call_sidecar_action",
|
|
return_value={"RawContent": nasty_html},
|
|
),
|
|
):
|
|
result = storage.load_entry_content(fake_path)
|
|
|
|
self.assertEqual(result, "Top\nBody")
|
|
|
|
def test_list_journal_files_uses_entries_list_in_hybrid_mode(self):
|
|
with (
|
|
patch("journal.core.storage.BACKEND_MODE", "csharp-hybrid"),
|
|
patch(
|
|
"journal.core.storage.call_sidecar_action",
|
|
return_value=[
|
|
{"FileName": "2026-02-01.md", "FilePath": "E:/tmp/2026-02-01.md"},
|
|
{"FileName": "2026-02-02.md", "FilePath": "E:/tmp/2026-02-02.md"},
|
|
],
|
|
) as mock_call,
|
|
):
|
|
result = storage.list_journal_files()
|
|
|
|
self.assertEqual(
|
|
result,
|
|
[
|
|
("2026-02-01.md", "E:/tmp/2026-02-01.md"),
|
|
("2026-02-02.md", "E:/tmp/2026-02-02.md"),
|
|
],
|
|
)
|
|
mock_call.assert_called_once()
|
|
|
|
def test_load_all_vaults_uses_csharp_workspace_hydration_in_hybrid_mode(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
with (
|
|
patch("journal.core.storage.BACKEND_MODE", "csharp-hybrid"),
|
|
patch("journal.core.storage.VAULT_DIR", Path(tmp) / "vault"),
|
|
patch("journal.core.storage.DATA_DIR", Path(tmp) / "data"),
|
|
patch(
|
|
"journal.core.storage.call_sidecar_action",
|
|
side_effect=[True, {"EntryFilesProcessed": 2}],
|
|
) as mock_call,
|
|
):
|
|
result = storage.load_all_vaults("vault-pass-123")
|
|
|
|
self.assertTrue(result)
|
|
self.assertEqual(mock_call.call_count, 2)
|
|
first_call = mock_call.call_args_list[0]
|
|
second_call = mock_call.call_args_list[1]
|
|
self.assertEqual(first_call.args[0], "vault.load_all")
|
|
self.assertEqual(second_call.args[0], "db.hydrate_workspace")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|