docs: update README and add test infrastructure
- Enhance .gitignore with comprehensive Python patterns - Improve README with better setup and testing instructions - Add test infrastructure: * Test requirements file * Environment setup script * Test runner script * Comprehensive test suite * Coverage configuration
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
from fastapi.testclient import TestClient
|
||||
from main import app
|
||||
|
||||
# Create a test client
|
||||
client = TestClient(app)
|
||||
|
||||
def test_health_check():
|
||||
"""Test the health check endpoint."""
|
||||
response = client.get("/health")
|
||||
assert response.status_code == 200
|
||||
assert "status" in response.json()
|
||||
assert response.json()["status"] == "healthy"
|
||||
|
||||
def test_favicon():
|
||||
"""Test the favicon endpoint."""
|
||||
response = client.get("/favicon.ico")
|
||||
# The favicon endpoint serves the actual favicon file, so we expect a 200
|
||||
# If the file doesn't exist, it would return a 404, but in our case it should exist
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_get_client_config():
|
||||
"""Test the client configuration endpoint."""
|
||||
response = client.get("/config")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "client_id" in data
|
||||
assert "issuer" in data
|
||||
# Just check that we get a client_id, not necessarily the test value
|
||||
assert isinstance(data["client_id"], str)
|
||||
assert len(data["client_id"]) > 0
|
||||
|
||||
@patch('main.verify_token')
|
||||
def test_validate_token_success(mock_verify_token):
|
||||
"""Test successful token validation."""
|
||||
# Mock the verify_token function to return a valid payload
|
||||
mock_verify_token.return_value = {
|
||||
"email": "rene.luria@infomaniak.com",
|
||||
"iss": "https://login.infomaniak.com",
|
||||
"aud": "test-client-id"
|
||||
}
|
||||
|
||||
response = client.post("/validate-token", json={
|
||||
"id_token": "valid.token.here"
|
||||
})
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["valid"]
|
||||
assert data["user"] is not None
|
||||
assert data["user"]["email"] == "rene.luria@infomaniak.com"
|
||||
assert data["secret_phrase"] == "Welcome to the secret club!"
|
||||
|
||||
@patch('main.verify_token')
|
||||
def test_validate_token_unauthorized_user(mock_verify_token):
|
||||
"""Test token validation for unauthorized user."""
|
||||
# Mock the verify_token function to return a payload with unauthorized user
|
||||
mock_verify_token.return_value = {
|
||||
"email": "unauthorized@example.com",
|
||||
"iss": "https://login.infomaniak.com",
|
||||
"aud": "test-client-id"
|
||||
}
|
||||
|
||||
response = client.post("/validate-token", json={
|
||||
"id_token": "valid.token.here"
|
||||
})
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["valid"]
|
||||
assert data["user"] is not None
|
||||
assert data["user"]["email"] == "unauthorized@example.com"
|
||||
assert data["secret_phrase"] is None
|
||||
|
||||
@patch('main.verify_token')
|
||||
def test_validate_token_missing_email(mock_verify_token):
|
||||
"""Test token validation when email is missing from token."""
|
||||
# Mock the verify_token function to return a payload without email
|
||||
mock_verify_token.return_value = {
|
||||
"iss": "https://login.infomaniak.com",
|
||||
"aud": "test-client-id"
|
||||
}
|
||||
|
||||
response = client.post("/validate-token", json={
|
||||
"id_token": "token.without.email"
|
||||
})
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert not data["valid"]
|
||||
assert data["error"] == "Email not found in token"
|
||||
|
||||
@patch('main.verify_token')
|
||||
def test_validate_token_invalid(mock_verify_token):
|
||||
"""Test validation with an invalid token."""
|
||||
# Mock the verify_token function to raise an exception
|
||||
mock_verify_token.side_effect = ValueError("Invalid token")
|
||||
|
||||
response = client.post("/validate-token", json={
|
||||
"id_token": "invalid.token.here"
|
||||
})
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert not data["valid"]
|
||||
assert data["error"] == "Invalid token"
|
||||
|
||||
def test_validate_token_empty_request():
|
||||
"""Test validation with empty token."""
|
||||
response = client.post("/validate-token", json={
|
||||
"id_token": ""
|
||||
})
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert not data["valid"]
|
||||
|
||||
@patch('main.refresh_token')
|
||||
def test_refresh_token_success(mock_refresh_token):
|
||||
"""Test successful token refresh."""
|
||||
# Mock the refresh_token function
|
||||
mock_refresh_token.return_value = {
|
||||
"access_token": "new-access-token",
|
||||
"id_token": "new-id-token",
|
||||
"expires_in": 3600,
|
||||
"token_type": "Bearer"
|
||||
}
|
||||
|
||||
response = client.post("/refresh-token", json={
|
||||
"refresh_token": "valid-refresh-token"
|
||||
})
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["access_token"] == "new-access-token"
|
||||
assert data["id_token"] == "new-id-token"
|
||||
assert data["expires_in"] == 3600
|
||||
assert data["token_type"] == "Bearer"
|
||||
|
||||
@patch('main.refresh_token')
|
||||
def test_refresh_token_failure(mock_refresh_token):
|
||||
"""Test token refresh failure."""
|
||||
# Mock the refresh_token function to raise an exception
|
||||
mock_refresh_token.side_effect = ValueError("Invalid refresh token")
|
||||
|
||||
response = client.post("/refresh-token", json={
|
||||
"refresh_token": "invalid-refresh-token"
|
||||
})
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["error"] == "Invalid refresh token"
|
||||
Reference in New Issue
Block a user