from pathlib import Path def test_login_page_does_not_disclose_demo_passwords(client): response = client.get('/auth/login') assert response.status_code == 200 assert b'admin' not in response.data assert b'admin
admin' not in response.data
def test_login_rejects_external_next_url(client, admin_user):
response = client.post(
'/auth/login?next=//example.net',
data={'username': admin_user['username'], 'password': admin_user['password']},
)
assert response.status_code == 302
assert 'example.net' not in response.headers['Location']
def test_setup_requires_token(client, monkeypatch, tmp_path):
from app_new.core.routes import setup_wizard
monkeypatch.setattr(setup_wizard, 'DATA_DIR', str(tmp_path))
assert client.get('/setup-wizard/').status_code == 403
assert client.get('/setup-wizard/?token=invalid').status_code == 403
def test_setup_token_is_removed_from_url(client, monkeypatch, tmp_path):
from app_new.core.routes import setup_wizard
monkeypatch.setattr(setup_wizard, 'DATA_DIR', str(tmp_path))
token = 'test-setup-token-with-at-least-32-characters'
response = client.get(f'/setup-wizard/?token={token}')
assert response.status_code == 302
assert 'token=' not in response.headers['Location']
assert client.get('/setup-wizard/').status_code == 200
def test_completed_setup_rejects_mutation(client, monkeypatch, tmp_path):
from app_new.core.routes import setup_wizard
monkeypatch.setattr(setup_wizard, 'DATA_DIR', str(tmp_path))
Path(tmp_path, '.setup_complete').write_text('complete', encoding='utf-8')
response = client.post('/setup-wizard/api/step/1', json={
'username': 'new-admin',
'password': 'a-strong-password',
})
assert response.status_code == 403