Files
synq/server/tests/test_org_writer.py

107 lines
3.8 KiB
Python

import pytest
from app.models import CaptureRequest
from app.org_writer import format_capture, normalize_tags
def make_capture(**kwargs) -> CaptureRequest:
defaults = dict(
id="phone-20260517-143122-a8f2",
created_at="2026-05-17T14:31:22-04:00",
kind="note",
body="hello world",
tags=[],
device="android",
)
defaults.update(kwargs)
return CaptureRequest(**defaults)
class TestNormalizeTags:
def test_lowercase(self):
assert normalize_tags(["Home", "ERRANDS"]) == ["home", "errands"]
def test_strips_hash(self):
assert normalize_tags(["#home"]) == ["home"]
def test_replaces_spaces(self):
assert normalize_tags(["my tag"]) == ["my_tag"]
def test_removes_invalid_chars(self):
assert normalize_tags(["tag!"]) == ["tag"]
def test_deduplicates(self):
assert normalize_tags(["home", "home"]) == ["home"]
def test_omits_empty(self):
assert normalize_tags(["", " "]) == []
def test_empty_list(self):
assert normalize_tags([]) == []
class TestFormatCapture:
def test_todo_with_tags(self):
c = make_capture(kind="todo", body="buy printer paper", tags=["home", "errands"])
result = format_capture(c)
assert result.startswith("* TODO buy printer paper :home:errands:\n")
assert ":CREATED:" in result
assert ":SOURCE: android" in result
assert ":ID: phone-20260517-143122-a8f2" in result
def test_todo_no_tags(self):
c = make_capture(kind="todo", body="do the thing", tags=[])
result = format_capture(c)
assert result.startswith("* TODO do the thing\n")
def test_note_single_line(self):
c = make_capture(kind="note", body="mobile capture should stay dumb and append-only.", tags=["retcon"])
result = format_capture(c)
assert result.startswith("* note :retcon:\n")
assert "mobile capture should stay dumb and append-only." in result
assert ":PROPERTIES:" in result
def test_note_no_tags(self):
c = make_capture(kind="note", body="simple note", tags=[])
result = format_capture(c)
assert result.startswith("* note\n")
assert "simple note" in result
def test_note_multiline(self):
body = "retcon capture idea\n\nphone should produce records, not edit org files."
c = make_capture(kind="note", body=body, tags=["retcon"])
result = format_capture(c)
assert result.startswith("* note: retcon capture idea :retcon:\n")
assert "retcon capture idea" in result
assert "phone should produce records, not edit org files." in result
assert ":PROPERTIES:" in result
def test_created_timestamp_format(self):
c = make_capture(created_at="2026-05-17T14:31:22-04:00")
result = format_capture(c)
assert ":CREATED: [2026-05-17 sun 14:31]" in result
def test_property_drawer_complete(self):
c = make_capture()
result = format_capture(c)
assert ":PROPERTIES:" in result
assert ":END:" in result
def test_todo_body_below_drawer_absent(self):
c = make_capture(kind="todo", body="simple todo")
result = format_capture(c)
lines = result.strip().split("\n")
# heading, drawer block — no extra body section
assert lines[0].startswith("* TODO")
assert ":END:" in result
# body should not appear after :END:
end_idx = result.index(":END:")
after_end = result[end_idx + len(":END:"):].strip()
assert after_end == ""
def test_note_body_appears_after_drawer(self):
c = make_capture(kind="note", body="my note body")
result = format_capture(c)
end_idx = result.index(":END:")
after_end = result[end_idx + len(":END:"):].strip()
assert "my note body" in after_end