chore: reorganize test files into domain-specific subdirectories
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
import hashlib
|
||||
import time
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from playwright.sync_api import expect
|
||||
from tests.conftest import BASE_URL
|
||||
from devplacepy.database import get_table
|
||||
from devplacepy.utils import hash_password, generate_uid
|
||||
from uuid import uuid4
|
||||
from datetime import datetime, timezone
|
||||
import requests
|
||||
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(
|
||||
{
|
||||
"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(
|
||||
{
|
||||
"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(
|
||||
{
|
||||
"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(
|
||||
{
|
||||
"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(
|
||||
{
|
||||
"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(
|
||||
{
|
||||
"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_login_page_loads(page, app_server):
|
||||
page.goto(f"{BASE_URL}/auth/login", wait_until="domcontentloaded")
|
||||
assert page.is_visible("h2:has-text('Welcome Back')")
|
||||
assert page.is_visible("#email")
|
||||
assert page.is_visible("#password")
|
||||
assert page.is_visible("button:has-text('Sign in')")
|
||||
|
||||
|
||||
def test_login_nonexistent_email(page, app_server):
|
||||
page.goto(f"{BASE_URL}/auth/login", wait_until="domcontentloaded")
|
||||
page.fill("#email", "nobody@nowhere.devplace")
|
||||
page.fill("#password", "secret123")
|
||||
page.click("button:has-text('Sign in')")
|
||||
expect(page.locator("text=Invalid email or password")).to_be_visible()
|
||||
|
||||
|
||||
def test_signup_link_from_login(page, app_server):
|
||||
page.goto(f"{BASE_URL}/auth/login", wait_until="domcontentloaded")
|
||||
page.click("a:has-text('Create new account')")
|
||||
page.wait_for_url("**/auth/signup", wait_until="domcontentloaded")
|
||||
|
||||
|
||||
def test_login_next_redirects_to_target(page, app_server, seeded_db):
|
||||
page.goto(f"{BASE_URL}/auth/login?next=/gists", wait_until="domcontentloaded")
|
||||
page.fill("#email", seeded_db["alice"]["email"])
|
||||
page.fill("#password", seeded_db["alice"]["password"])
|
||||
page.click("button:has-text('Sign in')")
|
||||
page.wait_for_url("**/gists", wait_until="domcontentloaded")
|
||||
|
||||
|
||||
def test_login_next_rejects_external(page, app_server, seeded_db):
|
||||
page.goto(
|
||||
f"{BASE_URL}/auth/login?next=https://evil.example.com",
|
||||
wait_until="domcontentloaded",
|
||||
)
|
||||
page.fill("#email", seeded_db["alice"]["email"])
|
||||
page.fill("#password", seeded_db["alice"]["password"])
|
||||
page.click("button:has-text('Sign in')")
|
||||
page.wait_for_url("**/feed", wait_until="domcontentloaded")
|
||||
|
||||
|
||||
def test_landing_nav_to_login(page, app_server):
|
||||
page.goto(f"{BASE_URL}/", wait_until="domcontentloaded")
|
||||
page.click("a:has-text('Login')")
|
||||
page.wait_for_url(f"{BASE_URL}/auth/login", wait_until="domcontentloaded")
|
||||
assert page.is_visible("h2:has-text('Welcome Back')")
|
||||
|
||||
|
||||
def test_landing_log_in_link(page, app_server):
|
||||
page.goto(f"{BASE_URL}/", wait_until="domcontentloaded")
|
||||
page.click("text=Log In")
|
||||
page.wait_for_url(f"{BASE_URL}/auth/login", wait_until="domcontentloaded")
|
||||
|
||||
|
||||
def test_login_page_is_noindex(page, app_server):
|
||||
page.goto(f"{BASE_URL}/auth/login", wait_until="domcontentloaded")
|
||||
meta = page.locator('meta[name="robots"]')
|
||||
content = meta.get_attribute("content")
|
||||
assert content and "noindex" in content
|
||||
Reference in New Issue
Block a user