P3 auth cors and distance fixes
This commit is contained in:
@@ -91,21 +91,21 @@ def get_base_speed(age: int) -> float:
|
||||
# Скорость смещения потерявшегося ребёнка (не скорость ходьбы)
|
||||
# ПСО ЭКСТРЕМУМ: 94% найдены в пределах 3 км
|
||||
if age <= 2:
|
||||
return 0.3
|
||||
return 1.0
|
||||
elif age <= 5:
|
||||
return 0.7
|
||||
elif age <= 8:
|
||||
return 1.2
|
||||
elif age <= 12:
|
||||
return 1.5
|
||||
elif age <= 15:
|
||||
return 2.0
|
||||
elif age <= 8:
|
||||
return 3.0
|
||||
elif age <= 12:
|
||||
return 4.0
|
||||
elif age <= 15:
|
||||
return 5.0
|
||||
elif age <= 17:
|
||||
return 2.5
|
||||
return 5.5
|
||||
elif age <= 64:
|
||||
return 2.5
|
||||
return 5.0
|
||||
else: # 65+
|
||||
return 1.5
|
||||
return 3.0
|
||||
|
||||
|
||||
def get_terrain_coefficient(terrain: str) -> float:
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from types import SimpleNamespace
|
||||
import importlib
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
if str(REPO_ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(REPO_ROOT))
|
||||
|
||||
|
||||
def make_user(role: str):
|
||||
return SimpleNamespace(
|
||||
id='test-user',
|
||||
username='tester',
|
||||
email='tester@example.com',
|
||||
full_name='Test User',
|
||||
role=role,
|
||||
is_active=True,
|
||||
last_login=None,
|
||||
)
|
||||
|
||||
|
||||
def test_admin_dashboard_requires_admin_role():
|
||||
from backend.main import app
|
||||
from backend.routers import auth
|
||||
|
||||
app.dependency_overrides[auth.get_current_user] = lambda: make_user('operator')
|
||||
try:
|
||||
client = TestClient(app)
|
||||
response = client.get('/api/v1/admin/dashboard')
|
||||
assert response.status_code == 403
|
||||
finally:
|
||||
app.dependency_overrides.clear()
|
||||
|
||||
|
||||
def test_admin_dashboard_allows_admin_role():
|
||||
from backend.main import app
|
||||
from backend.routers import auth
|
||||
|
||||
app.dependency_overrides[auth.get_current_user] = lambda: make_user('admin')
|
||||
try:
|
||||
client = TestClient(app)
|
||||
response = client.get('/api/v1/admin/dashboard')
|
||||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
assert 'total_cases' in payload
|
||||
finally:
|
||||
app.dependency_overrides.clear()
|
||||
|
||||
|
||||
def test_cases_endpoint_allows_field_role():
|
||||
from backend.main import app
|
||||
from backend.routers import auth
|
||||
|
||||
app.dependency_overrides[auth.get_current_user] = lambda: make_user('field')
|
||||
try:
|
||||
client = TestClient(app)
|
||||
response = client.get('/api/v1/cases')
|
||||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
assert 'items' in payload
|
||||
finally:
|
||||
app.dependency_overrides.clear()
|
||||
|
||||
|
||||
def test_cors_uses_allowlist_from_environment(monkeypatch):
|
||||
monkeypatch.setenv('CORS_ORIGINS', 'https://ui.example.com,https://admin.example.com')
|
||||
monkeypatch.setenv('CORS_ALLOW_CREDENTIALS', 'true')
|
||||
|
||||
import backend.main as main
|
||||
importlib.reload(main)
|
||||
client = TestClient(main.app)
|
||||
|
||||
response = client.options(
|
||||
'/api/v1/cases',
|
||||
headers={
|
||||
'Origin': 'https://ui.example.com',
|
||||
'Access-Control-Request-Method': 'GET',
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code in (200, 204)
|
||||
assert response.headers['access-control-allow-origin'] == 'https://ui.example.com'
|
||||
assert response.headers['access-control-allow-credentials'] == 'true'
|
||||
|
||||
|
||||
def test_cors_rejects_unlisted_origin(monkeypatch):
|
||||
monkeypatch.setenv('CORS_ORIGINS', 'https://ui.example.com')
|
||||
monkeypatch.setenv('CORS_ALLOW_CREDENTIALS', 'true')
|
||||
|
||||
import backend.main as main
|
||||
importlib.reload(main)
|
||||
client = TestClient(main.app)
|
||||
|
||||
response = client.options(
|
||||
'/api/v1/cases',
|
||||
headers={
|
||||
'Origin': 'https://evil.example.com',
|
||||
'Access-Control-Request-Method': 'GET',
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code in (200, 400)
|
||||
assert response.headers.get('access-control-allow-origin') is None
|
||||
@@ -91,21 +91,21 @@ def get_base_speed(age: int) -> float:
|
||||
# Скорость смещения потерявшегося ребёнка (не скорость ходьбы)
|
||||
# ПСО ЭКСТРЕМУМ: 94% найдены в пределах 3 км
|
||||
if age <= 2:
|
||||
return 0.3
|
||||
return 1.0
|
||||
elif age <= 5:
|
||||
return 0.7
|
||||
elif age <= 8:
|
||||
return 1.2
|
||||
elif age <= 12:
|
||||
return 1.5
|
||||
elif age <= 15:
|
||||
return 2.0
|
||||
elif age <= 8:
|
||||
return 3.0
|
||||
elif age <= 12:
|
||||
return 4.0
|
||||
elif age <= 15:
|
||||
return 5.0
|
||||
elif age <= 17:
|
||||
return 2.5
|
||||
return 5.5
|
||||
elif age <= 64:
|
||||
return 2.5
|
||||
return 5.0
|
||||
else: # 65+
|
||||
return 1.5
|
||||
return 3.0
|
||||
|
||||
|
||||
def get_terrain_coefficient(terrain: str) -> float:
|
||||
|
||||
Reference in New Issue
Block a user