- 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.
76 lines
2.0 KiB
Python
76 lines
2.0 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import timedelta
|
|
|
|
import pytest
|
|
|
|
from services.security import (
|
|
JWTSettings,
|
|
TokenDecodeError,
|
|
TokenExpiredError,
|
|
TokenTypeMismatchError,
|
|
create_access_token,
|
|
create_refresh_token,
|
|
decode_access_token,
|
|
hash_password,
|
|
verify_password,
|
|
)
|
|
|
|
|
|
def test_hash_password_round_trip() -> None:
|
|
hashed = hash_password("super-secret")
|
|
|
|
assert hashed != "super-secret"
|
|
assert verify_password("super-secret", hashed)
|
|
assert not verify_password("incorrect", hashed)
|
|
|
|
|
|
def test_verify_password_handles_malformed_hash() -> None:
|
|
assert not verify_password("secret", "not-a-valid-hash")
|
|
|
|
|
|
def test_access_token_roundtrip() -> None:
|
|
settings = JWTSettings(secret_key="unit-test-secret")
|
|
|
|
token = create_access_token(
|
|
"user-id-123",
|
|
settings,
|
|
scopes=("read", "write"),
|
|
extra_claims={"custom": "value"},
|
|
)
|
|
|
|
payload = decode_access_token(token, settings)
|
|
|
|
assert payload.sub == "user-id-123"
|
|
assert payload.type == "access"
|
|
assert payload.scopes == ["read", "write"]
|
|
|
|
|
|
def test_refresh_token_type_mismatch() -> None:
|
|
settings = JWTSettings(secret_key="unit-test-secret")
|
|
token = create_refresh_token("user-id-456", settings)
|
|
|
|
with pytest.raises(TokenTypeMismatchError):
|
|
decode_access_token(token, settings)
|
|
|
|
|
|
def test_decode_expired_token() -> None:
|
|
settings = JWTSettings(secret_key="unit-test-secret")
|
|
expired_token = create_access_token(
|
|
"user-id-789",
|
|
settings,
|
|
expires_delta=timedelta(seconds=-5),
|
|
)
|
|
|
|
with pytest.raises(TokenExpiredError):
|
|
decode_access_token(expired_token, settings)
|
|
|
|
|
|
def test_decode_tampered_token() -> None:
|
|
settings = JWTSettings(secret_key="unit-test-secret")
|
|
token = create_access_token("user-id-321", settings)
|
|
tampered = token[:-1] + ("a" if token[-1] != "a" else "b")
|
|
|
|
with pytest.raises(TokenDecodeError):
|
|
decode_access_token(tampered, settings)
|