CLI
This commit is contained in:
169
tests/test_templates.py
Normal file
169
tests/test_templates.py
Normal file
@@ -0,0 +1,169 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import aiosqlite
|
||||
|
||||
from backend import notes
|
||||
from backend.config import settings
|
||||
|
||||
|
||||
def test_extract_templates():
|
||||
assert notes.extract_templates("Daily log\n$journal\n# Journal for %date%") == ["journal"]
|
||||
|
||||
|
||||
def test_extract_templates_dedup_and_case():
|
||||
assert notes.extract_templates("$Journal $journal $JOURNAL") == ["journal"]
|
||||
|
||||
|
||||
def test_extract_templates_multiple():
|
||||
assert notes.extract_templates("$journal and $standup") == ["journal", "standup"]
|
||||
|
||||
|
||||
def test_extract_templates_ignores_prices():
|
||||
# first char must be a letter — "$5" is not a template marker
|
||||
assert notes.extract_templates("Lunch was $5, coffee $3") == []
|
||||
|
||||
|
||||
def test_templates_are_not_tags():
|
||||
body = "$journal #diary"
|
||||
assert notes.extract_templates(body) == ["journal"]
|
||||
assert notes.extract_tags(body) == ["diary"]
|
||||
|
||||
|
||||
async def test_templates_endpoint_lists_definitions(client):
|
||||
r = await client.post("/api/notes", json={"body": "# Journal for %date%\n\n$journal\n\n- "})
|
||||
assert r.status_code == 200
|
||||
|
||||
r = await client.get("/api/templates")
|
||||
assert r.status_code == 200
|
||||
names = [t["name"] for t in r.json()]
|
||||
assert "journal" in names
|
||||
tpl = next(t for t in r.json() if t["name"] == "journal")
|
||||
assert tpl["username"] == "schmeeve"
|
||||
assert tpl["title"] == "Journal for %date%"
|
||||
|
||||
|
||||
async def test_get_template_returns_body(client):
|
||||
await client.post("/api/notes", json={"body": "# Journal for %date%\n\n$journal\n"})
|
||||
r = await client.get("/api/templates/journal")
|
||||
assert r.status_code == 200
|
||||
assert r.json()["body"].startswith("# Journal for %date%")
|
||||
assert r.json()["name"] == "journal"
|
||||
|
||||
|
||||
async def test_get_template_404(client):
|
||||
r = await client.get("/api/templates/nope")
|
||||
assert r.status_code == 404
|
||||
|
||||
|
||||
async def test_get_template_name_normalization(client):
|
||||
await client.post("/api/notes", json={"body": "# T\n$Journal\n"})
|
||||
r = await client.get("/api/templates/$JOURNAL")
|
||||
assert r.status_code == 200
|
||||
assert r.json()["name"] == "journal"
|
||||
|
||||
|
||||
async def test_newest_note_wins_for_duplicate_template(client):
|
||||
await client.post("/api/notes", json={"body": "# Old journal\n$journal\nold"})
|
||||
r = await client.post("/api/notes", json={"body": "# New journal\n$journal\nnew"})
|
||||
new_id = r.json()["id"]
|
||||
|
||||
r = await client.get("/api/templates/journal")
|
||||
assert r.json()["id"] == new_id
|
||||
assert "new" in r.json()["body"]
|
||||
|
||||
|
||||
async def test_user_space_beats_common_for_templates(client):
|
||||
await client.post(
|
||||
"/api/notes", json={"body": "# Common journal\n$journal\ncommon", "username": "common"}
|
||||
)
|
||||
r = await client.post("/api/notes", json={"body": "# My journal\n$journal\nmine"})
|
||||
own_id = r.json()["id"]
|
||||
|
||||
r = await client.get("/api/templates/journal")
|
||||
assert r.json()["id"] == own_id
|
||||
assert r.json()["username"] == "schmeeve"
|
||||
|
||||
|
||||
async def test_removing_marker_removes_template(client):
|
||||
r = await client.post("/api/notes", json={"body": "# J\n$journal\n"})
|
||||
note_id = r.json()["id"]
|
||||
await client.put(f"/api/notes/{note_id}", json={"body": "# J\nno marker\n"})
|
||||
r = await client.get("/api/templates/journal")
|
||||
assert r.status_code == 404
|
||||
|
||||
|
||||
async def test_deleting_note_removes_template(client):
|
||||
r = await client.post("/api/notes", json={"body": "# J\n$journal\n"})
|
||||
note_id = r.json()["id"]
|
||||
await client.delete(f"/api/notes/{note_id}")
|
||||
r = await client.get("/api/templates/journal")
|
||||
assert r.status_code == 404
|
||||
|
||||
|
||||
async def test_lookup_by_title(client):
|
||||
await client.post("/api/notes", json={"body": "# Journal for 2026-09-26\nentry\n"})
|
||||
r = await client.get("/api/notes/lookup", params={"title": "Journal for 2026-09-26"})
|
||||
assert r.status_code == 200
|
||||
assert "entry" in r.json()["body"]
|
||||
|
||||
r = await client.get("/api/notes/lookup", params={"title": "Journal for 1999-01-01"})
|
||||
assert r.status_code == 404
|
||||
|
||||
|
||||
async def test_lookup_scoped_to_user(client):
|
||||
await client.post("/api/notes", json={"body": "# Shared title\n", "username": "common"})
|
||||
r = await client.get("/api/notes/lookup", params={"title": "Shared title"})
|
||||
assert r.status_code == 404 # schmeeve's space only
|
||||
|
||||
|
||||
async def test_lookup_requires_auth(remote_client):
|
||||
r = await remote_client.get("/api/notes/lookup", params={"title": "x"})
|
||||
assert r.status_code == 401
|
||||
|
||||
|
||||
async def test_templates_require_auth(remote_client):
|
||||
assert (await remote_client.get("/api/templates")).status_code == 401
|
||||
assert (await remote_client.get("/api/templates/x")).status_code == 401
|
||||
|
||||
|
||||
async def test_backfill_templates(client):
|
||||
r = await client.post("/api/notes", json={"body": "# J\n$journal\n"})
|
||||
note_id = r.json()["id"]
|
||||
|
||||
async with aiosqlite.connect(settings.database_path) as db:
|
||||
await db.execute("DELETE FROM note_templates WHERE note_id = ?", (note_id,))
|
||||
await db.commit()
|
||||
|
||||
await notes.backfill_templates()
|
||||
|
||||
r = await client.get("/api/templates/journal")
|
||||
assert r.status_code == 200
|
||||
assert r.json()["id"] == note_id
|
||||
|
||||
|
||||
async def test_cli_install_script(client):
|
||||
r = await client.get("/schmeeve/cli")
|
||||
assert r.status_code == 200
|
||||
assert "__SNOTES_URL__" not in r.text
|
||||
assert "__SNOTES_USER__" not in r.text
|
||||
assert 'SNOTES_USER="schmeeve"' in r.text
|
||||
assert 'SNOTES_URL="http://test"' in r.text
|
||||
assert "curl -fsSL" in r.text
|
||||
|
||||
|
||||
async def test_cli_install_script_unknown_user(client):
|
||||
r = await client.get("/ghost/cli")
|
||||
assert r.status_code == 404
|
||||
|
||||
|
||||
async def test_cli_install_script_is_public(remote_client):
|
||||
r = await remote_client.get("/schmeeve/cli")
|
||||
assert r.status_code == 200
|
||||
assert 'SNOTES_USER="schmeeve"' in r.text
|
||||
|
||||
|
||||
async def test_cli_script_served(client):
|
||||
r = await client.get("/cli/snotes.py")
|
||||
assert r.status_code == 200
|
||||
assert "# /// script" in r.text
|
||||
assert "textual" in r.text
|
||||
Reference in New Issue
Block a user