Files
michaelschiemer/tests/Unit/Framework/HttpClient/Curl/HandleExceptionTest.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

130 lines
5.7 KiB
PHP

<?php
declare(strict_types=1);
use App\Framework\HttpClient\Curl\Handle;
use App\Framework\HttpClient\Curl\HandleOption;
use App\Framework\HttpClient\Curl\Pause;
use App\Framework\HttpClient\Curl\Exception\HandleException;
describe('Curl\HandleException', function () {
it('provides context for initialization failures', function () {
try {
// Simulate initialization failure (hard to test directly)
throw HandleException::initializationFailed('https://example.com');
} catch (HandleException $e) {
expect($e->getMessage())->toContain('Failed to initialize cURL handle');
expect($e->getData())->toHaveKey('url');
expect($e->getData()['url'])->toBe('https://example.com');
}
});
it('provides context for execution failures', function () {
$exception = HandleException::executionFailed('Connection timeout', 28);
expect($exception->getMessage())->toContain('cURL execution failed');
expect($exception->getData())->toHaveKey('curl_error_code');
expect($exception->getData())->toHaveKey('curl_error_message');
expect($exception->getData()['curl_error_code'])->toBe(28);
expect($exception->getData()['curl_error_message'])->toBe('Connection timeout');
});
it('provides context for invalid output target', function () {
$exception = HandleException::invalidOutputTarget('not-a-resource');
expect($exception->getMessage())->toContain('Invalid output target');
expect($exception->getData())->toHaveKey('output_type');
expect($exception->getData()['output_type'])->toBe('string');
});
it('provides context for setOption failures', function () {
$exception = HandleException::setOptionFailed(
HandleOption::Timeout,
'invalid',
'Invalid type'
);
expect($exception->getMessage())->toContain('Failed to set cURL option');
expect($exception->getData())->toHaveKey('option');
expect($exception->getData())->toHaveKey('value');
expect($exception->getData())->toHaveKey('error');
expect($exception->getData()['option'])->toBe('Timeout');
});
it('provides context for invalid option types', function () {
$exception = HandleException::invalidOptionType(HandleOption::Timeout, 'invalid');
expect($exception->getMessage())->toContain('Invalid type for option Timeout');
expect($exception->getMessage())->toContain('expected integer');
expect($exception->getMessage())->toContain('got string');
expect($exception->getData())->toHaveKey('option');
expect($exception->getData())->toHaveKey('expected_type');
expect($exception->getData())->toHaveKey('actual_type');
expect($exception->getData()['expected_type'])->toBe('integer');
expect($exception->getData()['actual_type'])->toBe('string');
});
it('provides context for pause failures', function () {
$exception = HandleException::pauseFailed(Pause::Recv, 'Pause operation failed');
expect($exception->getMessage())->toContain('Failed to pause cURL handle');
expect($exception->getData())->toHaveKey('pause_flag');
expect($exception->getData())->toHaveKey('pause_value');
expect($exception->getData()['pause_flag'])->toBe('Recv');
});
it('provides context for escape failures', function () {
$exception = HandleException::escapeFailed('some string');
expect($exception->getMessage())->toContain('Failed to URL-escape string');
expect($exception->getData())->toHaveKey('string_length');
expect($exception->getData()['string_length'])->toBe(strlen('some string'));
});
it('provides context for unescape failures', function () {
$exception = HandleException::unescapeFailed('some%20string');
expect($exception->getMessage())->toContain('Failed to URL-unescape string');
expect($exception->getData())->toHaveKey('string');
expect($exception->getData()['string'])->toBe('some%20string');
});
it('provides context for upkeep failures', function () {
$exception = HandleException::upkeepFailed('Connection check failed');
expect($exception->getMessage())->toContain('cURL upkeep failed');
expect($exception->getData())->toHaveKey('error');
expect($exception->getData()['error'])->toBe('Connection check failed');
});
it('includes error details in real execution failure', function () {
$handle = new Handle('https://invalid-domain-that-does-not-exist-99999.com');
$handle->setOption(HandleOption::Timeout, 3);
try {
$handle->fetch();
throw new Exception('Should have thrown HandleException');
} catch (HandleException $e) {
expect($e->getMessage())->toContain('cURL execution failed');
expect($e->getData())->toHaveKey('curl_error_code');
expect($e->getData())->toHaveKey('curl_error_message');
expect($e->getData()['curl_error_code'])->toBeGreaterThan(0);
expect($e->getData()['curl_error_message'])->not->toBeEmpty();
}
});
it('includes error details in type validation failure', function () {
$handle = new Handle();
try {
$handle->setOption(HandleOption::Timeout, 'not-an-integer');
throw new Exception('Should have thrown HandleException');
} catch (HandleException $e) {
expect($e->getMessage())->toContain('Invalid type');
expect($e->getData()['option'])->toBe('Timeout');
expect($e->getData()['expected_type'])->toBe('integer');
expect($e->getData()['actual_type'])->toBe('string');
}
});
});