Enhance API and configuration for Telegram miniapp
- Added support for CORS origins and a new environment variable for miniapp access control. - Implemented date validation for API requests to ensure correct date formats. - Updated FastAPI app to allow access without Telegram initData for local development. - Enhanced error handling and logging for better debugging. - Added tests for API functionality and Telegram initData validation. - Updated README with new environment variable details and testing instructions. - Modified Docker and Git ignore files to include additional directories and files.
This commit is contained in:
103
api/test_app.py
Normal file
103
api/test_app.py
Normal file
@@ -0,0 +1,103 @@
|
||||
"""Tests for FastAPI app /api/duties."""
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from api.app import app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client():
|
||||
return TestClient(app)
|
||||
|
||||
|
||||
def test_duties_invalid_date_format(client):
|
||||
r = client.get("/api/duties", params={"from": "2025-01-01", "to": "invalid"})
|
||||
assert r.status_code == 400
|
||||
assert "YYYY-MM-DD" in r.json()["detail"]
|
||||
|
||||
|
||||
def test_duties_from_after_to(client):
|
||||
r = client.get("/api/duties", params={"from": "2025-02-01", "to": "2025-01-01"})
|
||||
assert r.status_code == 400
|
||||
assert "from" in r.json()["detail"].lower() or "позже" in r.json()["detail"]
|
||||
|
||||
|
||||
@patch("api.app._is_private_client")
|
||||
@patch("api.app.config.MINI_APP_SKIP_AUTH", False)
|
||||
def test_duties_403_without_init_data_from_public_client(mock_private, client):
|
||||
"""Without initData and without private IP / skip-auth, should get 403."""
|
||||
mock_private.return_value = False # simulate public client
|
||||
r = client.get(
|
||||
"/api/duties",
|
||||
params={"from": "2025-01-01", "to": "2025-01-31"},
|
||||
)
|
||||
assert r.status_code == 403
|
||||
|
||||
|
||||
@patch("api.app.config.MINI_APP_SKIP_AUTH", True)
|
||||
@patch("api.app._fetch_duties_response")
|
||||
def test_duties_200_when_skip_auth(mock_fetch, client):
|
||||
mock_fetch.return_value = []
|
||||
r = client.get(
|
||||
"/api/duties",
|
||||
params={"from": "2025-01-01", "to": "2025-01-31"},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
assert r.json() == []
|
||||
mock_fetch.assert_called_once_with("2025-01-01", "2025-01-31")
|
||||
|
||||
|
||||
@patch("api.app.validate_init_data")
|
||||
def test_duties_403_when_init_data_invalid(mock_validate, client):
|
||||
mock_validate.return_value = None
|
||||
r = client.get(
|
||||
"/api/duties",
|
||||
params={"from": "2025-01-01", "to": "2025-01-31"},
|
||||
headers={"X-Telegram-Init-Data": "some=data&hash=abc"},
|
||||
)
|
||||
assert r.status_code == 403
|
||||
assert "авторизации" in r.json()["detail"] or "Неверные" in r.json()["detail"]
|
||||
|
||||
|
||||
@patch("api.app.validate_init_data")
|
||||
@patch("api.app.config.can_access_miniapp")
|
||||
def test_duties_403_when_username_not_allowed(mock_can_access, mock_validate, client):
|
||||
mock_validate.return_value = "someuser"
|
||||
mock_can_access.return_value = False
|
||||
with patch("api.app._fetch_duties_response") as mock_fetch:
|
||||
r = client.get(
|
||||
"/api/duties",
|
||||
params={"from": "2025-01-01", "to": "2025-01-31"},
|
||||
headers={"X-Telegram-Init-Data": "user=xxx&hash=yyy"},
|
||||
)
|
||||
assert r.status_code == 403
|
||||
assert "Доступ запрещён" in r.json()["detail"]
|
||||
mock_fetch.assert_not_called()
|
||||
|
||||
|
||||
@patch("api.app.validate_init_data")
|
||||
@patch("api.app.config.can_access_miniapp")
|
||||
def test_duties_200_with_allowed_user(mock_can_access, mock_validate, client):
|
||||
mock_validate.return_value = "alloweduser"
|
||||
mock_can_access.return_value = True
|
||||
with patch("api.app._fetch_duties_response") as mock_fetch:
|
||||
mock_fetch.return_value = [
|
||||
{
|
||||
"id": 1,
|
||||
"user_id": 10,
|
||||
"start_at": "2025-01-15T09:00:00",
|
||||
"end_at": "2025-01-15T18:00:00",
|
||||
"full_name": "Иван Иванов",
|
||||
}
|
||||
]
|
||||
r = client.get(
|
||||
"/api/duties",
|
||||
params={"from": "2025-01-01", "to": "2025-01-31"},
|
||||
headers={"X-Telegram-Init-Data": "user=xxx&hash=yyy"},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
assert len(r.json()) == 1
|
||||
assert r.json()[0]["full_name"] == "Иван Иванов"
|
||||
mock_fetch.assert_called_once_with("2025-01-01", "2025-01-31")
|
||||
Reference in New Issue
Block a user