"""
Unit tests for cleverswarm_client module.
Copyright (c) 2016 - present Syncleus, Inc.
Copyright (c) 2016 - present CleverThis, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import tempfile
from pathlib import Path
from unittest.mock import Mock, patch
import pytest
import json
from httmock import HTTMock, urlmatch
from cleverswarm_python_client.libs.cleverswarm_client import CleverSwarmClient
from cleverswarm_python_client.libs.exceptions import (
InvalidFileException,
JobNotFoundException,
UnauthorizedException,
InvalidUsernameOrPasswordException,
RequestErrorException,
ConnectionErrorException,
ConnectionTimeoutException,
UnexpectedConditionException,
)
from cleverswarm_python_client.libs.job_enums import JobStatus
from cleverswarm_python_client.libs.file_type_enum import FileTypeAPI
from cleverswarm_python_client.libs.response_type_enum import ResponseTypeAPI
class TestCleverSwarmClient:
"""Test cases for CleverSwarmClient."""
def setup_method(self):
"""Set up test client."""
self.client = CleverSwarmClient("http://localhost:8000/api/v0/")
def test_init_with_base_url(self):
"""Test initialization with base URL."""
client = CleverSwarmClient("http://localhost:8000/api/v0/")
assert client._base_url == "http://localhost:8000/api/v0/"
assert client._username is None
assert client._token is None
def test_init_with_username_and_token(self):
"""Test initialization with username and token."""
client = CleverSwarmClient(
"http://localhost:8000/api/v0/",
username="testuser",
token="testtoken"
)
assert client._base_url == "http://localhost:8000/api/v0/"
assert client._username == "testuser"
assert client._token == "testtoken"
def test_init_with_empty_base_url(self):
"""Test initialization with empty base URL."""
client = CleverSwarmClient("")
assert client._base_url == ""
def test_init_with_none_base_url(self):
"""Test initialization with None base URL."""
client = CleverSwarmClient(None)
assert client._base_url is None
def test_client_initialization_attributes(self):
"""Test client initialization attributes."""
client = CleverSwarmClient("http://localhost:8000/api/v0/")
# Test all default attributes
assert client._base_url == "http://localhost:8000/api/v0/"
assert client._username is None
assert client._token is None
assert client._max_retries == 2
assert client._timeout == 10
assert client._triplets_template == "{}_output.jsonl"
def test_client_initialization_with_credentials(self):
"""Test client initialization with various credential combinations."""
# Test with all parameters
client = CleverSwarmClient(
"http://localhost:8000/api/v0/",
username="testuser",
token="testtoken"
)
assert client._username == "testuser"
assert client._token == "testtoken"
def test_client_with_custom_attributes(self):
"""Test client with custom attributes."""
client = CleverSwarmClient("http://localhost:8000/api/v0/")
# Test that we can modify attributes
client._max_retries = 5
client._timeout = 30
client._triplets_template = "custom_{}_output.jsonl"
assert client._max_retries == 5
assert client._timeout == 30
assert client._triplets_template == "custom_{}_output.jsonl"
def test_file_validation_with_missing_files(self):
"""Test file validation with missing files."""
# Test with non-existent files - this should raise InvalidFileException before calling update_token
# We need to mock the update_token method to avoid the input() call
with patch.object(self.client, 'update_token'):
with pytest.raises(InvalidFileException):
self.client.create_benchmark_job(
Path("nonexistent1.txt"),
Path("nonexistent2.json"),
Path("nonexistent3.jsonl"),
True
)
def test_file_validation_with_existing_files(self):
"""Test file validation with existing files."""
with tempfile.TemporaryDirectory() as temp_dir:
# Create valid test files
text_file = Path(temp_dir) / "test.txt"
json_file = Path(temp_dir) / "test.json"
jsonl_file = Path(temp_dir) / "test.jsonl"
text_file.write_text("Test content")
json_file.write_text('{"test": "data"}')
jsonl_file.write_text('{"test": "data"}')
# Test that files exist and are valid files
assert text_file.exists()
assert text_file.is_file()
assert json_file.exists()
assert json_file.is_file()
assert jsonl_file.exists()
assert jsonl_file.is_file()
# Test that the client can validate these files by calling create_benchmark_job
# We need to mock the update_token and the HTTP request to avoid actual API calls
with patch.object(self.client, 'update_token'):
with patch.object(self.client, '_generic_http_request_executor') as mock_executor:
# Mock the executor to return the job_id directly
mock_executor.return_value = "test_job_123"
# This should not raise InvalidFileException
result = self.client.create_benchmark_job(
text_file, json_file, jsonl_file, True
)
assert result == "test_job_123"
def test_client_state_management(self):
"""Test client state management."""
client = CleverSwarmClient("http://localhost:8000/api/v0/")
# Test initial state
assert client._token is None
assert client._username is None
# Test setting token
client._token = "test_token"
assert client._token == "test_token"
# Test setting username
client._username = "test_user"
assert client._username == "test_user"
def test_client_configuration(self):
"""Test client configuration options."""
client = CleverSwarmClient("http://localhost:8000/api/v0/")
# Test default configuration
assert client._max_retries == 2
assert client._timeout == 10
# Test modifying configuration
client._max_retries = 5
client._timeout = 30
assert client._max_retries == 5
assert client._timeout == 30
def test_triplets_template(self):
"""Test triplets template functionality."""
client = CleverSwarmClient("http://localhost:8000/api/v0/")
# Test default template
assert client._triplets_template == "{}_output.jsonl"
# Test template formatting
formatted = client._triplets_template.format("test_job")
assert formatted == "test_job_output.jsonl"
# Test custom template
client._triplets_template = "custom_{}_result.jsonl"
formatted = client._triplets_template.format("test_job")
assert formatted == "custom_test_job_result.jsonl"
def test_poll_job_ready_or_failed_completed(self):
"""Test polling job that is already completed."""
with patch.object(self.client, 'get_job_status') as mock_status:
mock_status.return_value = JobStatus.Completed
result = self.client.poll_job_ready_or_failed("job123")
assert result == JobStatus.Completed
mock_status.assert_called_once_with("job123")
def test_poll_job_ready_or_failed_failed(self):
"""Test polling job that has failed."""
with patch.object(self.client, 'get_job_status') as mock_status:
mock_status.return_value = JobStatus.Failed
result = self.client.poll_job_ready_or_failed("job123")
assert result == JobStatus.Failed
mock_status.assert_called_once_with("job123")
def test_poll_job_ready_or_failed_processing(self):
"""Test polling job that is still processing."""
with patch.object(self.client, 'get_job_status') as mock_status:
# First call returns Processing, second call returns Completed
mock_status.side_effect = [JobStatus.Processing, JobStatus.Completed]
with patch('time.sleep'): # Mock sleep to speed up test
result = self.client.poll_job_ready_or_failed("job123")
assert result == JobStatus.Completed
assert mock_status.call_count == 2
def test_generic_http_request_executor_success(self):
"""Test generic HTTP request executor with successful response."""
def test_func():
mock_response = Mock()
mock_response.status_code = 200
return mock_response
result = self.client._generic_http_request_executor(test_func)
assert result.status_code == 200
def test_generic_http_request_executor_max_retries_exceeded(self):
"""Test generic HTTP request executor with max retries exceeded."""
def test_func():
raise Exception("Persistent failure")
with patch('time.sleep'): # Mock sleep to speed up test
with pytest.raises(Exception):
self.client._generic_http_request_executor(test_func)
def test_job_status_enum_values(self):
"""Test JobStatus enum values."""
assert JobStatus.ReadyForProcessing == "ReadyForProcessing"
assert JobStatus.Processing == "Processing"
assert JobStatus.Completed == "Completed"
assert JobStatus.Failed == "Failed"
def test_file_type_enum_values(self):
"""Test FileTypeAPI enum values."""
assert FileTypeAPI.AutoDetect == "AutoDetect"
assert FileTypeAPI.Markdown == "Markdown"
assert FileTypeAPI.PlainText == "PlainText"
assert FileTypeAPI.PDF == "PDF"
def test_response_type_enum_values(self):
"""Test ResponseTypeAPI enum values."""
assert ResponseTypeAPI.JsonText == "JsonText"
assert ResponseTypeAPI.JsonFile == "JsonFile"
def test_client_with_different_base_urls(self):
"""Test client with different base URL formats."""
# Test with trailing slash
client1 = CleverSwarmClient("http://localhost:8000/api/v0/")
assert client1._base_url == "http://localhost:8000/api/v0/"
# Test without trailing slash
client2 = CleverSwarmClient("http://localhost:8000/api/v0")
assert client2._base_url == "http://localhost:8000/api/v0"
# Test with different port
client3 = CleverSwarmClient("http://localhost:9000/api/v1/")
assert client3._base_url == "http://localhost:9000/api/v1/"
def test_client_initialization_edge_cases(self):
"""Test client initialization with edge cases."""
# Test with empty string
client1 = CleverSwarmClient("")
assert client1._base_url == ""
# Test with None
client2 = CleverSwarmClient(None)
assert client2._base_url is None
# Test with just username
client3 = CleverSwarmClient("http://localhost:8000/api/v0/", username="testuser")
assert client3._username == "testuser"
assert client3._token is None
# Test with just token
client4 = CleverSwarmClient("http://localhost:8000/api/v0/", token="testtoken")
assert client4._token == "testtoken"
assert client4._username is None
def test_client_attribute_modification(self):
"""Test that client attributes can be modified after initialization."""
client = CleverSwarmClient("http://localhost:8000/api/v0/")
# Modify all attributes
client._base_url = "http://newhost:9000/api/v1/"
client._username = "newuser"
client._token = "newtoken"
client._max_retries = 10
client._timeout = 60
client._triplets_template = "new_{}_template.jsonl"
# Verify changes
assert client._base_url == "http://newhost:9000/api/v1/"
assert client._username == "newuser"
assert client._token == "newtoken"
assert client._max_retries == 10
assert client._timeout == 60
assert client._triplets_template == "new_{}_template.jsonl"
def test_client_string_representation(self):
"""Test client string representation."""
client = CleverSwarmClient("http://localhost:8000/api/v0/")
# Test that the client object can be converted to string
client_str = str(client)
assert isinstance(client_str, str)
assert "CleverSwarmClient" in client_str
def test_client_equality(self):
"""Test client equality comparison."""
client1 = CleverSwarmClient("http://localhost:8000/api/v0/")
client2 = CleverSwarmClient("http://localhost:8000/api/v0/")
client3 = CleverSwarmClient("http://localhost:9000/api/v0/")
# Different instances should not be equal
assert client1 != client2
assert client1 != client3
# Same instance should be equal to itself
assert client1 == client1
def test_client_hash(self):
"""Test client hash functionality."""
client = CleverSwarmClient("http://localhost:8000/api/v0/")
# Test that client can be hashed
client_hash = hash(client)
assert isinstance(client_hash, int)
# Test that same client has same hash
assert hash(client) == hash(client)
def test_client_with_credentials_initialization(self):
"""Test client initialization with various credential combinations."""
# Test with both username and token
client1 = CleverSwarmClient(
"http://localhost:8000/api/v0/",
username="user1",
token="token1"
)
assert client1._username == "user1"
assert client1._token == "token1"
# Test with only username
client2 = CleverSwarmClient(
"http://localhost:8000/api/v0/",
username="user2"
)
assert client2._username == "user2"
assert client2._token is None
# Test with only token
client3 = CleverSwarmClient(
"http://localhost:8000/api/v0/",
token="token3"
)
assert client3._username is None
assert client3._token == "token3"
def test_client_template_functionality(self):
"""Test client template functionality in detail."""
client = CleverSwarmClient("http://localhost:8000/api/v0/")
# Test default template
assert client._triplets_template == "{}_output.jsonl"
# Test template with different job IDs
job_ids = ["job1", "job2", "test_job_123", "my-special-job"]
for job_id in job_ids:
expected = f"{job_id}_output.jsonl"
actual = client._triplets_template.format(job_id)
assert actual == expected
# Test custom template
client._triplets_template = "results_{}_final.jsonl"
for job_id in job_ids:
expected = f"results_{job_id}_final.jsonl"
actual = client._triplets_template.format(job_id)
assert actual == expected
def test_client_retry_configuration(self):
"""Test client retry configuration."""
client = CleverSwarmClient("http://localhost:8000/api/v0/")
# Test default retry configuration
assert client._max_retries == 2
# Test setting different retry values
for retries in [0, 1, 5, 10]:
client._max_retries = retries
assert client._max_retries == retries
def test_client_timeout_configuration(self):
"""Test client timeout configuration."""
client = CleverSwarmClient("http://localhost:8000/api/v0/")
# Test default timeout
assert client._timeout == 10
# Test setting different timeout values
for timeout in [1, 5, 30, 60, 120]:
client._timeout = timeout
assert client._timeout == timeout
class TestCleverSwarmClientHTTP:
"""Test cases for CleverSwarmClient HTTP operations using httmock."""
def setup_method(self):
"""Set up test client."""
self.client = CleverSwarmClient("http://localhost:8000/api/v0/", token="test_token")
# Authentication Tests
@urlmatch(netloc='localhost:8000', path='/api/v0/login', method='POST')
def login_success_mock(self, url, request):
"""Mock successful login response."""
return {
'status_code': 200,
'content': json.dumps({
'access_token': 'new_token',
'token_type': 'bearer'
}).encode('utf-8'),
'headers': {'content-type': 'application/json'}
}
@urlmatch(netloc='localhost:8000', path='/api/v0/login', method='POST')
def login_unauthorized_mock(self, url, request):
"""Mock unauthorized login response."""
return {
'status_code': 401,
'content': b'User provided credentials are not correct.',
'headers': {'content-type': 'text/plain'}
}
@urlmatch(netloc='localhost:8000', path='/api/v0/login', method='POST')
def login_invalid_credentials_mock(self, url, request):
"""Mock invalid credentials login response."""
return {
'status_code': 400,
'content': b'Invalid credentials',
'headers': {'content-type': 'text/plain'}
}
@patch('cleverswarm_python_client.libs.cleverswarm_client.getpass')
def test_update_token_success(self, mock_getpass):
"""Test successful token update using httmock."""
mock_getpass.return_value = "testpassword"
with HTTMock(self.login_success_mock):
client = CleverSwarmClient("http://localhost:8000/api/v0/", username="testuser")
result = client.update_token()
assert result is client # Should return self
assert client._token == "new_token"
@patch('cleverswarm_python_client.libs.cleverswarm_client.getpass')
def test_update_token_unauthorized(self, mock_getpass):
"""Test token update with unauthorized response using httmock."""
mock_getpass.return_value = "testpassword"
with HTTMock(self.login_unauthorized_mock):
client = CleverSwarmClient("http://localhost:8000/api/v0/", username="testuser")
with pytest.raises(RequestErrorException, match="Failed process request, error from server"):
client.update_token()
@patch('cleverswarm_python_client.libs.cleverswarm_client.getpass')
def test_update_token_invalid_credentials(self, mock_getpass):
"""Test token update with invalid credentials using httmock."""
mock_getpass.return_value = "testpassword"
with HTTMock(self.login_invalid_credentials_mock):
client = CleverSwarmClient("http://localhost:8000/api/v0/", username="testuser")
with pytest.raises(InvalidUsernameOrPasswordException):
client.update_token()
# Job Management Tests
@urlmatch(netloc='localhost:8000', path='/api/v0/jobs', method='GET')
def jobs_list_success_mock(self, url, request):
"""Mock successful jobs list response."""
return {
'status_code': 200,
'content': json.dumps([
{"id": "job1", "type": "Benchmark", "status": "Completed"},
{"id": "job2", "type": "UnstructuredWithOntology", "status": "Processing"}
]).encode('utf-8'),
'headers': {'content-type': 'application/json'}
}
def test_get_jobs_list_success(self):
"""Test successful job list retrieval using httmock."""
with HTTMock(self.jobs_list_success_mock):
result = self.client.get_jobs_list(is_benchmark=True)
assert len(result) == 1 # Only Benchmark jobs are returned
assert result[0]["id"] == "job1"
assert result[0]["type"] == "Benchmark"
def test_get_jobs_list_filtering(self):
"""Test job list retrieval with filtering using httmock."""
with HTTMock(self.jobs_list_success_mock):
# Test benchmark jobs only
result = self.client.get_jobs_list(is_benchmark=True)
assert len(result) == 1
assert result[0]["type"] == "Benchmark"
# Test non-benchmark jobs only
result = self.client.get_jobs_list(is_benchmark=False)
assert len(result) == 1
assert result[0]["type"] == "UnstructuredWithOntology"
@urlmatch(netloc='localhost:8000', path=r'/api/v0/jobs/.*', method='GET')
def job_status_success_mock(self, url, request):
"""Mock successful job status response."""
return {
'status_code': 200,
'content': json.dumps("Completed").encode('utf-8'),
'headers': {'content-type': 'application/json'}
}
@urlmatch(netloc='localhost:8000', path=r'/api/v0/jobs/.*', method='GET')
def job_status_not_found_mock(self, url, request):
"""Mock job not found response."""
return {
'status_code': 404,
'content': b'Job not found',
'headers': {'content-type': 'text/plain'}
}
def test_get_job_status_success(self):
"""Test successful job status retrieval using httmock."""
with HTTMock(self.job_status_success_mock):
result = self.client.get_job_status("job123")
assert result == JobStatus.Completed
def test_get_job_status_not_found(self):
"""Test job status retrieval for non-existent job using httmock."""
with HTTMock(self.job_status_not_found_mock):
with pytest.raises(JobNotFoundException):
self.client.get_job_status("nonexistent")
@urlmatch(netloc='localhost:8000', path=r'/api/v0/jobs/.*', method='GET')
def job_details_success_mock(self, url, request):
"""Mock successful job details response."""
return {
'status_code': 200,
'content': json.dumps({
"id": "job123",
"status": "Completed",
"type": "Benchmark",
"created": "2023-01-01T00:00:00Z"
}).encode('utf-8'),
'headers': {'content-type': 'application/json'}
}
def test_get_job_details_success(self):
"""Test successful job details retrieval using httmock."""
with HTTMock(self.job_details_success_mock):
result = self.client.get_job_details("job123")
assert result["id"] == "job123"
assert result["status"] == "Completed"
@urlmatch(netloc='localhost:8000', path=r'/api/v0/jobs/.*', method='DELETE')
def delete_job_success_mock(self, url, request):
"""Mock successful job deletion response."""
return {
'status_code': 200,
'content': b'Job deleted',
'headers': {'content-type': 'text/plain'}
}
@urlmatch(netloc='localhost:8000', path=r'/api/v0/jobs/.*', method='DELETE')
def delete_job_not_found_mock(self, url, request):
"""Mock job not found for deletion response."""
return {
'status_code': 404,
'content': b'Job not found',
'headers': {'content-type': 'text/plain'}
}
def test_delete_job_success(self):
"""Test successful job deletion using httmock."""
with HTTMock(self.delete_job_success_mock):
result = self.client.delete_job("job123")
assert result is True
def test_delete_job_not_found(self):
"""Test job deletion for non-existent job using httmock."""
with HTTMock(self.delete_job_not_found_mock):
with pytest.raises(JobNotFoundException):
self.client.delete_job("nonexistent")
@urlmatch(netloc='localhost:8000', path=r'/api/v0/jobs/.*', method='PUT')
def retry_job_success_mock(self, url, request):
"""Mock successful job retry response."""
return {
'status_code': 200,
'content': json.dumps("Processing").encode('utf-8'),
'headers': {'content-type': 'application/json'}
}
def test_retry_job_success(self):
"""Test successful job retry using httmock."""
with HTTMock(self.retry_job_success_mock):
result = self.client.retry_job("job123")
assert result == JobStatus.Processing
# File Upload Tests
@urlmatch(netloc='localhost:8000', path='/api/v0/benchmark', method='POST')
def benchmark_job_success_mock(self, url, request):
"""Mock successful benchmark job creation response."""
return {
'status_code': 200,
'content': json.dumps({"job_id": "benchmark_job_123"}).encode('utf-8'),
'headers': {'content-type': 'application/json'}
}
def test_create_benchmark_job_success(self):
"""Test successful benchmark job creation using httmock."""
with tempfile.TemporaryDirectory() as temp_dir:
# Create valid test files
text_file = Path(temp_dir) / "test.txt"
json_file = Path(temp_dir) / "test.json"
jsonl_file = Path(temp_dir) / "test.jsonl"
text_file.write_text("Test content")
json_file.write_text('{"test": "data"}')
jsonl_file.write_text('{"test": "data"}')
with HTTMock(self.benchmark_job_success_mock):
with patch.object(self.client, 'update_token'): # Mock update_token to avoid input()
result = self.client.create_benchmark_job(
text_file, json_file, jsonl_file, True
)
assert result == "benchmark_job_123"
@urlmatch(netloc='localhost:8000', path='/api/v0/unstructured/with_ontology', method='POST')
def unstructured_job_success_mock(self, url, request):
"""Mock successful unstructured to KG job creation response."""
return {
'status_code': 201,
'content': json.dumps({"job_id": "unstructured_job_123"}).encode('utf-8'),
'headers': {'content-type': 'application/json'}
}
def test_create_unstructured_to_kg_job_success(self):
"""Test successful unstructured to KG job creation using httmock."""
with tempfile.TemporaryDirectory() as temp_dir:
# Create valid test files
text_file = Path(temp_dir) / "test.txt"
json_file = Path(temp_dir) / "test.json"
owl_file = Path(temp_dir) / "test.owl"
text_file.write_text("Test content")
json_file.write_text('{"test": "data"}')
owl_file.write_text('test')
with HTTMock(self.unstructured_job_success_mock):
with patch.object(self.client, 'update_token'): # Mock update_token to avoid input()
result = self.client.create_unstructured_to_kg_job(
text_file, json_file, owl_file
)
assert result == "unstructured_job_123"
@urlmatch(netloc='localhost:8000', path='/api/v0/unstructured/with_wildcards', method='POST')
def unstructured_wildcards_job_success_mock(self, url, request):
"""Mock successful unstructured to KG wildcards job creation response."""
return {
'status_code': 201,
'content': json.dumps({"job_id": "wildcards_job_123"}).encode('utf-8'),
'headers': {'content-type': 'application/json'}
}
def test_create_unstructured_to_kg_wildcards_job_success(self):
"""Test successful unstructured to KG wildcards job creation using httmock."""
with tempfile.TemporaryDirectory() as temp_dir:
# Create valid test files
text_file = Path(temp_dir) / "test.txt"
json_file = Path(temp_dir) / "test.json"
owl_file = Path(temp_dir) / "test.owl"
wildcards_file = Path(temp_dir) / "test.wildcards"
text_file.write_text("Test content")
json_file.write_text('{"test": "data"}')
owl_file.write_text('test')
wildcards_file.write_text("wildcard1\nwildcard2")
with HTTMock(self.unstructured_wildcards_job_success_mock):
with patch.object(self.client, 'update_token'): # Mock update_token to avoid input()
result = self.client.create_unstructured_to_kg_wildcards_job(
text_file, json_file, owl_file, wildcards_file
)
assert result == "wildcards_job_123"
# File Download Tests
@urlmatch(netloc='localhost:8000', path=r'/api/v0/benchmark/.*', method='GET')
def benchmark_file_download_mock(self, url, request):
"""Mock successful benchmark file download response."""
return {
'status_code': 200,
'content': b'{"test": "benchmark_data"}',
'headers': {'content-type': 'application/json'}
}
def test_retrieve_benchmark_files_success(self):
"""Test successful benchmark files retrieval using httmock."""
with tempfile.TemporaryDirectory() as temp_dir:
output_file = Path(temp_dir) / "output.jsonl"
with HTTMock(self.benchmark_file_download_mock):
with patch.object(self.client, 'update_token'): # Mock update_token to avoid input()
result = self.client.retrieve_benchmark_files("job123", [output_file])
assert result == [output_file]
@urlmatch(netloc='localhost:8000', path=r'/api/v0/unstructured/.*', method='GET')
def unstructured_file_download_mock(self, url, request):
"""Mock successful unstructured file download response."""
return {
'status_code': 200,
'content': b'{"test": "unstructured_data"}',
'headers': {'content-type': 'application/json'}
}
def test_retrieve_unstructured_to_kg_files_success(self):
"""Test successful unstructured to KG files retrieval using httmock."""
with tempfile.TemporaryDirectory() as temp_dir:
output_file = Path(temp_dir) / "output.jsonl"
with HTTMock(self.unstructured_file_download_mock):
with patch.object(self.client, 'update_token'): # Mock update_token to avoid input()
result = self.client.retrieve_unstructured_to_kg_files("job123", output_file)
assert result == output_file
# Error Handling Tests
@urlmatch(netloc='localhost:8000', path='/api/v0/test', method='GET')
def generic_http_success_mock(self, url, request):
"""Mock successful generic HTTP response."""
return {
'status_code': 200,
'content': json.dumps({"result": "success"}).encode('utf-8'),
'headers': {'content-type': 'application/json'}
}
@urlmatch(netloc='localhost:8000', path='/api/v0/test', method='GET')
def generic_http_error_mock(self, url, request):
"""Mock error generic HTTP response."""
return {
'status_code': 500,
'content': b'Internal Server Error',
'headers': {'content-type': 'text/plain'}
}
def test_generic_http_request_executor_success(self):
"""Test generic HTTP request executor with successful response using httmock."""
with HTTMock(self.generic_http_success_mock):
def test_func():
import requests
return requests.get("http://localhost:8000/api/v0/test")
result = self.client._generic_http_request_executor(test_func)
assert result.status_code == 200
# Connection Error Tests
def test_generic_http_request_executor_connection_error(self):
"""Test generic HTTP request executor with connection error."""
def test_func():
import requests
raise requests.exceptions.ConnectionError("Connection failed")
with pytest.raises(ConnectionErrorException):
self.client._generic_http_request_executor(test_func)
def test_generic_http_request_executor_read_timeout_error(self):
"""Test generic HTTP request executor with read timeout error."""
def test_func():
import requests
raise requests.exceptions.ReadTimeout("Read timeout")
with pytest.raises(ConnectionTimeoutException):
self.client._generic_http_request_executor(test_func)
def test_generic_http_request_executor_http_error(self):
"""Test generic HTTP request executor with HTTP error."""
def test_func():
import requests
raise requests.exceptions.HTTPError("HTTP error")
with pytest.raises(RequestErrorException):
self.client._generic_http_request_executor(test_func)
def test_generic_http_request_executor_request_error(self):
"""Test generic HTTP request executor with request error."""
def test_func():
import requests
raise requests.exceptions.RequestException("Request error")
with pytest.raises(UnexpectedConditionException, match="Client error while processing authorization"):
self.client._generic_http_request_executor(test_func)
def test_generic_http_request_executor_unexpected_error(self):
"""Test generic HTTP request executor with unexpected error."""
def test_func():
raise ValueError("Unexpected error")
with pytest.raises(UnexpectedConditionException):
self.client._generic_http_request_executor(test_func)