forked from retoor/devplacepy
feat: add TTLCache for get_cache_version and TEMPLATE_AUTO_RELOAD config with Makefile worker count variables
This commit is contained in:
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
import requests
|
||||
from tests.conftest import BASE_URL
|
||||
from devplacepy.database import get_table, refresh_snapshot
|
||||
|
||||
JSON = {"Accept": "application/json"}
|
||||
|
||||
|
||||
def _admin():
|
||||
refresh_snapshot()
|
||||
key = get_table("users").find_one(username="alice_test")["api_key"]
|
||||
s = requests.Session()
|
||||
s.headers.update({"X-API-KEY": key})
|
||||
return s
|
||||
|
||||
|
||||
def test_bots_page_requires_login(app_server):
|
||||
r = requests.get(f"{BASE_URL}/admin/bots", allow_redirects=False)
|
||||
assert r.status_code in (302, 303)
|
||||
|
||||
|
||||
def test_bots_data_denied_for_non_admin(app_server, seeded_db):
|
||||
s = requests.Session()
|
||||
s.post(
|
||||
f"{BASE_URL}/auth/login",
|
||||
data={
|
||||
"email": seeded_db["bob"]["email"],
|
||||
"password": seeded_db["bob"]["password"],
|
||||
},
|
||||
)
|
||||
r = s.get(f"{BASE_URL}/admin/bots/data", allow_redirects=False)
|
||||
assert r.status_code in (302, 303, 403)
|
||||
r_json = s.get(f"{BASE_URL}/admin/bots/data", headers=JSON, allow_redirects=False)
|
||||
assert r_json.status_code == 403
|
||||
|
||||
|
||||
def test_bots_data_shape_for_admin(app_server, seeded_db):
|
||||
admin = _admin()
|
||||
r = admin.get(f"{BASE_URL}/admin/bots/data", headers=JSON)
|
||||
assert r.status_code == 200, r.text[:300]
|
||||
body = r.json()
|
||||
assert "frames" in body
|
||||
assert isinstance(body["frames"], list)
|
||||
assert "enabled" in body
|
||||
assert isinstance(body["enabled"], bool)
|
||||
assert "service_status" in body
|
||||
|
||||
|
||||
def test_bots_frame_missing_is_404(app_server, seeded_db):
|
||||
admin = _admin()
|
||||
r = admin.get(f"{BASE_URL}/admin/bots/999/frame.jpg", allow_redirects=False)
|
||||
assert r.status_code == 404
|
||||
|
||||
|
||||
def test_bots_frame_requires_admin(app_server, seeded_db):
|
||||
r = requests.get(f"{BASE_URL}/admin/bots/0/frame.jpg", allow_redirects=False)
|
||||
assert r.status_code in (302, 303)
|
||||
@@ -0,0 +1,35 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
import requests
|
||||
from tests.conftest import BASE_URL
|
||||
|
||||
|
||||
def _bob(seeded_db):
|
||||
s = requests.Session()
|
||||
s.post(
|
||||
f"{BASE_URL}/auth/login",
|
||||
data={
|
||||
"email": seeded_db["bob"]["email"],
|
||||
"password": seeded_db["bob"]["password"],
|
||||
},
|
||||
)
|
||||
return s
|
||||
|
||||
|
||||
def test_create_requires_admin(app_server, seeded_db):
|
||||
s = _bob(seeded_db)
|
||||
r = s.post(
|
||||
f"{BASE_URL}/admin/containers/create",
|
||||
data={"project_slug": "x", "name": "x"},
|
||||
allow_redirects=False,
|
||||
)
|
||||
assert r.status_code in (302, 303, 403)
|
||||
|
||||
|
||||
def test_create_requires_login(app_server):
|
||||
r = requests.post(
|
||||
f"{BASE_URL}/admin/containers/create",
|
||||
data={"project_slug": "x", "name": "x"},
|
||||
allow_redirects=False,
|
||||
)
|
||||
assert r.status_code in (302, 303)
|
||||
@@ -0,0 +1 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
@@ -0,0 +1,35 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
import requests
|
||||
from tests.conftest import BASE_URL
|
||||
from devplacepy.database import get_table, refresh_snapshot
|
||||
|
||||
|
||||
def _admin_session():
|
||||
refresh_snapshot()
|
||||
key = get_table("users").find_one(username="alice_test")["api_key"]
|
||||
s = requests.Session()
|
||||
s.headers.update({"X-API-KEY": key})
|
||||
return s
|
||||
|
||||
|
||||
def test_project_search_requires_admin(app_server, seeded_db):
|
||||
s = requests.Session()
|
||||
s.post(
|
||||
f"{BASE_URL}/auth/login",
|
||||
data={
|
||||
"email": seeded_db["bob"]["email"],
|
||||
"password": seeded_db["bob"]["password"],
|
||||
},
|
||||
)
|
||||
r = s.get(
|
||||
f"{BASE_URL}/admin/containers/projects/search?q=a", allow_redirects=False
|
||||
)
|
||||
assert r.status_code in (302, 303, 403)
|
||||
|
||||
|
||||
def test_project_search_empty_query(app_server, seeded_db):
|
||||
s = _admin_session()
|
||||
r = s.get(f"{BASE_URL}/admin/containers/projects/search?q=")
|
||||
assert r.status_code == 200
|
||||
assert r.json()["results"] == []
|
||||
@@ -0,0 +1 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
@@ -0,0 +1,43 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
import requests
|
||||
from tests.conftest import BASE_URL
|
||||
from devplacepy.database import get_table, refresh_snapshot
|
||||
|
||||
|
||||
def _admin_session():
|
||||
refresh_snapshot()
|
||||
key = get_table("users").find_one(username="alice_test")["api_key"]
|
||||
s = requests.Session()
|
||||
s.headers.update({"X-API-KEY": key})
|
||||
return s
|
||||
|
||||
|
||||
def test_user_search_requires_admin(app_server, seeded_db):
|
||||
s = requests.Session()
|
||||
s.post(
|
||||
f"{BASE_URL}/auth/login",
|
||||
data={
|
||||
"email": seeded_db["bob"]["email"],
|
||||
"password": seeded_db["bob"]["password"],
|
||||
},
|
||||
)
|
||||
r = s.get(
|
||||
f"{BASE_URL}/admin/containers/users/search?q=alice", allow_redirects=False
|
||||
)
|
||||
assert r.status_code in (302, 303, 403)
|
||||
|
||||
|
||||
def test_user_search_returns_results(app_server, seeded_db):
|
||||
s = _admin_session()
|
||||
r = s.get(f"{BASE_URL}/admin/containers/users/search?q=alice")
|
||||
assert r.status_code == 200
|
||||
results = r.json()["results"]
|
||||
assert any(item["username"] == "alice_test" for item in results)
|
||||
|
||||
|
||||
def test_user_search_empty_query(app_server, seeded_db):
|
||||
s = _admin_session()
|
||||
r = s.get(f"{BASE_URL}/admin/containers/users/search?q=")
|
||||
assert r.status_code == 200
|
||||
assert r.json()["results"] == []
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
@@ -138,6 +140,8 @@ def _make_post_bookmarks(owner_uid, title):
|
||||
uid = generate_uid()
|
||||
get_table("posts").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"user_uid": owner_uid,
|
||||
"slug": f"{uid[:8]}-bookmark-post",
|
||||
@@ -155,6 +159,8 @@ def _make_gist(owner_uid, title):
|
||||
uid = generate_uid()
|
||||
get_table("gists").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"user_uid": owner_uid,
|
||||
"slug": f"{uid[:8]}-bookmark-gist",
|
||||
|
||||
@@ -29,6 +29,8 @@ def _make_post_bookmarks(owner_uid, title):
|
||||
uid = generate_uid()
|
||||
get_table("posts").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"user_uid": owner_uid,
|
||||
"slug": f"{uid[:8]}-bookmark-post",
|
||||
@@ -46,6 +48,8 @@ def _make_gist(owner_uid, title):
|
||||
uid = generate_uid()
|
||||
get_table("gists").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"user_uid": owner_uid,
|
||||
"slug": f"{uid[:8]}-bookmark-gist",
|
||||
|
||||
@@ -5,7 +5,7 @@ from datetime import datetime, timezone
|
||||
import pytest
|
||||
import requests
|
||||
from tests.conftest import BASE_URL
|
||||
from devplacepy.database import get_table, refresh_snapshot, set_setting
|
||||
from devplacepy.database import db, get_table, refresh_snapshot, set_setting
|
||||
from devplacepy.utils import generate_uid, make_combined_slug
|
||||
JSON_audit_log = {"Accept": "application/json"}
|
||||
_counter_audit_log = [0]
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
@@ -224,6 +226,7 @@ def test_create_reply_to_comment(app_server):
|
||||
},
|
||||
allow_redirects=False,
|
||||
)
|
||||
refresh_snapshot()
|
||||
parent = get_table("comments").find_one(target_uid=post_uid)
|
||||
r = s.post(
|
||||
f"{BASE_URL}/comments/create",
|
||||
@@ -237,7 +240,13 @@ def test_create_reply_to_comment(app_server):
|
||||
allow_redirects=False,
|
||||
)
|
||||
assert r.status_code in (302, 303)
|
||||
replies = list(get_table("comments").find(parent_uid=parent["uid"]))
|
||||
refresh_snapshot()
|
||||
replies = list(
|
||||
db.query(
|
||||
"SELECT content FROM comments WHERE parent_uid = :p AND deleted_at IS NULL",
|
||||
p=parent["uid"],
|
||||
)
|
||||
)
|
||||
assert len(replies) == 1
|
||||
assert replies[0]["content"] == "Reply to parent"
|
||||
|
||||
|
||||
@@ -84,6 +84,8 @@ def test_http_ingress_proxy(app_server):
|
||||
uid = f"ingtest-{port}"
|
||||
get_table("instances").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"name": "ingress",
|
||||
"project_uid": "ingtest",
|
||||
|
||||
+17
-3
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
@@ -297,6 +299,7 @@ def test_docs_operator_pages_require_admin(seeded_db):
|
||||
assert "/docs/services.html" in admin_index.text
|
||||
finally:
|
||||
users.update({"uid": bob["uid"], "role": "Member"}, ["uid"])
|
||||
clear_user_cache(bob["uid"])
|
||||
|
||||
|
||||
def test_docs_endpoint_config_is_valid_json(app_server):
|
||||
@@ -396,9 +399,20 @@ def test_media_moderation_doc_is_admin_only(seeded_db):
|
||||
# hidden from guests and members
|
||||
assert requests.get(f"{BASE_URL}/docs/media-moderation.html").status_code == 404
|
||||
bob = get_table("users").find_one(username="bob_test")
|
||||
member = requests.get(
|
||||
f"{BASE_URL}/docs/media-moderation.html", headers={"X-API-KEY": bob["api_key"]}
|
||||
)
|
||||
clear_user_cache(bob["uid"])
|
||||
# A prior test may have promoted bob and warmed the server's auth cache; the
|
||||
# cache-version bump propagates cross-process with up to a one second delay,
|
||||
# so poll until the server resolves bob back to a member (404).
|
||||
deadline = time.time() + 5
|
||||
member = None
|
||||
while time.time() < deadline:
|
||||
member = requests.get(
|
||||
f"{BASE_URL}/docs/media-moderation.html",
|
||||
headers={"X-API-KEY": bob["api_key"]},
|
||||
)
|
||||
if member.status_code == 404:
|
||||
break
|
||||
time.sleep(0.2)
|
||||
assert member.status_code == 404
|
||||
# visible to admins, and this is where soft-delete is explained
|
||||
admin = get_table("users").find_one(username="alice_test")
|
||||
|
||||
+27
-1
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
@@ -170,6 +172,8 @@ def _seed_news_seo():
|
||||
slug = make_combined_slug(title, uid)
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": slug,
|
||||
"title": title,
|
||||
@@ -213,6 +217,8 @@ def _seed_post_seo(image=None):
|
||||
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,
|
||||
@@ -237,6 +243,8 @@ def _seed_gist():
|
||||
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,
|
||||
@@ -260,6 +268,8 @@ def _seed_project():
|
||||
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,
|
||||
@@ -278,6 +288,8 @@ def _seed_news_image(news_uid):
|
||||
|
||||
get_table("news_images").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"news_uid": news_uid,
|
||||
"url": "https://example.com/seo-news-image.jpg",
|
||||
}
|
||||
@@ -296,6 +308,8 @@ def _seed_feed_posts(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),
|
||||
@@ -315,9 +329,21 @@ def test_maintenance_block_recorded(seeded_db):
|
||||
admin = _admin(seeded_db)
|
||||
set_setting("maintenance_mode", "1")
|
||||
try:
|
||||
requests.get(f"{BASE_URL}/feed", allow_redirects=False)
|
||||
deadline = time.time() + 5
|
||||
status = None
|
||||
while time.time() < deadline:
|
||||
status = requests.get(f"{BASE_URL}/feed", allow_redirects=False).status_code
|
||||
if status == 503:
|
||||
break
|
||||
time.sleep(0.2)
|
||||
assert status == 503
|
||||
finally:
|
||||
set_setting("maintenance_mode", "0")
|
||||
deadline = time.time() + 5
|
||||
while time.time() < deadline:
|
||||
if requests.get(f"{BASE_URL}/feed", allow_redirects=False).status_code != 503:
|
||||
break
|
||||
time.sleep(0.2)
|
||||
event = _find(admin, "security.maintenance.block", lambda e: True)
|
||||
assert event is not None
|
||||
assert event["result"] == "denied"
|
||||
|
||||
@@ -121,6 +121,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -52,6 +52,8 @@ def _make_source_project(*, is_private=False, binary=False):
|
||||
)
|
||||
get_table("projects").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": pid,
|
||||
"user_uid": owner_uid,
|
||||
"slug": f"{pid}-source",
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
@@ -159,6 +161,8 @@ def _seed_gists(count):
|
||||
title = f"Pag Gist {i}"
|
||||
gists.insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"user_uid": owner,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
|
||||
@@ -12,6 +12,8 @@ def _seed_news_seo():
|
||||
slug = make_combined_slug(title, uid)
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": slug,
|
||||
"title": title,
|
||||
@@ -55,6 +57,8 @@ def _seed_post_seo(image=None):
|
||||
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,
|
||||
@@ -79,6 +83,8 @@ def _seed_gist():
|
||||
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,
|
||||
@@ -102,6 +108,8 @@ def _seed_project():
|
||||
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,
|
||||
@@ -120,6 +128,8 @@ def _seed_news_image(news_uid):
|
||||
|
||||
get_table("news_images").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"news_uid": news_uid,
|
||||
"url": "https://example.com/seo-news-image.jpg",
|
||||
}
|
||||
@@ -138,6 +148,8 @@ def _seed_feed_posts(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),
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import time
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
import websockets
|
||||
|
||||
from tests.conftest import BASE_URL, PORT
|
||||
from devplacepy.database import get_table, refresh_snapshot, set_setting
|
||||
|
||||
WS_URL = f"ws://127.0.0.1:{PORT}/messages/ws"
|
||||
_counter = [0]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def _ws_settings(app_server):
|
||||
for key, value in {
|
||||
"rate_limit_per_minute": "1000000",
|
||||
"rate_limit_window_seconds": "60",
|
||||
"registration_open": "1",
|
||||
"maintenance_mode": "0",
|
||||
}.items():
|
||||
set_setting(key, value)
|
||||
yield
|
||||
|
||||
|
||||
def _db_user(name):
|
||||
refresh_snapshot()
|
||||
return get_table("users").find_one(username=name)
|
||||
|
||||
|
||||
def _unique(prefix="wsm"):
|
||||
_counter[0] += 1
|
||||
return f"{prefix}{int(time.time() * 1000)}{_counter[0]}"
|
||||
|
||||
|
||||
def _member():
|
||||
name = _unique()
|
||||
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,
|
||||
)
|
||||
return s, name
|
||||
|
||||
|
||||
def _cookie_header(session):
|
||||
token = session.cookies.get("session")
|
||||
assert token, "expected a session cookie after signup"
|
||||
return {"Cookie": f"session={token}"}
|
||||
|
||||
|
||||
async def _recv_until(ws, frame_type, timeout=5.0):
|
||||
deadline = asyncio.get_event_loop().time() + timeout
|
||||
while True:
|
||||
remaining = deadline - asyncio.get_event_loop().time()
|
||||
if remaining <= 0:
|
||||
raise AssertionError(f"timed out waiting for {frame_type}")
|
||||
raw = await asyncio.wait_for(ws.recv(), timeout=remaining)
|
||||
frame = json.loads(raw)
|
||||
if frame.get("type") == frame_type:
|
||||
return frame
|
||||
|
||||
|
||||
def test_ws_requires_authentication(app_server):
|
||||
async def run():
|
||||
async with websockets.connect(WS_URL) as ws:
|
||||
with pytest.raises(websockets.exceptions.ConnectionClosed):
|
||||
await asyncio.wait_for(ws.recv(), timeout=3.0)
|
||||
|
||||
asyncio.run(run())
|
||||
|
||||
|
||||
def test_ws_send_broadcasts_to_both_parties(app_server):
|
||||
sender_session, _ = _member()
|
||||
receiver_session, receiver_name = _member()
|
||||
receiver_uid = _db_user(receiver_name)["uid"]
|
||||
client_id = "cid-" + _unique("c")
|
||||
|
||||
async def run():
|
||||
async with websockets.connect(
|
||||
WS_URL, additional_headers=_cookie_header(sender_session)
|
||||
) as sender_ws, websockets.connect(
|
||||
WS_URL, additional_headers=_cookie_header(receiver_session)
|
||||
) as receiver_ws:
|
||||
await _recv_until(sender_ws, "ready")
|
||||
await _recv_until(receiver_ws, "ready")
|
||||
|
||||
await sender_ws.send(
|
||||
json.dumps(
|
||||
{
|
||||
"type": "send",
|
||||
"receiver_uid": receiver_uid,
|
||||
"content": "hello over the wire",
|
||||
"client_id": client_id,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
echo = await _recv_until(sender_ws, "message")
|
||||
assert echo["client_id"] == client_id
|
||||
assert echo["content"] == "hello over the wire"
|
||||
assert echo["receiver_uid"] == receiver_uid
|
||||
|
||||
delivered = await _recv_until(receiver_ws, "message")
|
||||
assert delivered["content"] == "hello over the wire"
|
||||
assert delivered["sender_uid"] == echo["sender_uid"]
|
||||
|
||||
asyncio.run(run())
|
||||
|
||||
|
||||
def test_ws_typing_relays_to_receiver_only(app_server):
|
||||
sender_session, sender_name = _member()
|
||||
receiver_session, receiver_name = _member()
|
||||
sender_uid = _db_user(sender_name)["uid"]
|
||||
receiver_uid = _db_user(receiver_name)["uid"]
|
||||
|
||||
async def run():
|
||||
async with websockets.connect(
|
||||
WS_URL, additional_headers=_cookie_header(sender_session)
|
||||
) as sender_ws, websockets.connect(
|
||||
WS_URL, additional_headers=_cookie_header(receiver_session)
|
||||
) as receiver_ws:
|
||||
await _recv_until(sender_ws, "ready")
|
||||
await _recv_until(receiver_ws, "ready")
|
||||
|
||||
await sender_ws.send(
|
||||
json.dumps({"type": "typing", "receiver_uid": receiver_uid})
|
||||
)
|
||||
typing = await _recv_until(receiver_ws, "typing")
|
||||
assert typing["from_uid"] == sender_uid
|
||||
|
||||
asyncio.run(run())
|
||||
|
||||
|
||||
def test_ws_read_marks_and_notifies(app_server):
|
||||
sender_session, sender_name = _member()
|
||||
receiver_session, receiver_name = _member()
|
||||
sender_uid = _db_user(sender_name)["uid"]
|
||||
receiver_uid = _db_user(receiver_name)["uid"]
|
||||
|
||||
sender_session.post(
|
||||
f"{BASE_URL}/messages/send",
|
||||
headers={"Accept": "application/json"},
|
||||
data={"content": "read me please", "receiver_uid": receiver_uid},
|
||||
)
|
||||
|
||||
async def run():
|
||||
async with websockets.connect(
|
||||
WS_URL, additional_headers=_cookie_header(sender_session)
|
||||
) as sender_ws, websockets.connect(
|
||||
WS_URL, additional_headers=_cookie_header(receiver_session)
|
||||
) as receiver_ws:
|
||||
await _recv_until(sender_ws, "ready")
|
||||
await _recv_until(receiver_ws, "ready")
|
||||
|
||||
await receiver_ws.send(
|
||||
json.dumps({"type": "read", "with_uid": sender_uid})
|
||||
)
|
||||
receipt = await _recv_until(sender_ws, "read")
|
||||
assert receipt["by_uid"] == receiver_uid
|
||||
|
||||
asyncio.run(run())
|
||||
refresh_snapshot()
|
||||
rows = list(
|
||||
get_table("messages").find(
|
||||
sender_uid=sender_uid, receiver_uid=receiver_uid, read=True
|
||||
)
|
||||
)
|
||||
assert rows, "messages should be marked read after the read frame"
|
||||
@@ -12,6 +12,8 @@ def _seed_news_seo():
|
||||
slug = make_combined_slug(title, uid)
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": slug,
|
||||
"title": title,
|
||||
@@ -55,6 +57,8 @@ def _seed_post_seo(image=None):
|
||||
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,
|
||||
@@ -79,6 +83,8 @@ def _seed_gist():
|
||||
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,
|
||||
@@ -102,6 +108,8 @@ def _seed_project():
|
||||
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,
|
||||
@@ -120,6 +128,8 @@ def _seed_news_image(news_uid):
|
||||
|
||||
get_table("news_images").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"news_uid": news_uid,
|
||||
"url": "https://example.com/seo-news-image.jpg",
|
||||
}
|
||||
@@ -138,6 +148,8 @@ def _seed_feed_posts(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),
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
@@ -222,6 +224,8 @@ def _make_post_reactions(owner_uid):
|
||||
uid = generate_uid()
|
||||
get_table("posts").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"user_uid": owner_uid,
|
||||
"slug": f"{uid[:8]}-reaction-post",
|
||||
@@ -239,6 +243,8 @@ def _make_comment(post_uid, owner_uid):
|
||||
uid = generate_uid()
|
||||
get_table("comments").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"target_type": "post",
|
||||
"target_uid": post_uid,
|
||||
@@ -260,6 +266,8 @@ def _seed_news_seo():
|
||||
slug = make_combined_slug(title, uid)
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": slug,
|
||||
"title": title,
|
||||
@@ -303,6 +311,8 @@ def _seed_post_seo(image=None):
|
||||
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,
|
||||
@@ -327,6 +337,8 @@ def _seed_gist():
|
||||
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,
|
||||
@@ -350,6 +362,8 @@ def _seed_project():
|
||||
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,
|
||||
@@ -368,6 +382,8 @@ def _seed_news_image(news_uid):
|
||||
|
||||
get_table("news_images").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"news_uid": news_uid,
|
||||
"url": "https://example.com/seo-news-image.jpg",
|
||||
}
|
||||
@@ -386,6 +402,8 @@ def _seed_feed_posts(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),
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -12,6 +12,8 @@ def _seed_news_seo():
|
||||
slug = make_combined_slug(title, uid)
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": slug,
|
||||
"title": title,
|
||||
@@ -55,6 +57,8 @@ def _seed_post_seo(image=None):
|
||||
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,
|
||||
@@ -79,6 +83,8 @@ def _seed_gist():
|
||||
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,
|
||||
@@ -102,6 +108,8 @@ def _seed_project():
|
||||
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,
|
||||
@@ -120,6 +128,8 @@ def _seed_news_image(news_uid):
|
||||
|
||||
get_table("news_images").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"news_uid": news_uid,
|
||||
"url": "https://example.com/seo-news-image.jpg",
|
||||
}
|
||||
@@ -138,6 +148,8 @@ def _seed_feed_posts(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),
|
||||
|
||||
@@ -156,6 +156,8 @@ def _insert_post(user_uid, dt):
|
||||
uid = generate_uid()
|
||||
get_table("posts").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"user_uid": user_uid,
|
||||
"slug": f"{uid[:8]}-streak",
|
||||
@@ -173,6 +175,8 @@ def _insert_comment(user_uid, post_uid, dt):
|
||||
uid = generate_uid()
|
||||
get_table("comments").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"target_type": "post",
|
||||
"target_uid": post_uid,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
@@ -197,6 +199,8 @@ def _seed_news_seo():
|
||||
slug = make_combined_slug(title, uid)
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": slug,
|
||||
"title": title,
|
||||
@@ -240,6 +244,8 @@ def _seed_post_seo(image=None):
|
||||
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,
|
||||
@@ -264,6 +270,8 @@ def _seed_gist():
|
||||
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,
|
||||
@@ -287,6 +295,8 @@ def _seed_project():
|
||||
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,
|
||||
@@ -305,6 +315,8 @@ def _seed_news_image(news_uid):
|
||||
|
||||
get_table("news_images").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"news_uid": news_uid,
|
||||
"url": "https://example.com/seo-news-image.jpg",
|
||||
}
|
||||
@@ -323,6 +335,8 @@ def _seed_feed_posts(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),
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
@@ -158,6 +160,8 @@ def _make_post_reactions(owner_uid):
|
||||
uid = generate_uid()
|
||||
get_table("posts").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"user_uid": owner_uid,
|
||||
"slug": f"{uid[:8]}-reaction-post",
|
||||
@@ -175,6 +179,8 @@ def _make_comment(post_uid, owner_uid):
|
||||
uid = generate_uid()
|
||||
get_table("comments").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"target_type": "post",
|
||||
"target_uid": post_uid,
|
||||
|
||||
@@ -25,6 +25,8 @@ def _seed_news_seo():
|
||||
slug = make_combined_slug(title, uid)
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": slug,
|
||||
"title": title,
|
||||
@@ -68,6 +70,8 @@ def _seed_post_seo(image=None):
|
||||
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,
|
||||
@@ -92,6 +96,8 @@ def _seed_gist():
|
||||
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,
|
||||
@@ -115,6 +121,8 @@ def _seed_project():
|
||||
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,
|
||||
@@ -133,6 +141,8 @@ def _seed_news_image(news_uid):
|
||||
|
||||
get_table("news_images").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"news_uid": news_uid,
|
||||
"url": "https://example.com/seo-news-image.jpg",
|
||||
}
|
||||
@@ -151,6 +161,8 @@ def _seed_feed_posts(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),
|
||||
|
||||
@@ -88,6 +88,8 @@ def _seed_news_seo():
|
||||
slug = make_combined_slug(title, uid)
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": slug,
|
||||
"title": title,
|
||||
@@ -131,6 +133,8 @@ def _seed_post_seo(image=None):
|
||||
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,
|
||||
@@ -155,6 +159,8 @@ def _seed_gist():
|
||||
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,
|
||||
@@ -178,6 +184,8 @@ def _seed_project():
|
||||
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,
|
||||
@@ -196,6 +204,8 @@ def _seed_news_image(news_uid):
|
||||
|
||||
get_table("news_images").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"news_uid": news_uid,
|
||||
"url": "https://example.com/seo-news-image.jpg",
|
||||
}
|
||||
@@ -214,6 +224,8 @@ def _seed_feed_posts(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),
|
||||
|
||||
@@ -34,6 +34,8 @@ def _insert_post(user_uid, dt):
|
||||
uid = generate_uid()
|
||||
get_table("posts").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"user_uid": user_uid,
|
||||
"slug": f"{uid[:8]}-streak",
|
||||
@@ -51,6 +53,8 @@ def _insert_comment(user_uid, post_uid, dt):
|
||||
uid = generate_uid()
|
||||
get_table("comments").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"target_type": "post",
|
||||
"target_uid": post_uid,
|
||||
|
||||
@@ -98,6 +98,8 @@ def _seed_news_audit_log():
|
||||
title = _unique("aunews")
|
||||
get_table("news").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"slug": make_combined_slug(title, uid),
|
||||
"title": title,
|
||||
|
||||
@@ -43,6 +43,8 @@ def _make_post_votes(owner_uid):
|
||||
uid = generate_uid()
|
||||
get_table("posts").insert(
|
||||
{
|
||||
"deleted_at": None,
|
||||
"deleted_by": None,
|
||||
"uid": uid,
|
||||
"user_uid": owner_uid,
|
||||
"slug": f"{uid[:8]}-vote-post",
|
||||
|
||||
Reference in New Issue
Block a user