# retoor <retoor@molodetz.nl>
import requests
from tests.conftest import BASE_URL
def _seed_news_seo():
from datetime import datetime, timezone
from devplacepy.database import get_table
from devplacepy.utils import generate_uid, make_combined_slug
uid = generate_uid()
title = f"SEO Test News Article {uid.split('-')[-1]}"
slug = make_combined_slug(title, uid)
get_table("news").insert(
{
"deleted_at": None,
"deleted_by": None,
"uid": uid,
"slug": slug,
"title": title,
"description": "A seeded news article for SEO tests.",
"content": "Body content for the seeded article.",
"url": "https://example.com/article",
"source_name": "ExampleSource",
"status": "published",
"synced_at": datetime.now(timezone.utc).isoformat(),
"show_on_landing": 0,
"grade": 8,
}
)
return slug, uid
def _seed_owner():
from datetime import datetime, timezone
from uuid import uuid4
from devplacepy.database import get_table
uid = str(uuid4())
get_table("users").insert(
{
"uid": uid,
"username": f"seo_{uid[:8]}",
"email": f"{uid[:8]}@seo.test",
"password_hash": "x",
"role": "Member",
"is_active": True,
"created_at": datetime.now(timezone.utc).isoformat(),
}
)
return uid
def _seed_post_seo(image=None):
from datetime import datetime, timezone
from uuid import uuid4
from devplacepy.database import get_table
from devplacepy.utils import make_combined_slug
owner = _seed_owner()
uid = str(uuid4())
slug = make_combined_slug("SEO Detail Post", uid)
get_table("posts").insert(
{
"deleted_at": None,
"deleted_by": None,
"uid": uid,
"user_uid": owner,
"slug": slug,
"title": "SEO Detail Post",
"content": "Body text for the SEO detail post.",
"topic": "general",
"project_uid": None,
"image": image,
"stars": 0,
"created_at": datetime.now(timezone.utc).isoformat(),
}
)
return slug, uid
def _seed_gist():
from datetime import datetime, timezone
from uuid import uuid4
from devplacepy.database import get_table
from devplacepy.utils import make_combined_slug
owner = _seed_owner()
uid = str(uuid4())
slug = make_combined_slug("SEO Detail Gist", uid)
get_table("gists").insert(
{
"deleted_at": None,
"deleted_by": None,
"uid": uid,
"user_uid": owner,
"slug": slug,
"title": "SEO Detail Gist",
"description": "Gist description for SEO tests.",
"source_code": "print('seo')",
"language": "python",
"stars": 0,
"created_at": datetime.now(timezone.utc).isoformat(),
}
)
return slug, uid
def _seed_project():
from datetime import datetime, timezone
from uuid import uuid4
from devplacepy.database import get_table
from devplacepy.utils import make_combined_slug
owner = _seed_owner()
uid = str(uuid4())
slug = make_combined_slug("SEO Detail Project", uid)
get_table("projects").insert(
{
"deleted_at": None,
"deleted_by": None,
"uid": uid,
"user_uid": owner,
"slug": slug,
"title": "SEO Detail Project",
"description": "Project description for SEO tests.",
"project_type": "software",
"platforms": "Linux",
"status": "Released",
"stars": 0,
"created_at": datetime.now(timezone.utc).isoformat(),
}
)
return slug, uid
def _seed_news_image(news_uid):
from devplacepy.database import get_table
get_table("news_images").insert(
{
"deleted_at": None,
"deleted_by": None,
"news_uid": news_uid,
"url": "https://example.com/seo-news-image.jpg",
}
)
def _seed_feed_posts(count):
from datetime import datetime, timezone, timedelta
from uuid import uuid4
from devplacepy.database import get_table
from devplacepy.utils import make_combined_slug
owner = _seed_owner()
topic = f"seopag{owner[:8]}"
base = datetime(2026, 1, 1, tzinfo=timezone.utc)
posts = get_table("posts")
for i in range(count):
uid = str(uuid4())
posts.insert(
{
"deleted_at": None,
"deleted_by": None,
"uid": uid,
"user_uid": owner,
"slug": make_combined_slug(f"seo pag {i}", uid),
"title": None,
"content": f"seo pag post {i}",
"topic": topic,
"project_uid": None,
"image": None,
"stars": 0,
"created_at": (base - timedelta(seconds=i)).isoformat(),
}
)
return topic
def test_missing_profile_returns_404(app_server):
r = requests.get(f"{BASE_URL}/profile/no-such-user-xyz", allow_redirects=False)
assert r.status_code == 404
def _seed_comment_on_post(commenter_uid):
from datetime import datetime, timezone
from uuid import uuid4
from devplacepy.database import get_table
post_slug, post_uid = _seed_post_seo()
comment_uid = str(uuid4())
get_table("comments").insert(
{
"deleted_at": None,
"deleted_by": None,
"uid": comment_uid,
"target_type": "post",
"target_uid": post_uid,
"post_uid": post_uid,
"user_uid": commenter_uid,
"content": "Activity tab link comment body",
"parent_uid": None,
"created_at": datetime.now(timezone.utc).isoformat(),
}
)
return post_slug, post_uid, comment_uid
def test_activity_comment_exposes_parent_post_url(app_server):
from devplacepy.database import get_table, refresh_snapshot
commenter = _seed_owner()
username = get_table("users").find_one(uid=commenter)["username"]
post_slug, _post_uid, comment_uid = _seed_comment_on_post(commenter)
refresh_snapshot()
r = requests.get(
f"{BASE_URL}/profile/{username}?tab=activity",
headers={"Accept": "application/json"},
)
assert r.status_code == 200
activities = r.json()["activities"]
comment_acts = [a for a in activities if a.get("type") == "comment"]
assert comment_acts, "expected a comment activity"
act = comment_acts[0]
assert act["url"] == f"/posts/{post_slug}#comment-{comment_uid}"
assert act["target_type"] == "post"
def test_activity_comment_url_matches_notification_target(app_server):
from devplacepy.database import get_table, refresh_snapshot, resolve_object_url
commenter = _seed_owner()
username = get_table("users").find_one(uid=commenter)["username"]
_post_slug, post_uid, comment_uid = _seed_comment_on_post(commenter)
refresh_snapshot()
expected = f"{resolve_object_url('post', post_uid)}#comment-{comment_uid}"
r = requests.get(
f"{BASE_URL}/profile/{username}?tab=activity",
headers={"Accept": "application/json"},
)
act = [a for a in r.json()["activities"] if a.get("type") == "comment"][0]
assert act["url"] == expected
def test_activity_post_exposes_url(app_server):
from datetime import datetime, timezone
from devplacepy.database import get_table, refresh_snapshot
owner = _seed_owner()
username = get_table("users").find_one(uid=owner)["username"]
post_slug, post_uid = _seed_post_seo()
get_table("posts").update({"uid": post_uid, "user_uid": owner}, ["uid"])
refresh_snapshot()
r = requests.get(
f"{BASE_URL}/profile/{username}?tab=activity",
headers={"Accept": "application/json"},
)
assert r.status_code == 200
post_acts = [a for a in r.json()["activities"] if a.get("type") == "post"]
assert post_acts, "expected a post activity"
assert post_acts[0]["url"] == f"/posts/{post_slug}"
def test_activity_comment_card_renders_overlay_link(app_server):
from devplacepy.database import get_table, refresh_snapshot
commenter = _seed_owner()
username = get_table("users").find_one(uid=commenter)["username"]
post_slug, _post_uid, comment_uid = _seed_comment_on_post(commenter)
refresh_snapshot()
r = requests.get(f"{BASE_URL}/profile/{username}?tab=activity")
assert r.status_code == 200
assert "activity-card card-link-host" in r.text
assert f'class="card-link" href="/posts/{post_slug}#comment-{comment_uid}"' in r.text
def test_profile_json_exposes_online_presence(app_server):
import time
name = f"pres{int(time.time() * 1000)}"
session = requests.Session()
session.post(
f"{BASE_URL}/auth/signup",
data={
"username": name,
"email": f"{name}@t.dev",
"password": "secret123",
"confirm_password": "secret123",
},
allow_redirects=True,
)
r = session.get(
f"{BASE_URL}/profile/{name}", headers={"Accept": "application/json"}
)
assert r.status_code == 200
body = r.json()
assert body["profile_online"] is True
assert body["profile_user"]["last_seen"]
def test_profile_json_offline_when_last_seen_stale(app_server):
from datetime import datetime, timezone, timedelta
from devplacepy.config import PRESENCE_TIMEOUT_SECONDS
from devplacepy.database import get_table, refresh_snapshot
owner = _seed_owner()
username = get_table("users").find_one(uid=owner)["username"]
stale = (
datetime.now(timezone.utc)
- timedelta(seconds=PRESENCE_TIMEOUT_SECONDS + 120)
).isoformat()
get_table("users").update({"uid": owner, "last_seen": stale}, ["uid"])
refresh_snapshot()
r = requests.get(
f"{BASE_URL}/profile/{username}", headers={"Accept": "application/json"}
)
assert r.status_code == 200
body = r.json()
assert body["profile_online"] is False
assert body["profile_user"]["last_seen"] == stale
def test_profile_hero_avatar_has_presence_dot(app_server):
import time
from devplacepy.database import get_table, refresh_snapshot
name = f"phero{int(time.time() * 1000)}"
s = requests.Session()
s.post(
f"{BASE_URL}/auth/signup",
data={
"username": name,
"email": f"{name}@t.dev",
"password": "secret123",
"confirm_password": "secret123",
},
allow_redirects=True,
)
refresh_snapshot()
uid = get_table("users").find_one(username=name)["uid"]
html = s.get(f"{BASE_URL}/profile/{name}").text
assert "profile-avatar-wrap" in html
assert "presence-dot" in html
assert f'data-presence-uid="{uid}"' in html
def test_followers_list_avatar_has_presence_dot(app_server):
import time
from devplacepy.database import get_table, refresh_snapshot
stamp = int(time.time() * 1000)
target = f"folt{stamp}"
follower = f"folf{stamp}"
st = requests.Session()
sf = requests.Session()
for sess, name in ((st, target), (sf, follower)):
sess.post(
f"{BASE_URL}/auth/signup",
data={
"username": name,
"email": f"{name}@t.dev",
"password": "secret123",
"confirm_password": "secret123",
},
allow_redirects=True,
)
sf.post(f"{BASE_URL}/follow/{target}", allow_redirects=True)
refresh_snapshot()
follower_uid = get_table("users").find_one(username=follower)["uid"]
html = st.get(f"{BASE_URL}/profile/{target}?tab=followers").text
assert "follow-user" in html
assert f'data-presence-uid="{follower_uid}"' in html
assert "data-presence-last-seen" in html
def test_viewing_profile_marks_notification_read(app_server):
import time
from datetime import datetime, timezone
from devplacepy.database import get_table, refresh_snapshot
from devplacepy.utils import generate_uid
name = f"nmark{int(time.time() * 1000)}"
session = requests.Session()
session.post(
f"{BASE_URL}/auth/signup",
data={
"username": name,
"email": f"{name}@t.dev",
"password": "secret123",
"confirm_password": "secret123",
},
allow_redirects=True,
)
refresh_snapshot()
user = get_table("users").find_one(username=name)
notif_uid = generate_uid()
get_table("notifications").insert(
{
"uid": notif_uid,
"user_uid": user["uid"],
"type": "follow",
"message": "someone followed you",
"related_uid": generate_uid(),
"target_url": f"/profile/{name}",
"read": False,
"created_at": datetime.now(timezone.utc).isoformat(),
}
)
refresh_snapshot()
r = session.get(f"{BASE_URL}/profile/{name}", allow_redirects=True)
assert r.status_code == 200
refresh_snapshot()
assert bool(get_table("notifications").find_one(uid=notif_uid)["read"]) is True