feat: Enhance project and scenario creation with monitoring metrics
- Added monitoring metrics for project creation success and error handling in `ProjectRepository`. - Implemented similar monitoring for scenario creation in `ScenarioRepository`. - Refactored `run_monte_carlo` function in `simulation.py` to include timing and success/error metrics. - Introduced new CSS styles for headers, alerts, and navigation buttons in `main.css` and `projects.css`. - Created a new JavaScript file for navigation logic to handle chevron buttons. - Updated HTML templates to include new navigation buttons and improved styling for buttons. - Added tests for reporting service and routes to ensure proper functionality and access control. - Removed unused imports and optimized existing test files for better clarity and performance.
This commit is contained in:
@@ -284,3 +284,110 @@ class TestLogoutFlow:
|
||||
set_cookie_header = response.headers.get("set-cookie") or ""
|
||||
assert "calminer_access_token=" in set_cookie_header
|
||||
assert "Max-Age=0" in set_cookie_header or "expires=" in set_cookie_header.lower()
|
||||
|
||||
|
||||
class TestLoginFlowEndToEnd:
|
||||
def test_get_login_form_renders(self, client: TestClient) -> None:
|
||||
response = client.get("/login")
|
||||
assert response.status_code == 200
|
||||
assert "login-form" in response.text
|
||||
assert "username" in response.text
|
||||
|
||||
def test_unauthenticated_root_redirects_to_login(self, client: TestClient) -> None:
|
||||
# Temporarily override to anonymous session
|
||||
app = cast(FastAPI, client.app)
|
||||
original_override = app.dependency_overrides.get(get_auth_session)
|
||||
app.dependency_overrides[get_auth_session] = lambda: AuthSession.anonymous(
|
||||
)
|
||||
try:
|
||||
response = client.get("/", follow_redirects=False)
|
||||
assert response.status_code == 303
|
||||
assert response.headers.get(
|
||||
"location") == "http://testserver/login"
|
||||
finally:
|
||||
if original_override is not None:
|
||||
app.dependency_overrides[get_auth_session] = original_override
|
||||
else:
|
||||
app.dependency_overrides.pop(get_auth_session, None)
|
||||
|
||||
def test_login_success_redirects_to_dashboard_and_sets_session(
|
||||
self, client: TestClient, db_session: Session
|
||||
) -> None:
|
||||
password = "TestP@ss123"
|
||||
user = User(
|
||||
email="e2e@example.com",
|
||||
username="e2euser",
|
||||
password_hash=hash_password(password),
|
||||
is_active=True,
|
||||
)
|
||||
db_session.add(user)
|
||||
db_session.commit()
|
||||
|
||||
# Override to anonymous for login
|
||||
app = cast(FastAPI, client.app)
|
||||
app.dependency_overrides[get_auth_session] = lambda: AuthSession.anonymous(
|
||||
)
|
||||
try:
|
||||
login_response = client.post(
|
||||
"/login",
|
||||
data={"username": "e2euser", "password": password},
|
||||
follow_redirects=False,
|
||||
)
|
||||
assert login_response.status_code == 303
|
||||
assert login_response.headers.get(
|
||||
"location") == "http://testserver/"
|
||||
set_cookie_header = login_response.headers.get("set-cookie", "")
|
||||
assert "calminer_access_token=" in set_cookie_header
|
||||
|
||||
# Now with cookies, GET / should show dashboard
|
||||
dashboard_response = client.get("/")
|
||||
assert dashboard_response.status_code == 200
|
||||
assert "Dashboard" in dashboard_response.text or "metrics" in dashboard_response.text
|
||||
finally:
|
||||
app.dependency_overrides.pop(get_auth_session, None)
|
||||
|
||||
def test_logout_redirects_to_login_and_clears_session(self, client: TestClient) -> None:
|
||||
# Assuming authenticated from conftest
|
||||
logout_response = client.get("/logout", follow_redirects=False)
|
||||
assert logout_response.status_code == 303
|
||||
location = logout_response.headers.get("location")
|
||||
assert location and "login" in location
|
||||
set_cookie_header = logout_response.headers.get("set-cookie", "")
|
||||
assert "calminer_access_token=" in set_cookie_header
|
||||
assert "Max-Age=0" in set_cookie_header or "expires=" in set_cookie_header.lower()
|
||||
|
||||
# After logout, GET / should redirect to login
|
||||
app = cast(FastAPI, client.app)
|
||||
app.dependency_overrides[get_auth_session] = lambda: AuthSession.anonymous(
|
||||
)
|
||||
try:
|
||||
root_response = client.get("/", follow_redirects=False)
|
||||
assert root_response.status_code == 303
|
||||
assert root_response.headers.get(
|
||||
"location") == "http://testserver/login"
|
||||
finally:
|
||||
app.dependency_overrides.pop(get_auth_session, None)
|
||||
|
||||
def test_login_inactive_user_shows_error(self, client: TestClient, db_session: Session) -> None:
|
||||
user = User(
|
||||
email="inactive@example.com",
|
||||
username="inactiveuser",
|
||||
password_hash=hash_password("TestP@ss123"),
|
||||
is_active=False,
|
||||
)
|
||||
db_session.add(user)
|
||||
db_session.commit()
|
||||
|
||||
app = cast(FastAPI, client.app)
|
||||
app.dependency_overrides[get_auth_session] = lambda: AuthSession.anonymous(
|
||||
)
|
||||
try:
|
||||
response = client.post(
|
||||
"/login",
|
||||
data={"username": "inactiveuser", "password": "TestP@ss123"},
|
||||
follow_redirects=False,
|
||||
)
|
||||
assert response.status_code == 400
|
||||
assert "Account is inactive" in response.text
|
||||
finally:
|
||||
app.dependency_overrides.pop(get_auth_session, None)
|
||||
|
||||
Reference in New Issue
Block a user