config = new Config( sid: $testConfig['credentials']['sid'], appKey: $testConfig['credentials']['app_key'], appSecret: $testConfig['credentials']['app_secret'], baseUrl: $testConfig['endpoints']['sandbox_base_url'], timeout: $testConfig['settings']['timeout'], debug: $testConfig['settings']['debug'] ); } public function testConstructorWithDefaultClient(): void { $httpClient = new HttpClient($this->config); $this->assertInstanceOf(HttpClient::class, $httpClient); } public function testSuccessfulPostRequest(): void { $mockResponses = TestConfig::getMockResponses(); $mockResponse = json_encode($mockResponses['success']); // Create a mock handler with successful response $mock = new MockHandler([ new Response(200, [], $mockResponse) ]); $handlerStack = HandlerStack::create($mock); $mockClient = new Client(['handler' => $handlerStack]); $httpClient = new HttpClient($this->config, $mockClient); $result = $httpClient->post('test_endpoint.php', ['param' => 'value']); $this->assertEquals($mockResponses['success'], $result); } public function testPostRequestWithNon200Status(): void { $mock = new MockHandler([ new Response(500, [], 'Internal Server Error') ]); $handlerStack = HandlerStack::create($mock); $mockClient = new Client(['handler' => $handlerStack]); $httpClient = new HttpClient($this->config, $mockClient); $this->expectException(HttpException::class); $this->expectExceptionMessageMatches('/HTTP request failed.*500/'); $httpClient->post('test_endpoint.php', ['param' => 'value']); } public function testPostRequestWithInvalidJson(): void { $mock = new MockHandler([ new Response(200, [], 'invalid json response') ]); $handlerStack = HandlerStack::create($mock); $mockClient = new Client(['handler' => $handlerStack]); $httpClient = new HttpClient($this->config, $mockClient); $this->expectException(HttpException::class); $this->expectExceptionMessage('Failed to parse JSON response'); $httpClient->post('test_endpoint.php', ['param' => 'value']); } public function testPostRequestWithEmptyResponse(): void { $mock = new MockHandler([ new Response(200, [], '') ]); $handlerStack = HandlerStack::create($mock); $mockClient = new Client(['handler' => $handlerStack]); $httpClient = new HttpClient($this->config, $mockClient); $this->expectException(HttpException::class); $this->expectExceptionMessage('Empty response body received'); $httpClient->post('test_endpoint.php', ['param' => 'value']); } public function testPostRequestWithRequestException(): void { $mock = new MockHandler([ new RequestException('Connection timeout', new Request('POST', 'test')) ]); $handlerStack = HandlerStack::create($mock); $mockClient = new Client(['handler' => $handlerStack]); $httpClient = new HttpClient($this->config, $mockClient); $this->expectException(HttpException::class); $this->expectExceptionMessage('HTTP request failed: Connection timeout'); $httpClient->post('test_endpoint.php', ['param' => 'value']); } public function testEndpointUrlGeneration(): void { $mockResponses = TestConfig::getMockResponses(); $mockResponse = json_encode($mockResponses['success']); $mock = new MockHandler([ new Response(200, [], $mockResponse) ]); $handlerStack = HandlerStack::create($mock); $mockClient = new Client(['handler' => $handlerStack]); $httpClient = new HttpClient($this->config, $mockClient); $result = $httpClient->post('trade_push.php', ['test' => 'data']); $this->assertEquals($mockResponses['success'], $result); } public function testSslVerificationDisabledForSandbox(): void { $sandboxConfig = Config::sandbox('test_sid', 'test_key', 'test_secret'); $httpClient = new HttpClient($sandboxConfig); $this->assertInstanceOf(HttpClient::class, $httpClient); $this->assertTrue($sandboxConfig->isSandbox()); } public function testHttpExceptionContext(): void { $mock = new MockHandler([ new RequestException('Network error', new Request('POST', 'test')) ]); $handlerStack = HandlerStack::create($mock); $mockClient = new Client(['handler' => $handlerStack]); $httpClient = new HttpClient($this->config, $mockClient); try { $httpClient->post('test_endpoint.php', ['param' => 'value']); $this->fail('Expected HttpException was not thrown'); } catch (HttpException $e) { $context = $e->getContext(); $this->assertIsArray($context); $this->assertArrayHasKey('url', $context); $this->assertArrayHasKey('data', $context); } } }