This commit is contained in:
2026-08-07 10:53:43 +02:00
parent e02919a1db
commit 6c161401de
101 changed files with 20 additions and 6737 deletions
+6 -2
View File
@@ -6,8 +6,12 @@ from datetime import datetime, timezone
import pytest
from PIL import Image
from devplacepy.db_client import get_award_usage, get_table, init_db
from devplacepy.db_client import recompute_user_award_stats
from devplacepy.database import (
get_award_usage,
get_table,
init_db,
recompute_user_award_stats,
)
from devplacepy.services.jobs.award_service import AwardService
from devplacepy.utils import generate_uid, make_combined_slug
from tests.conftest import run_async
-212
View File
@@ -1,212 +0,0 @@
# retoor <retoor@molodetz.nl>
from datetime import datetime, timezone
import pytest
from devplacepy.db_client import get_table
from devplacepy.utils import generate_uid
def _now():
return datetime.now(timezone.utc).isoformat()
def _make_user(local_db, **overrides):
uid = generate_uid()
row = {
"uid": uid,
"username": f"cpd_{uid[:8]}",
"email": f"cpd_{uid[:8]}@t.dev",
"api_key": generate_uid(),
"role": "Member",
"is_active": True,
"created_at": _now(),
"bio": "",
}
row.update(overrides)
get_table("users").insert(row)
return row
def _make_post(local_db, user, **overrides):
from devplacepy.utils import make_combined_slug
uid = generate_uid()
row = {
"uid": uid,
"user_uid": user["uid"],
"title": "Compound test post",
"content": "Body of the compound test post.",
"topic": "devlog",
"slug": make_combined_slug("Compound test post", uid),
"stars": 0,
"created_at": _now(),
"deleted_at": None,
"deleted_by": None,
}
row.update(overrides)
get_table("posts").insert(row)
return row
def _make_project(local_db, user, **overrides):
from devplacepy.utils import make_combined_slug
uid = generate_uid()
row = {
"uid": uid,
"user_uid": user["uid"],
"title": "Compound test project",
"description": "",
"slug": make_combined_slug("Compound test project", uid),
"stars": 0,
"is_private": 0,
"created_at": _now(),
"deleted_at": None,
"deleted_by": None,
}
row.update(overrides)
get_table("projects").insert(row)
return row
def _make_gist(local_db, user, **overrides):
from devplacepy.utils import make_combined_slug
uid = generate_uid()
row = {
"uid": uid,
"user_uid": user["uid"],
"title": "Compound test gist",
"description": "",
"source_code": "print('hi')",
"language": "python",
"slug": make_combined_slug("Compound test gist", uid),
"stars": 0,
"created_at": _now(),
"deleted_at": None,
"deleted_by": None,
}
row.update(overrides)
get_table("gists").insert(row)
return row
# Section 5.3 page compounds actually wired to a caller (db_client.build_*)
# and consumed by a real web route. Each assertion checks the template
# context keys the corresponding route/schema depends on.
def test_build_feed_page_shape(local_db):
from devplacepy_services.database.compounds_page import build_feed_page
user = _make_user(local_db)
post = _make_post(local_db, user)
result = build_feed_page(user=user)
for key in ("posts", "next_cursor", "stats", "top_authors", "daily_topic", "current_tab"):
assert key in result
uids = [item["post"]["uid"] for item in result["posts"]]
assert post["uid"] in uids
item = next(i for i in result["posts"] if i["post"]["uid"] == post["uid"])
for key in ("attachments", "recent_comments", "reactions", "bookmarked", "poll"):
assert key in item
def test_build_post_detail_shape(local_db):
from devplacepy_services.database.compounds_page import build_post_detail
user = _make_user(local_db)
post = _make_post(local_db, user)
result = build_post_detail(post["uid"], user=user)
assert result["post"]["uid"] == post["uid"]
assert result["author"]["uid"] == user["uid"]
assert isinstance(result["comments"], list)
assert isinstance(result["attachments"], list)
def test_build_post_detail_missing_post(local_db):
from devplacepy_services.database.compounds_page import build_post_detail
result = build_post_detail("does-not-exist")
assert result["post"] is None
def test_build_profile_bundle_shape(local_db):
from devplacepy_services.database.compounds_page import build_profile_bundle
user = _make_user(local_db)
result = build_profile_bundle(user["uid"])
assert result["user"]["uid"] == user["uid"]
assert "followers" in result["follow_counts"]
assert "following" in result["follow_counts"]
def test_build_leaderboard_page_shape(local_db):
from devplacepy_services.database.compounds_page import build_leaderboard_page
user = _make_user(local_db)
result = build_leaderboard_page(viewer_uid=user["uid"])
assert "leaderboard" in result
assert isinstance(result["leaderboard"], list)
def test_build_project_detail_shape(local_db):
from devplacepy_services.database.compounds_page import build_project_detail
user = _make_user(local_db)
project = _make_project(local_db, user)
result = build_project_detail(project["uid"])
assert result["project"]["uid"] == project["uid"]
assert result["owner"]["uid"] == user["uid"]
def test_build_gist_detail_shape(local_db):
from devplacepy_services.database.compounds_page import build_gist_detail
user = _make_user(local_db)
gist = _make_gist(local_db, user)
result = build_gist_detail(gist["uid"], user=user)
assert result["gist"]["uid"] == gist["uid"]
assert result["author"]["uid"] == user["uid"]
assert isinstance(result["comments"], list)
# Section 5.3 rows registered as HTTP endpoints (devplacepy_services/database/routes.py)
# but not yet called by any web route (routers/messages.py, notifications.py,
# game/, admin/index.py all still do their own direct db_client calls) - these
# four builders are unfinished stubs, tracked here so a real implementation
# lands as a visible test change rather than silently.
@pytest.mark.parametrize(
"fn_name,args,expected_keys",
[
("build_messages_page", ("u1",), {"threads", "unread", "partners"}),
("build_notifications_page", ("u1",), {"notifications", "actors", "unread_count"}),
("build_game_state", (), {"store", "leaderboard"}),
("build_admin_dashboard", (), {"stats", "service_states"}),
],
)
def test_stub_compounds_documented(local_db, fn_name, args, expected_keys):
import devplacepy_services.database.compounds_page as compounds_page
fn = getattr(compounds_page, fn_name)
result = fn(*args)
assert set(result.keys()) == expected_keys, (
f"{fn_name} shape changed - if this is a real implementation now, "
"replace this stub-tracking test with a real assertion and update "
"splitup.md Section 17.2"
)
-56
View File
@@ -1,56 +0,0 @@
# retoor <retoor@molodetz.nl>
import os
import subprocess
import sys
import pytest
from devplacepy_services.base.config import PROFILES
SERVICE_MODULES = (
"devplacepy_services.database.main",
"devplacepy_services.pubsub.main",
"devplacepy_services.web.main",
"devplacepy_services.gateway.main",
"devplacepy_services.jobs.main",
"devplacepy_services.devii.main",
"devplacepy_services.bot.main",
"devplacepy_services.backup.main",
"devplacepy_services.containers.main",
"devplacepy_services.telegram.main",
"devplacepy_services.email.main",
"devplacepy_services.news.main",
"devplacepy_services.gitea.main",
"devplacepy_services.audit.main",
"devplacepy_services.xmlrpc.main",
)
@pytest.mark.parametrize("module_name", SERVICE_MODULES)
def test_service_imports(module_name):
env = os.environ.copy()
env["DEVPLACE_DISABLE_SERVICES"] = "1"
env["DEVPLACE_DATABASE_URL"] = "sqlite:///:memory:"
env.pop("DEVPLACE_REMOTE_DB", None)
env.pop("DEVPLACE_DB_SERVICE", None)
script = (
f"import importlib; m = importlib.import_module('{module_name}'); "
"assert hasattr(m, 'app')"
)
result = subprocess.run(
[sys.executable, "-c", script],
env=env,
capture_output=True,
text=True,
timeout=30,
check=False,
)
assert result.returncode == 0, result.stderr or result.stdout
def test_port_profiles_complete():
for profile in ("micro-dev", "micro-test", "micro-prod"):
ports = PROFILES[profile]
assert "web" in ports
assert ports["web"] in (10500, 20500)