feat: add test suites for backup schedules, service config, auth token, bookmarks, content permissions, devii adopt, and devrant auth

Add comprehensive test coverage for seven new API areas:
- Backup schedules CRUD operations in admin panel
- Service configuration saving and retrieval for news AI model
- Token authentication with email/username and JSON body support
- Bookmarking for project and news targets with invalid type validation
- Content permissions testing with member and admin session fixtures
- Devii adopt endpoint redirect behavior and session cookie handling
- Devrant authentication flow with user registration and token retrieval
This commit is contained in:
2026-06-23 00:47:40 +00:00
parent 34e33995c4
commit e773067106
28 changed files with 2737 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
# retoor <retoor@molodetz.nl>
import time
from playwright.sync_api import expect
from tests.conftest import BASE_URL
from devplacepy.database import get_table, refresh_snapshot
def test_admin_creates_backup_schedule_via_modal(alice):
page, user = alice
name = f"Nightly {int(time.time() * 1000)}"
page.goto(f"{BASE_URL}/admin/backups", wait_until="domcontentloaded")
page.locator("#backup-schedule-new").click()
expect(page.locator("#backup-schedule-modal")).to_be_visible()
page.locator("#backup-schedule-name").fill(name)
page.locator("#backup-schedule-target").select_option("database")
page.locator("#backup-schedule-kind").select_option("interval")
page.locator("#backup-schedule-every").fill("3600")
page.locator("#backup-schedule-form button[type='submit']").click()
page.wait_for_url("**/admin/backups", wait_until="domcontentloaded")
expect(page.locator(f"text={name}")).to_be_visible()
refresh_snapshot()
row = get_table("backup_schedules").find_one(name=name, deleted_at=None)
assert row is not None
assert row["target"] == "database"
def test_non_admin_cannot_open_backups_page(bob):
page, user = bob
page.goto(f"{BASE_URL}/admin/backups", wait_until="domcontentloaded")
expect(page.locator("#backup-schedule-new")).to_have_count(0)
+56
View File
@@ -0,0 +1,56 @@
# retoor <retoor@molodetz.nl>
from playwright.sync_api import expect
from tests.conftest import BASE_URL
from devplacepy.database import get_table, refresh_snapshot
from devplacepy.utils import clear_user_cache
def _user(username):
refresh_snapshot()
return get_table("users").find_one(username=username)
def _reset(uid):
get_table("users").update(
{"uid": uid, "ai_correction_enabled": 0, "ai_correction_sync": 0}, ["uid"]
)
clear_user_cache(uid)
def _profile(page, username):
page.goto(f"{BASE_URL}/profile/{username}", wait_until="domcontentloaded")
def test_owner_sees_ai_correction_block(bob):
page, user = bob
_reset(_user(user["username"])["uid"])
_profile(page, user["username"])
expect(page.locator("[data-ai-correction]")).to_be_visible()
expect(page.locator("[data-ai-correction-save]")).to_be_visible()
def test_owner_enables_and_saves(bob):
page, user = bob
uid = _user(user["username"])["uid"]
_reset(uid)
_profile(page, user["username"])
toggle = page.locator("[data-ai-correction-toggle]")
if not toggle.is_checked():
toggle.check()
page.locator("[data-ai-correction-prompt]").fill("Fix only casing and punctuation")
page.locator("[data-ai-correction-save]").click()
expect(page.locator("[data-ai-correction-status]")).to_have_text("Saved", timeout=10000)
refresh_snapshot()
row = get_table("users").find_one(uid=uid)
assert row["ai_correction_enabled"] == 1
assert row["ai_correction_prompt"] == "Fix only casing and punctuation"
def test_non_owner_does_not_see_block(bob, seeded_db):
page, user = bob
_profile(page, seeded_db["alice"]["username"])
expect(page.locator("[data-ai-correction]")).to_have_count(0)
+56
View File
@@ -0,0 +1,56 @@
# retoor <retoor@molodetz.nl>
from playwright.sync_api import expect
from tests.conftest import BASE_URL
from devplacepy.database import get_table, refresh_snapshot
from devplacepy.utils import clear_user_cache
def _user(username):
refresh_snapshot()
return get_table("users").find_one(username=username)
def _reset(uid):
get_table("users").update(
{"uid": uid, "ai_modifier_enabled": 0, "ai_modifier_sync": 0}, ["uid"]
)
clear_user_cache(uid)
def _profile(page, username):
page.goto(f"{BASE_URL}/profile/{username}", wait_until="domcontentloaded")
def test_owner_sees_ai_modifier_block(bob):
page, user = bob
_reset(_user(user["username"])["uid"])
_profile(page, user["username"])
expect(page.locator("[data-ai-modifier]")).to_be_visible()
expect(page.locator("[data-ai-modifier-save]")).to_be_visible()
def test_owner_enables_and_saves(bob):
page, user = bob
uid = _user(user["username"])["uid"]
_reset(uid)
_profile(page, user["username"])
toggle = page.locator("[data-ai-modifier-toggle]")
if not toggle.is_checked():
toggle.check()
page.locator("[data-ai-modifier-prompt]").fill("Run the @ai instruction")
page.locator("[data-ai-modifier-save]").click()
expect(page.locator("[data-ai-modifier-status]")).to_have_text("Saved", timeout=10000)
refresh_snapshot()
row = get_table("users").find_one(uid=uid)
assert row["ai_modifier_enabled"] == 1
assert row["ai_modifier_prompt"] == "Run the @ai instruction"
def test_non_owner_does_not_see_block(bob, seeded_db):
page, user = bob
_profile(page, seeded_db["alice"]["username"])
expect(page.locator("[data-ai-modifier]")).to_have_count(0)