| 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(): |
| |
| return data.APIRequestComponent() |
|
|
|
|
| @respx.mock |
| async def test_successful_get_request(api_request): |
| |
| url = "https://example.com/api/test" |
| method = "GET" |
| mock_response = {"success": True} |
| respx.get(url).mock(return_value=Response(200, json=mock_response)) |
|
|
| |
| result = await api_request.make_request( |
| client=httpx.AsyncClient(), |
| method=method, |
| url=url, |
| include_httpx_metadata=True, |
| ) |
|
|
| |
| assert result.data["status_code"] == 200 |
| assert result.data["result"] == mock_response |
|
|
|
|
| def test_parse_curl(api_request): |
| |
| 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": {}, |
| } |
| |
| new_build_config = api_request.parse_curl(field_value, build_config.copy()) |
|
|
| |
| 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): |
| |
| url = "https://example.com/api/test" |
| method = "GET" |
| respx.get(url).mock(return_value=Response(404)) |
|
|
| |
| result = await api_request.make_request( |
| client=httpx.AsyncClient(), method=method, url=url, include_httpx_metadata=True |
| ) |
|
|
| |
| assert result.data["status_code"] == 404 |
|
|
|
|
| @respx.mock |
| async def test_timeout(api_request): |
| |
| url = "https://example.com/api/timeout" |
| method = "GET" |
| respx.get(url).mock(side_effect=httpx.TimeoutException(message="Timeout", request=None)) |
|
|
| |
| result = await api_request.make_request( |
| client=httpx.AsyncClient(), method=method, url=url, timeout=1, include_httpx_metadata=True |
| ) |
|
|
| |
| assert result.data["status_code"] == 408 |
| assert result.data["error"] == "Request timed out" |
|
|
|
|
| @respx.mock |
| async def test_build_with_multiple_urls(api_request): |
| |
| |
|
|
| |
| method = "GET" |
| urls = ["https://example.com/api/one", "https://example.com/api/two"] |
| |
| for url in urls: |
| respx.get(url).mock(return_value=Response(200, json={"success": True})) |
|
|
| |
| |
|
|
| |
| api_request.set_attributes( |
| { |
| "method": method, |
| "urls": urls, |
| } |
| ) |
| results = await api_request.make_requests() |
|
|
| |
| 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 |
| ): |
| |
| 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()] |
|
|
| |
| 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() |
|
|
| |
| 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") |
| |
| (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) |
| ] |
|
|
| |
| |
| |
| 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"]}) |
| |
| 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_) |
|
|