|
import time
|
|
import requests
|
|
from tests.conftest import BASE_URL
|
|
from devplacepy.database import get_table
|
|
|
|
DEFAULT_MAINTENANCE_MESSAGE = "DevPlace is undergoing scheduled maintenance. Please check back shortly."
|
|
|
|
OPERATIONAL_FIELDS = (
|
|
"rate_limit_per_minute",
|
|
"rate_limit_window_seconds",
|
|
"news_service_interval",
|
|
"session_max_age_days",
|
|
"session_remember_days",
|
|
"registration_open",
|
|
"maintenance_mode",
|
|
"maintenance_message",
|
|
)
|
|
|
|
|
|
def _save_settings(page, **fields):
|
|
page.goto(f"{BASE_URL}/admin/settings", wait_until="domcontentloaded")
|
|
for name, value in fields.items():
|
|
locator = page.locator(f"#{name}")
|
|
tag = locator.evaluate("el => el.tagName.toLowerCase()")
|
|
if tag == "select":
|
|
page.select_option(f"#{name}", value)
|
|
else:
|
|
locator.fill(value)
|
|
page.click("button:has-text('Save Settings')")
|
|
page.wait_for_url("**/admin/settings", wait_until="domcontentloaded")
|
|
|
|
|
|
def test_operational_fields_render(alice):
|
|
page, _ = alice
|
|
page.goto(f"{BASE_URL}/admin/settings", wait_until="domcontentloaded")
|
|
assert page.is_visible("text=Operational")
|
|
for field in OPERATIONAL_FIELDS:
|
|
assert page.is_visible(f"#{field}"), field
|
|
|
|
|
|
def test_operational_settings_persist(alice):
|
|
page, _ = alice
|
|
try:
|
|
_save_settings(
|
|
page,
|
|
news_service_interval="1800",
|
|
session_remember_days="14",
|
|
maintenance_message="Custom maintenance text",
|
|
)
|
|
assert page.locator("#news_service_interval").input_value() == "1800"
|
|
assert page.locator("#session_remember_days").input_value() == "14"
|
|
assert page.locator("#maintenance_message").input_value() == "Custom maintenance text"
|
|
finally:
|
|
_save_settings(
|
|
page,
|
|
news_service_interval="3600",
|
|
session_remember_days="30",
|
|
maintenance_message=DEFAULT_MAINTENANCE_MESSAGE,
|
|
)
|
|
|
|
|
|
def test_maintenance_mode_blocks_guests(alice):
|
|
page, _ = alice
|
|
try:
|
|
_save_settings(page, maintenance_mode="1", maintenance_message="Down for tests")
|
|
response = requests.get(f"{BASE_URL}/feed")
|
|
assert response.status_code == 503
|
|
assert "Down for tests" in response.text
|
|
finally:
|
|
_save_settings(page, maintenance_mode="0", maintenance_message=DEFAULT_MAINTENANCE_MESSAGE)
|
|
|
|
|
|
def test_maintenance_mode_admin_retains_access(alice):
|
|
page, _ = alice
|
|
try:
|
|
_save_settings(page, maintenance_mode="1")
|
|
page.goto(f"{BASE_URL}/admin/settings", wait_until="domcontentloaded")
|
|
assert page.is_visible("#maintenance_mode")
|
|
login = requests.get(f"{BASE_URL}/auth/login")
|
|
assert login.status_code == 200
|
|
finally:
|
|
_save_settings(page, maintenance_mode="0")
|
|
|
|
|
|
def test_registration_closed_blocks_signup(alice):
|
|
page, _ = alice
|
|
try:
|
|
_save_settings(page, registration_open="0")
|
|
|
|
signup_page = requests.get(f"{BASE_URL}/auth/signup")
|
|
assert signup_page.status_code == 200
|
|
assert "Registration is currently closed" in signup_page.text
|
|
|
|
attempt = requests.post(
|
|
f"{BASE_URL}/auth/signup",
|
|
data={
|
|
"username": "closed_signup",
|
|
"email": "closed_signup@test.devplace",
|
|
"password": "secret123",
|
|
"confirm_password": "secret123",
|
|
},
|
|
)
|
|
assert "Registration is currently closed" in attempt.text
|
|
assert get_table("users").find_one(username="closed_signup") is None
|
|
finally:
|
|
_save_settings(page, registration_open="1")
|
|
|
|
|
|
def test_registration_open_allows_signup(alice):
|
|
page, _ = alice
|
|
_save_settings(page, registration_open="1")
|
|
signup_page = requests.get(f"{BASE_URL}/auth/signup")
|
|
assert "Registration is currently closed" not in signup_page.text
|
|
assert 'name="username"' in signup_page.text
|
|
|
|
|
|
def test_session_length_setting_applies(alice, browser):
|
|
page, _ = alice
|
|
context = browser.new_context(viewport={"width": 1400, "height": 900})
|
|
guest = context.new_page()
|
|
guest.set_default_timeout(15000)
|
|
try:
|
|
_save_settings(page, session_max_age_days="1")
|
|
|
|
username = f"sesslen_{int(time.time() * 1000)}"
|
|
guest.goto(f"{BASE_URL}/auth/signup", wait_until="domcontentloaded")
|
|
guest.fill("#username", username)
|
|
guest.fill("#email", f"{username}@test.devplace")
|
|
guest.fill("#password", "secret123")
|
|
guest.fill("#confirm_password", "secret123")
|
|
guest.click("button:has-text('Create account')")
|
|
guest.wait_for_url("**/feed", wait_until="domcontentloaded")
|
|
|
|
session_cookie = next(c for c in context.cookies() if c["name"] == "session")
|
|
remaining = session_cookie["expires"] - time.time()
|
|
assert 0 < remaining < 2 * 86400, remaining
|
|
finally:
|
|
guest.close()
|
|
context.close()
|
|
_save_settings(page, session_max_age_days="7")
|