from __future__ import annotations from backend import auth, notes def test_is_lan(): assert auth.is_lan("192.168.1.23") is True assert auth.is_lan("192.168.2.1") is False assert auth.is_lan("8.8.8.8") is False assert auth.is_lan(None) is False assert auth.is_lan("not-an-ip") is False def test_extract_tags(): tags = notes.extract_tags("Made a great soup today #recipe #dinner #recipe") assert tags == ["recipe", "dinner"] def test_extract_title_heading(): assert notes.extract_title("# My Note\n\nbody") == "My Note" def test_extract_title_first_line(): assert notes.extract_title("Just a first line\nmore text") == "Just a first line" def test_extract_title_untitled(): assert notes.extract_title(" \n\n") == "Untitled" async def test_users_seeded(client): r = await client.get("/api/users") assert r.status_code == 200 names = [u["name"] for u in r.json()] assert "schmeeve" in names assert "ilya" in names async def test_create_and_get_note(client): r = await client.post("/api/notes", json={"body": "# Test\nThis is a note #tag1"}) assert r.status_code == 200 note = r.json() assert note["title"] == "Test" assert note["tags"] == ["tag1"] r2 = await client.get(f"/api/notes/{note['id']}") assert r2.status_code == 200 assert r2.json()["body"] == "# Test\nThis is a note #tag1" async def test_note_file_written(client, tmp_path): r = await client.post("/api/notes", json={"body": "hello world"}) note = r.json() import os expected = os.path.join(str(tmp_path / "notes"), "schmeeve", f"{note['id']}.md") assert os.path.isfile(expected) assert open(expected).read() == "hello world" async def test_update_note(client): r = await client.post("/api/notes", json={"body": "original"}) note_id = r.json()["id"] r2 = await client.put(f"/api/notes/{note_id}", json={"body": "updated #newtag"}) assert r2.status_code == 200 assert r2.json()["tags"] == ["newtag"] async def test_delete_note(client): r = await client.post("/api/notes", json={"body": "delete me"}) note_id = r.json()["id"] r2 = await client.delete(f"/api/notes/{note_id}") assert r2.status_code == 200 r3 = await client.get(f"/api/notes/{note_id}") assert r3.status_code == 404 async def test_search(client): await client.post("/api/notes", json={"body": "A note about recipes #recipe"}) await client.post("/api/notes", json={"body": "Completely different content"}) r = await client.get("/api/search", params={"q": "recipe"}) assert r.status_code == 200 results = r.json() assert len(results) == 1 async def test_tag_counts(client): await client.post("/api/notes", json={"body": "one #recipe"}) await client.post("/api/notes", json={"body": "two #recipe #dinner"}) await client.post("/api/notes", json={"body": "three #recipe"}) r = await client.get("/api/tags") tags = {t["name"]: t["count"] for t in r.json()} assert tags["recipe"] == 3 assert tags["dinner"] == 1 async def test_history_recorded(client): r = await client.post("/api/notes", json={"body": "note"}) note_id = r.json()["id"] r2 = await client.get(f"/api/notes/{note_id}/history") history = r2.json() assert len(history) == 1 assert history[0]["action"] == "create" assert history[0]["ip"] == "192.168.1.5" async def test_user_selection_cookie(client): r = await client.post("/api/users/select", json={"username": "ilya"}) assert r.status_code == 200 assert "snotes_user" in r.cookies async def test_remote_requires_auth(remote_client): r = await remote_client.get("/api/notes") assert r.status_code == 401 async def test_remote_login_unlocks(remote_client): r = await remote_client.post("/api/auth/login", json={"password": "wrong"}) assert r.status_code == 401 r2 = await remote_client.post("/api/auth/login", json={"password": "hunter2"}) assert r2.status_code == 200 assert "snotes_auth" in r2.cookies auth_cookie = r2.cookies["snotes_auth"] r3 = await remote_client.get("/api/notes", headers={"Cookie": "snotes_auth=" + auth_cookie}) assert r3.status_code == 200