chore: remove placeholder update message from repository root

This commit is contained in:
2026-06-14 00:36:10 +00:00
parent 11c528679b
commit 18df2086b8
85 changed files with 682 additions and 5442 deletions
View File
+225
View File
@@ -0,0 +1,225 @@
# retoor <retoor@molodetz.nl>
import requests
from tests.conftest import BASE_URL
from devplacepy.database import get_table, refresh_snapshot
from devplacepy.services.jobs import queue
def _json_headers():
return {"Accept": "application/json"}
def _clear_seo_jobs():
refresh_snapshot()
jobs = get_table("jobs")
for row in list(jobs.find(kind="seo")):
jobs.delete(uid=row["uid"])
def test_seo_page_renders(app_server):
r = requests.get(f"{BASE_URL}/tools/seo")
assert r.status_code == 200
assert "SEO Diagnostics" in r.text
assert "data-seo-form" in r.text
def test_run_enqueues_and_returns_uid(app_server):
try:
r = requests.post(
f"{BASE_URL}/tools/seo/run",
headers=_json_headers(),
data={"url": "https://example.com", "mode": "url", "max_pages": "5"},
)
assert r.status_code == 200, r.text
body = r.json()
uid = body["uid"]
assert uid
assert body["status_url"] == f"/tools/seo/{uid}"
assert body["ws_url"] == f"/tools/seo/{uid}/ws"
refresh_snapshot()
job = queue.get_job(uid)
assert job is not None
assert job["kind"] == "seo"
assert job["status"] == queue.PENDING
assert job["payload"]["url"] == "https://example.com"
assert job["payload"]["max_pages"] == 5
assert job["payload"]["allow_private"] is False
finally:
_clear_seo_jobs()
def test_run_rejects_blank_url(app_server):
try:
r = requests.post(
f"{BASE_URL}/tools/seo/run",
headers=_json_headers(),
data={"url": " ", "mode": "url"},
allow_redirects=False,
)
assert r.status_code in (400, 422), r.text
finally:
_clear_seo_jobs()
def test_run_rejects_invalid_mode(app_server):
try:
r = requests.post(
f"{BASE_URL}/tools/seo/run",
headers=_json_headers(),
data={"url": "https://example.com", "mode": "bogus"},
allow_redirects=False,
)
assert r.status_code in (400, 422), r.text
finally:
_clear_seo_jobs()
def test_run_clamps_max_pages_above_cap(app_server):
try:
r = requests.post(
f"{BASE_URL}/tools/seo/run",
headers=_json_headers(),
data={"url": "https://example.com", "mode": "url", "max_pages": "9999"},
allow_redirects=False,
)
assert r.status_code in (400, 422), r.text
finally:
_clear_seo_jobs()
def test_run_enforces_one_active_job_per_owner(app_server):
try:
first = requests.post(
f"{BASE_URL}/tools/seo/run",
headers=_json_headers(),
data={"url": "https://example.com", "mode": "url"},
)
assert first.status_code == 200, first.text
first_uid = first.json()["uid"]
second = requests.post(
f"{BASE_URL}/tools/seo/run",
headers=_json_headers(),
data={"url": "https://other.example", "mode": "url"},
)
assert second.status_code == 429, second.text
error = second.json()["error"]
assert error["status"] == 429
assert error["uid"] == first_uid
finally:
_clear_seo_jobs()
def test_status_shape_for_pending_job(app_server):
try:
uid = queue.enqueue(
"seo",
{"url": "https://example.com", "mode": "url", "max_pages": 10},
"user",
"seo-status-owner",
"SEO: https://example.com",
)
refresh_snapshot()
r = requests.get(f"{BASE_URL}/tools/seo/{uid}", headers=_json_headers())
assert r.status_code == 200, r.text
body = r.json()
assert body["uid"] == uid
assert body["kind"] == "seo"
assert body["status"] == "pending"
assert body["target"] == "https://example.com"
assert body["mode"] == "url"
assert body["ws_url"] == f"/tools/seo/{uid}/ws"
assert body["report_url"] is None
assert body["score"] is None
assert body["grade"] is None
assert body["page_count"] == 0
finally:
_clear_seo_jobs()
def test_status_unknown_uid_404(app_server):
r = requests.get(
f"{BASE_URL}/tools/seo/nope-not-a-job", headers=_json_headers()
)
assert r.status_code == 404
def test_status_rejects_non_seo_kind(app_server):
try:
uid = queue.enqueue("other", {}, "user", "seo-kind-owner", "x")
refresh_snapshot()
r = requests.get(f"{BASE_URL}/tools/seo/{uid}", headers=_json_headers())
assert r.status_code == 404
finally:
get_table("jobs").delete(kind="other")
def test_report_unknown_uid_404(app_server):
r = requests.get(
f"{BASE_URL}/tools/seo/nope-not-a-job/report", headers=_json_headers()
)
assert r.status_code == 404
def test_report_pending_job_renders_empty(app_server):
try:
uid = queue.enqueue(
"seo",
{"url": "https://example.com", "mode": "url", "max_pages": 10},
"user",
"seo-report-owner",
"SEO: https://example.com",
)
refresh_snapshot()
r = requests.get(
f"{BASE_URL}/tools/seo/{uid}/report", headers=_json_headers()
)
assert r.status_code == 200, r.text
body = r.json()
assert body["uid"] == uid
assert body["status"] == "pending"
assert body["score"] is None
assert body["page_count"] == 0
assert body["pages"] == []
assert body["checks"] == []
finally:
_clear_seo_jobs()
def test_screenshot_unknown_uid_404(app_server):
r = requests.get(f"{BASE_URL}/tools/seo/nope-not-a-job/screenshot/0")
assert r.status_code == 404
def test_screenshot_missing_file_404(app_server):
try:
uid = queue.enqueue(
"seo",
{"url": "https://example.com", "mode": "url", "max_pages": 10},
"user",
"seo-shot-owner",
"SEO: https://example.com",
)
refresh_snapshot()
r = requests.get(f"{BASE_URL}/tools/seo/{uid}/screenshot/0")
assert r.status_code == 404
finally:
_clear_seo_jobs()
def test_screenshot_rejects_path_traversal(app_server):
try:
uid = queue.enqueue(
"seo",
{"url": "https://example.com", "mode": "url", "max_pages": 10},
"user",
"seo-traversal-owner",
"SEO: https://example.com",
)
refresh_snapshot()
r = requests.get(f"{BASE_URL}/tools/seo/{uid}/screenshot/-1")
assert r.status_code == 404
finally:
_clear_seo_jobs()
View File
+39
View File
@@ -0,0 +1,39 @@
# retoor <retoor@molodetz.nl>
from tests.conftest import BASE_URL
from devplacepy.database import get_table, refresh_snapshot
def _clear_seo_jobs():
refresh_snapshot()
jobs = get_table("jobs")
for row in list(jobs.find(kind="seo")):
jobs.delete(uid=row["uid"])
def test_seo_page_loads(page, app_server):
page.goto(f"{BASE_URL}/tools/seo", wait_until="domcontentloaded")
page.locator("[data-seo-tool]").wait_for(state="visible")
page.locator("[data-seo-form] input[name='url']").wait_for(state="visible")
page.locator("[data-seo-run]").wait_for(state="visible")
def test_seo_page_mode_toggle_reveals_pages(page, app_server):
page.goto(f"{BASE_URL}/tools/seo", wait_until="domcontentloaded")
page.locator("[data-seo-form]").wait_for(state="visible")
pages_label = page.locator("[data-seo-pages]")
assert pages_label.is_hidden()
page.locator("[data-seo-mode]").select_option("sitemap")
pages_label.wait_for(state="visible")
def test_seo_form_submit_shows_live_section(alice):
page, _user = alice
try:
page.goto(f"{BASE_URL}/tools/seo", wait_until="domcontentloaded")
page.locator("[data-seo-form]").wait_for(state="visible")
page.locator("[data-seo-form] input[name='url']").fill("https://example.com")
page.locator("[data-seo-run]").click()
page.locator("[data-seo-live]").wait_for(state="visible")
finally:
_clear_seo_jobs()
+69
View File
@@ -0,0 +1,69 @@
# retoor <retoor@molodetz.nl>
import ipaddress
import pytest
from devplacepy import net_guard
from devplacepy.net_guard import BlockedAddressError
from tests.conftest import run_async
def test_loopback_is_blocked():
assert net_guard.is_blocked_address(ipaddress.ip_address("127.0.0.1"))
def test_private_ranges_are_blocked():
assert net_guard.is_blocked_address(ipaddress.ip_address("10.0.0.1"))
assert net_guard.is_blocked_address(ipaddress.ip_address("192.168.1.1"))
assert net_guard.is_blocked_address(ipaddress.ip_address("172.16.0.1"))
def test_link_local_and_unspecified_blocked():
assert net_guard.is_blocked_address(ipaddress.ip_address("169.254.1.1"))
assert net_guard.is_blocked_address(ipaddress.ip_address("0.0.0.0"))
def test_public_address_allowed():
assert not net_guard.is_blocked_address(ipaddress.ip_address("1.1.1.1"))
assert not net_guard.is_blocked_address(ipaddress.ip_address("8.8.8.8"))
def test_ipv4_mapped_ipv6_unwrapped_and_blocked():
mapped = ipaddress.ip_address("::ffff:127.0.0.1")
assert isinstance(net_guard.effective_address(mapped), ipaddress.IPv4Address)
assert net_guard.is_blocked_address(mapped)
def test_nat64_prefix_unwrapped_to_ipv4():
nat64 = ipaddress.ip_address("64:ff9b::7f00:1")
resolved = net_guard.effective_address(nat64)
assert isinstance(resolved, ipaddress.IPv4Address)
assert net_guard.is_blocked_address(nat64)
def test_guard_rejects_non_http_scheme():
with pytest.raises(BlockedAddressError):
run_async(net_guard.guard_public_url("ftp://example.com/x"))
with pytest.raises(BlockedAddressError):
run_async(net_guard.guard_public_url("file:///etc/passwd"))
def test_guard_rejects_missing_host():
with pytest.raises(BlockedAddressError):
run_async(net_guard.guard_public_url("http://"))
def test_guard_rejects_loopback_literal():
with pytest.raises(BlockedAddressError):
run_async(net_guard.guard_public_url("http://127.0.0.1:8080/admin"))
def test_guard_rejects_private_literal():
with pytest.raises(BlockedAddressError):
run_async(net_guard.guard_public_url("http://10.0.0.5/internal"))
def test_guard_allow_private_skips_resolution():
host = run_async(
net_guard.guard_public_url("http://127.0.0.1:9000/x", allow_private=True)
)
assert host == "127.0.0.1"
@@ -0,0 +1,125 @@
# retoor <retoor@molodetz.nl>
from devplacepy.services.jobs.seo.checks import registry
from devplacepy.services.jobs.seo.checks.base import (
Check,
PageContext,
SiteContext,
PASS,
WARN,
FAIL,
INFO,
SKIP,
CRITICAL,
HIGH,
LOW,
)
def _check(status, severity, category="meta"):
return Check(
id=f"{category}.{status}",
category=category,
title="t",
status=status,
severity=severity,
)
def test_all_pass_scores_100_grade_a():
checks = [_check(PASS, HIGH), _check(PASS, CRITICAL)]
result = registry.compute_score(checks)
assert result["score"] == 100
assert result["grade"] == "A"
def test_all_fail_scores_0_grade_f():
checks = [_check(FAIL, HIGH), _check(FAIL, CRITICAL)]
result = registry.compute_score(checks)
assert result["score"] == 0
assert result["grade"] == "F"
def test_warn_gives_half_credit():
result = registry.compute_score([_check(WARN, HIGH)])
assert result["score"] == 50
def test_info_and_skip_excluded_from_weight():
checks = [_check(INFO, LOW), _check(SKIP, LOW), _check(PASS, HIGH)]
result = registry.compute_score(checks)
assert result["score"] == 100
assert result["counts"]["info"] == 1
assert result["counts"]["skip"] == 1
assert result["counts"]["pass"] == 1
def test_informational_severity_zero_weight_ignored():
checks = [_check(FAIL, "info"), _check(PASS, HIGH)]
result = registry.compute_score(checks)
assert result["score"] == 100
def test_severity_weighting_favours_critical():
checks = [_check(FAIL, CRITICAL), _check(PASS, LOW)]
result = registry.compute_score(checks)
assert result["score"] < 50
def test_grade_boundaries():
assert registry._grade(90) == "A"
assert registry._grade(89) == "B"
assert registry._grade(80) == "B"
assert registry._grade(70) == "C"
assert registry._grade(55) == "D"
assert registry._grade(54) == "F"
def test_categories_reported_per_bucket():
checks = [
_check(PASS, HIGH, category="meta"),
_check(FAIL, HIGH, category="links"),
]
result = registry.compute_score(checks)
assert result["categories"]["meta"]["score"] == 100
assert result["categories"]["links"]["score"] == 0
def test_empty_checks_scores_zero():
result = registry.compute_score([])
assert result["score"] == 0
assert result["grade"] == "F"
def test_run_page_checks_returns_checks():
page = PageContext(
requested_url="https://example.com",
url="https://example.com",
status=200,
ok=True,
rendered_html="<html><head><title>Hi</title></head><body></body></html>",
)
site = SiteContext(target_url="https://example.com", base_host="example.com")
checks = registry.run_page_checks(page, site)
assert isinstance(checks, list)
assert all(isinstance(c, Check) for c in checks)
def test_run_site_checks_returns_checks():
site = SiteContext(target_url="https://example.com", base_host="example.com")
checks = registry.run_site_checks(site)
assert isinstance(checks, list)
assert all(isinstance(c, Check) for c in checks)
def test_bad_page_check_does_not_abort(monkeypatch):
def explode(page, site):
raise RuntimeError("boom")
monkeypatch.setattr(registry, "PAGE_CHECKS", [explode])
page = PageContext(url="https://example.com", ok=True)
site = SiteContext(target_url="https://example.com")
checks = registry.run_page_checks(page, site)
assert len(checks) == 1
assert checks[0].status == INFO
assert "explode" in checks[0].id