HttpClientTest.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <?php
  2. declare(strict_types=1);
  3. namespace SixShop\Wangdian\Tests\Unit\Http;
  4. use GuzzleHttp\Client;
  5. use GuzzleHttp\Exception\RequestException;
  6. use GuzzleHttp\Handler\MockHandler;
  7. use GuzzleHttp\HandlerStack;
  8. use GuzzleHttp\Psr7\Request;
  9. use GuzzleHttp\Psr7\Response;
  10. use PHPUnit\Framework\TestCase;
  11. use SixShop\Wangdian\Config\Config;
  12. use SixShop\Wangdian\Exception\HttpException;
  13. use SixShop\Wangdian\Http\HttpClient;
  14. use SixShop\Wangdian\Tests\TestConfig;
  15. class HttpClientTest extends TestCase
  16. {
  17. private Config $config;
  18. protected function setUp(): void
  19. {
  20. // Use secure test configuration
  21. $testConfig = TestConfig::get();
  22. $this->config = new Config(
  23. sid: $testConfig['credentials']['sid'],
  24. appKey: $testConfig['credentials']['app_key'],
  25. appSecret: $testConfig['credentials']['app_secret'],
  26. baseUrl: $testConfig['endpoints']['sandbox_base_url'],
  27. timeout: $testConfig['settings']['timeout'],
  28. debug: $testConfig['settings']['debug']
  29. );
  30. }
  31. public function testConstructorWithDefaultClient(): void
  32. {
  33. $httpClient = new HttpClient($this->config);
  34. $this->assertInstanceOf(HttpClient::class, $httpClient);
  35. }
  36. public function testSuccessfulPostRequest(): void
  37. {
  38. $mockResponses = TestConfig::getMockResponses();
  39. $mockResponse = json_encode($mockResponses['success']);
  40. // Create a mock handler with successful response
  41. $mock = new MockHandler([
  42. new Response(200, [], $mockResponse)
  43. ]);
  44. $handlerStack = HandlerStack::create($mock);
  45. $mockClient = new Client(['handler' => $handlerStack]);
  46. $httpClient = new HttpClient($this->config, $mockClient);
  47. $result = $httpClient->post('test_endpoint.php', ['param' => 'value']);
  48. $this->assertEquals($mockResponses['success'], $result);
  49. }
  50. public function testPostRequestWithNon200Status(): void
  51. {
  52. $mock = new MockHandler([
  53. new Response(500, [], 'Internal Server Error')
  54. ]);
  55. $handlerStack = HandlerStack::create($mock);
  56. $mockClient = new Client(['handler' => $handlerStack]);
  57. $httpClient = new HttpClient($this->config, $mockClient);
  58. $this->expectException(HttpException::class);
  59. $this->expectExceptionMessageMatches('/HTTP request failed.*500/');
  60. $httpClient->post('test_endpoint.php', ['param' => 'value']);
  61. }
  62. public function testPostRequestWithInvalidJson(): void
  63. {
  64. $mock = new MockHandler([
  65. new Response(200, [], 'invalid json response')
  66. ]);
  67. $handlerStack = HandlerStack::create($mock);
  68. $mockClient = new Client(['handler' => $handlerStack]);
  69. $httpClient = new HttpClient($this->config, $mockClient);
  70. $this->expectException(HttpException::class);
  71. $this->expectExceptionMessage('Failed to parse JSON response');
  72. $httpClient->post('test_endpoint.php', ['param' => 'value']);
  73. }
  74. public function testPostRequestWithEmptyResponse(): void
  75. {
  76. $mock = new MockHandler([
  77. new Response(200, [], '')
  78. ]);
  79. $handlerStack = HandlerStack::create($mock);
  80. $mockClient = new Client(['handler' => $handlerStack]);
  81. $httpClient = new HttpClient($this->config, $mockClient);
  82. $this->expectException(HttpException::class);
  83. $this->expectExceptionMessage('Empty response body received');
  84. $httpClient->post('test_endpoint.php', ['param' => 'value']);
  85. }
  86. public function testPostRequestWithRequestException(): void
  87. {
  88. $mock = new MockHandler([
  89. new RequestException('Connection timeout', new Request('POST', 'test'))
  90. ]);
  91. $handlerStack = HandlerStack::create($mock);
  92. $mockClient = new Client(['handler' => $handlerStack]);
  93. $httpClient = new HttpClient($this->config, $mockClient);
  94. $this->expectException(HttpException::class);
  95. $this->expectExceptionMessage('HTTP request failed: Connection timeout');
  96. $httpClient->post('test_endpoint.php', ['param' => 'value']);
  97. }
  98. public function testEndpointUrlGeneration(): void
  99. {
  100. $mockResponses = TestConfig::getMockResponses();
  101. $mockResponse = json_encode($mockResponses['success']);
  102. $mock = new MockHandler([
  103. new Response(200, [], $mockResponse)
  104. ]);
  105. $handlerStack = HandlerStack::create($mock);
  106. $mockClient = new Client(['handler' => $handlerStack]);
  107. $httpClient = new HttpClient($this->config, $mockClient);
  108. $result = $httpClient->post('trade_push.php', ['test' => 'data']);
  109. $this->assertEquals($mockResponses['success'], $result);
  110. }
  111. public function testSslVerificationDisabledForSandbox(): void
  112. {
  113. $sandboxConfig = Config::sandbox('test_sid', 'test_key', 'test_secret');
  114. $httpClient = new HttpClient($sandboxConfig);
  115. $this->assertInstanceOf(HttpClient::class, $httpClient);
  116. $this->assertTrue($sandboxConfig->isSandbox());
  117. }
  118. public function testHttpExceptionContext(): void
  119. {
  120. $mock = new MockHandler([
  121. new RequestException('Network error', new Request('POST', 'test'))
  122. ]);
  123. $handlerStack = HandlerStack::create($mock);
  124. $mockClient = new Client(['handler' => $handlerStack]);
  125. $httpClient = new HttpClient($this->config, $mockClient);
  126. try {
  127. $httpClient->post('test_endpoint.php', ['param' => 'value']);
  128. $this->fail('Expected HttpException was not thrown');
  129. } catch (HttpException $e) {
  130. $context = $e->getContext();
  131. $this->assertIsArray($context);
  132. $this->assertArrayHasKey('url', $context);
  133. $this->assertArrayHasKey('data', $context);
  134. }
  135. }
  136. }