agent-flow / src /backend /tests /unit /test_data_components.py
Tai Truong
fix readme
d202ada
raw
history blame
6.71 kB
import tempfile
from pathlib import Path
from unittest.mock import ANY, Mock, patch
import httpx
import pytest
import respx
from httpx import Response
from langflow.components import data
@pytest.fixture
def api_request():
# This fixture provides an instance of APIRequest for each test case
return data.APIRequestComponent()
@respx.mock
async def test_successful_get_request(api_request):
# Mocking a successful GET request
url = "https://example.com/api/test"
method = "GET"
mock_response = {"success": True}
respx.get(url).mock(return_value=Response(200, json=mock_response))
# Making the request
result = await api_request.make_request(
client=httpx.AsyncClient(),
method=method,
url=url,
include_httpx_metadata=True,
)
# Assertions
assert result.data["status_code"] == 200
assert result.data["result"] == mock_response
def test_parse_curl(api_request):
# Arrange
field_value = (
"curl -X GET https://example.com/api/test -H 'Content-Type: application/json' -d '{\"key\": \"value\"}'"
)
build_config = {
"method": {"value": ""},
"urls": {"value": []},
"headers": {},
"body": {},
}
# Act
new_build_config = api_request.parse_curl(field_value, build_config.copy())
# Assert
assert new_build_config["method"]["value"] == "GET"
assert new_build_config["urls"]["value"] == ["https://example.com/api/test"]
assert new_build_config["headers"]["value"] == {"Content-Type": "application/json"}
assert new_build_config["body"]["value"] == {"key": "value"}
@respx.mock
async def test_failed_request(api_request):
# Mocking a failed GET request
url = "https://example.com/api/test"
method = "GET"
respx.get(url).mock(return_value=Response(404))
# Making the request
result = await api_request.make_request(
client=httpx.AsyncClient(), method=method, url=url, include_httpx_metadata=True
)
# Assertions
assert result.data["status_code"] == 404
@respx.mock
async def test_timeout(api_request):
# Mocking a timeout
url = "https://example.com/api/timeout"
method = "GET"
respx.get(url).mock(side_effect=httpx.TimeoutException(message="Timeout", request=None))
# Making the request
result = await api_request.make_request(
client=httpx.AsyncClient(), method=method, url=url, timeout=1, include_httpx_metadata=True
)
# Assertions
assert result.data["status_code"] == 408
assert result.data["error"] == "Request timed out"
@respx.mock
async def test_build_with_multiple_urls(api_request):
# This test depends on having a working internet connection and accessible URLs
# It's better to mock these requests using respx or a similar library
# Setup for multiple URLs
method = "GET"
urls = ["https://example.com/api/one", "https://example.com/api/two"]
# You would mock these requests similarly to the single request tests
for url in urls:
respx.get(url).mock(return_value=Response(200, json={"success": True}))
# Do I have to mock the async client?
#
# Execute the build method
api_request.set_attributes(
{
"method": method,
"urls": urls,
}
)
results = await api_request.make_requests()
# Assertions
assert len(results) == len(urls)
@patch("langflow.components.data.directory.parallel_load_data")
@patch("langflow.components.data.directory.retrieve_file_paths")
@patch("langflow.components.data.DirectoryComponent.resolve_path")
def test_directory_component_build_with_multithreading(
mock_resolve_path, mock_retrieve_file_paths, mock_parallel_load_data
):
# Arrange
directory_component = data.DirectoryComponent()
path = Path(__file__).resolve().parent
depth = 1
max_concurrency = 2
load_hidden = False
recursive = True
silent_errors = False
use_multithreading = True
mock_resolve_path.return_value = str(path)
mock_retrieve_file_paths.return_value = [str(p) for p in path.iterdir() if p.suffix == ".py"]
mock_parallel_load_data.return_value = [Mock()]
# Act
directory_component.set_attributes(
{
"path": str(path),
"depth": depth,
"max_concurrency": max_concurrency,
"load_hidden": load_hidden,
"recursive": recursive,
"silent_errors": silent_errors,
"use_multithreading": use_multithreading,
}
)
directory_component.load_directory()
# Assert
mock_resolve_path.assert_called_once_with(str(path))
mock_retrieve_file_paths.assert_called_once_with(
str(path), load_hidden=load_hidden, recursive=recursive, depth=depth, types=ANY
)
mock_parallel_load_data.assert_called_once_with(
mock_retrieve_file_paths.return_value, silent_errors=silent_errors, max_concurrency=max_concurrency
)
def test_directory_without_mocks():
directory_component = data.DirectoryComponent()
with tempfile.TemporaryDirectory() as temp_dir:
(Path(temp_dir) / "test.txt").write_text("test", encoding="utf-8")
# also add a json file
(Path(temp_dir) / "test.json").write_text('{"test": "test"}', encoding="utf-8")
directory_component.set_attributes({"path": str(temp_dir), "use_multithreading": False})
results = directory_component.load_directory()
assert len(results) == 2
values = ["test", '{"test":"test"}']
assert all(result.text in values for result in results), [
(len(result.text), len(val)) for result, val in zip(results, values, strict=True)
]
# in ../docs/docs/components there are many mdx files
# check if the directory component can load them
# just check if the number of results is the same as the number of files
directory_component = data.DirectoryComponent()
docs_path = Path(__file__).parent.parent.parent.parent.parent / "docs" / "docs" / "Components"
directory_component.set_attributes({"path": str(docs_path), "use_multithreading": False})
results = directory_component.load_directory()
docs_files = list(docs_path.glob("*.md")) + list(docs_path.glob("*.json"))
assert len(results) == len(docs_files)
def test_url_component():
url_component = data.URLComponent()
url_component.set_attributes({"urls": ["https://langflow.org"]})
# the url component can be used to load the contents of a website
data_ = url_component.fetch_content()
assert all(value.data for value in data_)
assert all(value.text for value in data_)
assert all(value.source for value in data_)