Skip to content

Commit ecaee49

Browse files
authored
Comprehensive Integration Test Suite (#140)
1 parent 361147a commit ecaee49

File tree

2 files changed

+165
-2
lines changed

2 files changed

+165
-2
lines changed

src/server/main.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
""" Main module for the FastAPI application. """
22

33
import os
4+
from pathlib import Path
45

56
from api_analytics.fastapi import Analytics
67
from dotenv import load_dotenv
@@ -24,8 +25,11 @@
2425
# Register the custom exception handler for rate limits
2526
app.add_exception_handler(RateLimitExceeded, rate_limit_exception_handler)
2627

27-
# Mount static files to serve CSS, JS, and other static assets
28-
app.mount("/static", StaticFiles(directory="static"), name="static")
28+
29+
# Mount static files dynamically to serve CSS, JS, and other static assets
30+
static_dir = Path(__file__).parent.parent / "static"
31+
app.mount("/static", StaticFiles(directory=static_dir), name="static")
32+
2933

3034
# Set up API analytics middleware if an API key is provided
3135
if app_analytics_key := os.getenv("API_ANALYTICS_KEY"):

tests/test_flow_integration.py

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
"""
2+
Integration tests for GitIngest.
3+
These tests cover core functionalities, edge cases, and concurrency handling.
4+
"""
5+
6+
import shutil
7+
from concurrent.futures import ThreadPoolExecutor
8+
from pathlib import Path
9+
from unittest.mock import patch
10+
11+
import pytest
12+
from fastapi.testclient import TestClient
13+
14+
from src.server.main import app
15+
16+
BASE_DIR = Path(__file__).resolve().parent.parent
17+
TEMPLATE_DIR = BASE_DIR / "src" / "templates"
18+
19+
20+
@pytest.fixture(scope="module")
21+
def test_client():
22+
"""Create a test client fixture."""
23+
with TestClient(app) as client_instance:
24+
client_instance.headers.update({"Host": "localhost"})
25+
yield client_instance
26+
27+
28+
@pytest.fixture(scope="module", autouse=True)
29+
def mock_static_files():
30+
"""Mock the static file mount to avoid directory errors."""
31+
with patch("src.server.main.StaticFiles") as mock_static:
32+
mock_static.return_value = None # Mocks the StaticFiles response
33+
yield mock_static
34+
35+
36+
@pytest.fixture(scope="module", autouse=True)
37+
def mock_templates():
38+
"""Mock Jinja2 template rendering to bypass actual file loading."""
39+
with patch("starlette.templating.Jinja2Templates.TemplateResponse") as mock_template:
40+
mock_template.return_value = "Mocked Template Response"
41+
yield mock_template
42+
43+
44+
def cleanup_temp_directories():
45+
temp_dir = Path("/tmp/gitingest")
46+
if temp_dir.exists():
47+
try:
48+
shutil.rmtree(temp_dir)
49+
except PermissionError as e:
50+
print(f"Error cleaning up {temp_dir}: {e}")
51+
52+
53+
@pytest.fixture(scope="module", autouse=True)
54+
def cleanup():
55+
"""Cleanup temporary directories after tests."""
56+
yield
57+
cleanup_temp_directories()
58+
59+
60+
@pytest.mark.asyncio
61+
async def test_remote_repository_analysis(request):
62+
"""Test the complete flow of analyzing a remote repository."""
63+
client = request.getfixturevalue("test_client")
64+
form_data = {
65+
"input_text": "https://github.com/octocat/Hello-World",
66+
"max_file_size": "243",
67+
"pattern_type": "exclude",
68+
"pattern": "",
69+
}
70+
71+
response = client.post("/", data=form_data)
72+
assert response.status_code == 200, f"Form submission failed: {response.text}"
73+
assert "Mocked Template Response" in response.text
74+
75+
76+
@pytest.mark.asyncio
77+
async def test_invalid_repository_url(request):
78+
"""Test handling of an invalid repository URL."""
79+
client = request.getfixturevalue("test_client")
80+
form_data = {
81+
"input_text": "https://github.com/nonexistent/repo",
82+
"max_file_size": "243",
83+
"pattern_type": "exclude",
84+
"pattern": "",
85+
}
86+
87+
response = client.post("/", data=form_data)
88+
assert response.status_code == 200, f"Request failed: {response.text}"
89+
assert "Mocked Template Response" in response.text
90+
91+
92+
@pytest.mark.asyncio
93+
async def test_large_repository(request):
94+
"""Simulate analysis of a large repository with nested folders."""
95+
client = request.getfixturevalue("test_client")
96+
form_data = {
97+
"input_text": "https://github.com/large/repo-with-many-files",
98+
"max_file_size": "243",
99+
"pattern_type": "exclude",
100+
"pattern": "",
101+
}
102+
103+
response = client.post("/", data=form_data)
104+
assert response.status_code == 200, f"Request failed: {response.text}"
105+
assert "Mocked Template Response" in response.text
106+
107+
108+
@pytest.mark.asyncio
109+
async def test_concurrent_requests(request):
110+
"""Test handling of multiple concurrent requests."""
111+
client = request.getfixturevalue("test_client")
112+
113+
def make_request():
114+
form_data = {
115+
"input_text": "https://github.com/octocat/Hello-World",
116+
"max_file_size": "243",
117+
"pattern_type": "exclude",
118+
"pattern": "",
119+
}
120+
response = client.post("/", data=form_data)
121+
assert response.status_code == 200, f"Request failed: {response.text}"
122+
assert "Mocked Template Response" in response.text
123+
124+
with ThreadPoolExecutor(max_workers=5) as executor:
125+
futures = [executor.submit(make_request) for _ in range(5)]
126+
for future in futures:
127+
future.result()
128+
129+
130+
@pytest.mark.asyncio
131+
async def test_large_file_handling(request):
132+
"""Test handling of repositories with large files."""
133+
client = request.getfixturevalue("test_client")
134+
form_data = {
135+
"input_text": "https://github.com/octocat/Hello-World",
136+
"max_file_size": "1",
137+
"pattern_type": "exclude",
138+
"pattern": "",
139+
}
140+
141+
response = client.post("/", data=form_data)
142+
assert response.status_code == 200, f"Request failed: {response.text}"
143+
assert "Mocked Template Response" in response.text
144+
145+
146+
@pytest.mark.asyncio
147+
async def test_repository_with_patterns(request):
148+
"""Test repository analysis with include/exclude patterns."""
149+
client = request.getfixturevalue("test_client")
150+
form_data = {
151+
"input_text": "https://github.com/octocat/Hello-World",
152+
"max_file_size": "243",
153+
"pattern_type": "include",
154+
"pattern": "*.md",
155+
}
156+
157+
response = client.post("/", data=form_data)
158+
assert response.status_code == 200, f"Request failed: {response.text}"
159+
assert "Mocked Template Response" in response.text

0 commit comments

Comments
 (0)