forked from retoor/devplacepy
chore: reorganize test files into domain-specific subdirectories under tests/
Split the monolithic test directory into three tiers (unit, api, e2e) with a path-mirroring directory structure. Added corresponding Makefile targets (test-unit, test-api, test-e2e) and updated all documentation references (CLAUDE.md, README.md, testing-cicd.html, testing-framework.html, testing-make.html) to reflect the new layout and naming conventions.
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
import argparse
|
||||
from datetime import datetime, timezone
|
||||
import pytest
|
||||
from devplacepy import cli
|
||||
from devplacepy.database import get_table
|
||||
from devplacepy.utils import generate_uid
|
||||
def _make_user_cli(role="Member"):
|
||||
username = f"cli_{generate_uid()[:8]}"
|
||||
get_table("users").insert(
|
||||
{
|
||||
"uid": generate_uid(),
|
||||
"username": username,
|
||||
"email": f"{username}@t.dev",
|
||||
"role": role,
|
||||
"created_at": datetime.now(timezone.utc).isoformat(),
|
||||
}
|
||||
)
|
||||
return username
|
||||
|
||||
|
||||
def test_role_get_prints_lowercased_role(local_db, capsys):
|
||||
username = _make_user_cli(role="Admin")
|
||||
cli.cmd_role_get(argparse.Namespace(username=username))
|
||||
assert capsys.readouterr().out.strip() == "admin"
|
||||
|
||||
|
||||
def test_role_get_missing_user_exits(local_db):
|
||||
with pytest.raises(SystemExit):
|
||||
cli.cmd_role_get(argparse.Namespace(username="cli_absent_xyz"))
|
||||
|
||||
|
||||
def test_role_set_updates_role(local_db):
|
||||
username = _make_user_cli(role="Member")
|
||||
cli.cmd_role_set(argparse.Namespace(username=username, role="admin"))
|
||||
user = get_table("users").find_one(username=username)
|
||||
assert user["role"] == "Admin"
|
||||
|
||||
|
||||
def test_role_set_invalid_role_exits(local_db):
|
||||
username = _make_user_cli()
|
||||
with pytest.raises(SystemExit):
|
||||
cli.cmd_role_set(argparse.Namespace(username=username, role="superuser"))
|
||||
|
||||
|
||||
def test_role_set_missing_user_exits(local_db):
|
||||
with pytest.raises(SystemExit):
|
||||
cli.cmd_role_set(argparse.Namespace(username="cli_absent_xyz", role="admin"))
|
||||
|
||||
|
||||
def test_news_clear_deletes_all_tables(local_db, capsys):
|
||||
for table in ("news", "news_images", "news_sync"):
|
||||
get_table(table).insert({"uid": generate_uid(), "marker": "cli"})
|
||||
cli.cmd_news_clear(argparse.Namespace())
|
||||
for table in ("news", "news_images", "news_sync"):
|
||||
assert get_table(table).count() == 0
|
||||
assert "News data cleared" in capsys.readouterr().out
|
||||
|
||||
|
||||
def test_news_sanitize_strips_html(local_db, capsys):
|
||||
uid = generate_uid()
|
||||
get_table("news").insert(
|
||||
{
|
||||
"uid": uid,
|
||||
"description": "<b>Bold</b> & clean",
|
||||
"content": "<p>Body</p>",
|
||||
}
|
||||
)
|
||||
cli.cmd_news_sanitize(argparse.Namespace())
|
||||
row = get_table("news").find_one(uid=uid)
|
||||
assert row["description"] == "Bold & clean"
|
||||
assert row["content"] == "Body"
|
||||
assert "Sanitized" in capsys.readouterr().out
|
||||
|
||||
|
||||
def test_attachments_prune_removes_only_stale_orphans(local_db, capsys):
|
||||
old_uid = generate_uid()
|
||||
fresh_uid = generate_uid()
|
||||
attachments = get_table("attachments")
|
||||
attachments.insert(
|
||||
{
|
||||
"uid": old_uid,
|
||||
"target_type": "",
|
||||
"target_uid": "",
|
||||
"created_at": "2000-01-01T00:00:00+00:00",
|
||||
}
|
||||
)
|
||||
attachments.insert(
|
||||
{
|
||||
"uid": fresh_uid,
|
||||
"target_type": "",
|
||||
"target_uid": "",
|
||||
"created_at": datetime.now(timezone.utc).isoformat(),
|
||||
}
|
||||
)
|
||||
cli.cmd_attachments_prune(argparse.Namespace(hours=24))
|
||||
assert attachments.find_one(uid=old_uid) is None
|
||||
assert attachments.find_one(uid=fresh_uid) is not None
|
||||
|
||||
|
||||
def test_apikey_get_prints_key(local_db, capsys):
|
||||
username = _make_user_cli()
|
||||
key = generate_uid()
|
||||
get_table("users").update(
|
||||
{"uid": get_table("users").find_one(username=username)["uid"], "api_key": key},
|
||||
["uid"],
|
||||
)
|
||||
cli.cmd_apikey_get(argparse.Namespace(username=username))
|
||||
assert capsys.readouterr().out.strip() == key
|
||||
|
||||
|
||||
def test_apikey_reset_changes_key(local_db, capsys):
|
||||
username = _make_user_cli()
|
||||
users = get_table("users")
|
||||
users.update(
|
||||
{"uid": users.find_one(username=username)["uid"], "api_key": generate_uid()},
|
||||
["uid"],
|
||||
)
|
||||
before = users.find_one(username=username)["api_key"]
|
||||
cli.cmd_apikey_reset(argparse.Namespace(username=username))
|
||||
printed = capsys.readouterr().out.strip()
|
||||
after = users.find_one(username=username)["api_key"]
|
||||
assert after != before
|
||||
assert printed == after
|
||||
|
||||
|
||||
def test_apikey_backfill_assigns_missing(local_db, capsys):
|
||||
users = get_table("users")
|
||||
uid = generate_uid()
|
||||
users.insert(
|
||||
{
|
||||
"uid": uid,
|
||||
"username": f"cli_{uid[:8]}",
|
||||
"email": f"{uid[:8]}@t.dev",
|
||||
"role": "Member",
|
||||
"created_at": datetime.now(timezone.utc).isoformat(),
|
||||
}
|
||||
)
|
||||
cli.cmd_apikey_backfill(argparse.Namespace())
|
||||
assert capsys.readouterr().out.strip().startswith("Assigned API keys to")
|
||||
assert users.find_one(uid=uid).get("api_key")
|
||||
|
||||
|
||||
def test_main_without_command_exits(monkeypatch):
|
||||
monkeypatch.setattr("sys.argv", ["devplace"])
|
||||
with pytest.raises(SystemExit):
|
||||
cli.main()
|
||||
|
||||
|
||||
def test_main_dispatches_subcommand(local_db, monkeypatch, capsys):
|
||||
username = _make_user_cli(role="Admin")
|
||||
monkeypatch.setattr("sys.argv", ["devplace", "role", "get", username])
|
||||
cli.main()
|
||||
assert capsys.readouterr().out.strip() == "admin"
|
||||
Reference in New Issue
Block a user