mirror of
https://github.com/Sudo-JHare/FHIRFLARE-IG-Toolkit.git
synced 2025-06-15 17:20:00 +00:00
165 lines
6.6 KiB
Python
165 lines
6.6 KiB
Python
# tests/test_auth.py
|
|
|
|
import pytest
|
|
from flask import url_for, session, request # Keep request import
|
|
from app.models import User
|
|
from app import db
|
|
from urllib.parse import urlparse, parse_qs # Keep URL parsing tools
|
|
|
|
# --- Helper to create a user ---
|
|
# (Using the version that defaults email based on username)
|
|
def create_test_user(username="testuser", email=None, password="password", role="user"):
|
|
"""Helper function to add a user to the test database."""
|
|
if email is None:
|
|
email = f"{username}@example.test" # Default email based on username
|
|
# Check if user already exists by username or email
|
|
user = User.query.filter((User.username == username) | (User.email == email)).first()
|
|
if user:
|
|
print(f"\nDEBUG: Found existing test user '{user.username}' with ID {user.id}")
|
|
return user
|
|
user = User(username=username, email=email, role=role)
|
|
user.set_password(password)
|
|
db.session.add(user)
|
|
db.session.commit()
|
|
print(f"\nDEBUG: Created test user '{username}' (Role: {role}) with ID {user.id}")
|
|
return user
|
|
|
|
# --- Tests ---
|
|
|
|
def test_login_page_loads(client):
|
|
"""Test that the login page loads correctly."""
|
|
response = client.get(url_for('auth.login'))
|
|
assert response.status_code == 200
|
|
assert b"Login" in response.data
|
|
assert b"Username" in response.data
|
|
assert b"Password" in response.data
|
|
|
|
def test_successful_login_as_admin(client, app):
|
|
"""Test logging in with correct ADMIN credentials."""
|
|
with app.app_context():
|
|
admin_user = create_test_user(
|
|
username="test_admin",
|
|
email="admin@example.test",
|
|
password="password",
|
|
role="admin"
|
|
)
|
|
assert admin_user.id is not None
|
|
assert admin_user.role == 'admin'
|
|
|
|
response = client.post(url_for('auth.login'), data={
|
|
'username': 'test_admin',
|
|
'password': 'password'
|
|
}, follow_redirects=True)
|
|
|
|
assert response.status_code == 200
|
|
assert b"Logout" in response.data
|
|
assert bytes(f"{admin_user.username}", 'utf-8') in response.data
|
|
assert b"Control Panel" in response.data
|
|
# --- CORRECTED ASSERTION ---
|
|
assert b"Manage Modules" in response.data # Check for the button/link text
|
|
|
|
|
|
def test_login_wrong_password(client, app):
|
|
"""Test logging in with incorrect password."""
|
|
with app.app_context():
|
|
create_test_user(username="wrong_pass_user", password="password")
|
|
response = client.post(url_for('auth.login'), data={
|
|
'username': 'wrong_pass_user',
|
|
'password': 'wrongpassword'
|
|
}, follow_redirects=True)
|
|
assert response.status_code == 200
|
|
assert b"Invalid username or password" in response.data
|
|
assert b"Logout" not in response.data
|
|
|
|
def test_login_wrong_username(client):
|
|
"""Test logging in with non-existent username."""
|
|
response = client.post(url_for('auth.login'), data={
|
|
'username': 'nosuchuser',
|
|
'password': 'password'
|
|
}, follow_redirects=True)
|
|
assert response.status_code == 200
|
|
assert b"Invalid username or password" in response.data
|
|
assert b"Logout" not in response.data
|
|
|
|
def test_successful_login_as_user(client, app):
|
|
"""Test logging in with correct USER credentials."""
|
|
with app.app_context():
|
|
test_user = create_test_user(
|
|
username="test_user",
|
|
email="user@example.test",
|
|
password="password",
|
|
role="user"
|
|
)
|
|
assert test_user.id is not None
|
|
assert test_user.role == 'user'
|
|
response = client.post(url_for('auth.login'), data={
|
|
'username': 'test_user',
|
|
'password': 'password'
|
|
}, follow_redirects=True)
|
|
assert response.status_code == 200
|
|
assert b"Logout" in response.data
|
|
assert bytes(f"{test_user.username}", 'utf-8') in response.data
|
|
assert b"Control Panel" not in response.data
|
|
site_name = app.config.get('SITE_NAME', 'PAS Framework')
|
|
assert bytes(site_name, 'utf-8') in response.data
|
|
|
|
|
|
# --- Replace the existing test_logout function with this: ---
|
|
def test_logout(client, app):
|
|
"""Test logging out."""
|
|
with app.app_context():
|
|
user = create_test_user(username='logout_user', password='password')
|
|
login_res = client.post(url_for('auth.login'), data={'username': 'logout_user', 'password': 'password'})
|
|
assert login_res.status_code == 302
|
|
|
|
logout_response = client.get(url_for('auth.logout'), follow_redirects=True)
|
|
assert logout_response.status_code == 200
|
|
assert b"You have been logged out." in logout_response.data
|
|
assert b"Login" in logout_response.data
|
|
assert b"Logout" not in logout_response.data
|
|
|
|
# Assert: Accessing protected page redirects to login
|
|
protected_response = client.get(url_for('control_panel.index'), follow_redirects=False)
|
|
assert protected_response.status_code == 302
|
|
|
|
# --- Use Manual Path Comparison ---
|
|
redirect_location = protected_response.headers.get('Location', '')
|
|
parsed_location = urlparse(redirect_location)
|
|
query_params = parse_qs(parsed_location.query)
|
|
|
|
# Manually define the expected RELATIVE paths
|
|
expected_login_path_manual = '/auth/login'
|
|
expected_next_path_manual = '/control-panel/' # Includes trailing slash from previous logs
|
|
|
|
# Compare the path from the header with the known relative string
|
|
assert parsed_location.path == expected_login_path_manual
|
|
|
|
# Check the 'next' parameter
|
|
assert 'next' in query_params
|
|
assert query_params['next'][0] == expected_next_path_manual
|
|
|
|
|
|
# --- Replace the existing test_login_required_redirect function with this: ---
|
|
def test_login_required_redirect(client, app):
|
|
"""Test that accessing a protected page redirects to login when logged out."""
|
|
# Act: Attempt to access control panel index
|
|
response = client.get(url_for('control_panel.index'), follow_redirects=False)
|
|
|
|
# Assert: Check for redirect status code (302)
|
|
assert response.status_code == 302
|
|
|
|
# --- Use Manual Path Comparison ---
|
|
redirect_location = response.headers.get('Location', '')
|
|
parsed_location = urlparse(redirect_location)
|
|
query_params = parse_qs(parsed_location.query)
|
|
|
|
# Manually define the expected RELATIVE paths
|
|
expected_login_path_manual = '/auth/login'
|
|
expected_next_path_manual = '/control-panel/' # Includes trailing slash
|
|
|
|
# Compare the path from the header with the known relative string
|
|
assert parsed_location.path == expected_login_path_manual
|
|
|
|
# Check the 'next' query parameter exists and has the correct value
|
|
assert 'next' in query_params
|
|
assert query_params['next'][0] == expected_next_path_manual |