Skip to content

Commit d6afe5e

Browse files
add testing to splitter endpoints
1 parent 44f3f81 commit d6afe5e

File tree

7 files changed

+158
-3
lines changed

7 files changed

+158
-3
lines changed

app/fastapi_utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ def get_parameters_info(params):
7777
if param.annotation == bytes:
7878
param_info = ParameterInfo(name=param.name, type="bytes")
7979
parameters_info.append(param_info)
80-
elif hasattr(param.annotation, "schema"):
81-
schema = param.annotation.schema()
80+
elif hasattr(param.annotation, "model_json_schema"):
81+
schema = param.annotation.model_json_schema()
8282
param_info = extract_fields_from_schema(schema)
8383
parameters_info.extend(param_info)
8484
else:
@@ -101,7 +101,7 @@ def get_return_type_info(return_type: Type[BaseModel]):
101101
A list of ParameterInfo objects representing the return type fields.
102102
103103
"""
104-
if hasattr(return_type, "schema"):
104+
if hasattr(return_type, "model_json_schema"):
105105
schema = return_type.model_json_schema()
106106
return extract_fields_from_schema(schema)
107107
return [ParameterInfo(name="return", type=str(return_type.__name__))]

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ fastapi==0.111.1
22
langchain==0.2.11
33
pydantic==2.8.2
44
pymupdf==1.24.9
5+
pytest==8.3.2
56
python_pptx==0.6.23
67
PyYAML==6.0.1

tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Tests module."""

tests/conftest.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import pytest
2+
from unittest.mock import patch
3+
4+
# Mock API key for testing
5+
MOCK_API_KEY = "test_api_key"
6+
7+
@pytest.fixture(autouse=True)
8+
def mock_api_key():
9+
"""Mock the API key for testing."""
10+
with patch('app.config.CONFIG.flowkit_python_api_key', MOCK_API_KEY):
11+
yield

tests/test_endpoints_splitter.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import base64
2+
from fastapi import HTTPException
3+
import pytest
4+
from fastapi.testclient import TestClient
5+
from app.app import app
6+
from app.endpoints.splitter import validate_request
7+
from app.models.splitter import SplitterRequest
8+
from tests.conftest import MOCK_API_KEY
9+
10+
# Create a test client
11+
client = TestClient(app)
12+
13+
def encode_file_to_base64(file_path):
14+
"""Encode a file to base64 string."""
15+
with open(file_path, "rb") as file:
16+
return base64.b64encode(file.read()).decode('utf-8')
17+
18+
@pytest.mark.asyncio
19+
async def test_split_ppt():
20+
"""Test splitting text in a PowerPoint document into chunks."""
21+
ppt_content_base64 = encode_file_to_base64("./tests/test_files/test_presentation.pptx")
22+
request_payload = {
23+
"document_content": ppt_content_base64,
24+
"chunk_size": 100,
25+
"chunk_overlap": 10
26+
}
27+
response = client.post(
28+
"/splitter/ppt",
29+
json=request_payload,
30+
headers={"api-key": MOCK_API_KEY}
31+
)
32+
if response.status_code != 200:
33+
print(f"Response status code: {response.status_code}")
34+
print(f"Response content: {response.json()}")
35+
assert response.status_code == 200
36+
assert "chunks" in response.json()
37+
38+
@pytest.mark.asyncio
39+
async def test_split_py():
40+
"""Test splitting Python code into chunks."""
41+
python_code = """
42+
def hello_world():
43+
print("Hello, world!")
44+
"""
45+
python_code_base64 = base64.b64encode(python_code.encode()).decode('utf-8')
46+
request_payload = {
47+
"document_content": python_code_base64,
48+
"chunk_size": 50,
49+
"chunk_overlap": 5
50+
}
51+
response = client.post(
52+
"/splitter/py",
53+
json=request_payload,
54+
headers={"api-key": MOCK_API_KEY}
55+
)
56+
assert response.status_code == 200
57+
assert "chunks" in response.json()
58+
59+
@pytest.mark.asyncio
60+
async def test_split_pdf():
61+
"""Test splitting text in a PDF document into chunks."""
62+
pdf_content_base64 = encode_file_to_base64("./tests/test_files/test_document.pdf")
63+
request_payload = {
64+
"document_content": pdf_content_base64,
65+
"chunk_size": 200,
66+
"chunk_overlap": 20
67+
}
68+
response = client.post(
69+
"/splitter/pdf",
70+
json=request_payload,
71+
headers={"api-key": MOCK_API_KEY}
72+
)
73+
assert response.status_code == 200
74+
assert "chunks" in response.json()
75+
76+
# Define test cases for validate_request()
77+
validate_request_test_cases = [
78+
# Test case 1: valid request
79+
(
80+
SplitterRequest(
81+
document_content="dGVzdA==", # base64 for "test"
82+
chunk_size=100,
83+
chunk_overlap=10
84+
),
85+
MOCK_API_KEY,
86+
None,
87+
),
88+
# Test case: invalid API key
89+
(
90+
SplitterRequest(
91+
document_content="dGVzdA==",
92+
chunk_size=100,
93+
chunk_overlap=10
94+
),
95+
"invalid_api_key",
96+
HTTPException(status_code=401, detail="Invalid API key"),
97+
),
98+
# Test case 2: missing document content
99+
(
100+
SplitterRequest(
101+
document_content="",
102+
chunk_size=100,
103+
chunk_overlap=10
104+
),
105+
MOCK_API_KEY,
106+
HTTPException(status_code=400, detail="No document content provided"),
107+
),
108+
# Test case 4: invalid chunk size
109+
(
110+
SplitterRequest(
111+
document_content="dGVzdA==",
112+
chunk_size=0,
113+
chunk_overlap=10
114+
),
115+
MOCK_API_KEY,
116+
HTTPException(status_code=400, detail="No chunk size provided"),
117+
),
118+
# Test case 5: invalid chunk overlap
119+
(
120+
SplitterRequest(
121+
document_content="dGVzdA==",
122+
chunk_size=100,
123+
chunk_overlap=-1
124+
),
125+
MOCK_API_KEY,
126+
HTTPException(status_code=400, detail="Chunk overlap must be greater than or equal to 0"),
127+
),
128+
]
129+
130+
@pytest.mark.parametrize("api_request, api_key, expected_exception", validate_request_test_cases)
131+
def test_validate_request(api_request, api_key, expected_exception):
132+
"""Test the validate_request function with various scenarios."""
133+
if expected_exception:
134+
with pytest.raises(HTTPException) as exc_info:
135+
validate_request(api_request, api_key)
136+
assert exc_info.value.status_code == expected_exception.status_code
137+
assert exc_info.value.detail == expected_exception.detail
138+
else:
139+
try:
140+
validate_request(api_request, api_key)
141+
except HTTPException:
142+
pytest.fail("validate_request() raised HTTPException unexpectedly!")

tests/test_files/test_document.pdf

36.2 KB
Binary file not shown.
36.5 KB
Binary file not shown.

0 commit comments

Comments
 (0)