/** * @param HttpMethod $method * @param string $url * @param mixed[]|null $data * @param string[] $headers * @return Response * @throws CurlDriverException */ public function request(HttpMethod $method, string $url, array $data = null, array $headers = []) : Response { $ch = curl_init($url); if ($method->equalsValue(HttpMethod::POST) || $method->equalsValue(HttpMethod::PUT)) { curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method->getValue()); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); } curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($ch, CURLOPT_COOKIESESSION, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers + ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); $output = curl_exec($ch); if ($output === false) { throw new CurlDriverException($ch); } $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $headers = substr($output, 0, $headerSize); $body = substr($output, $headerSize); $responseCode = new ResponseCode(curl_getinfo($ch, CURLINFO_HTTP_CODE)); curl_close($ch); return new Response($responseCode, json_decode($body, true), $this->parseHeaders($headers)); }
/** * @param HttpMethod $method * @param string $url * @param mixed[]|null $data * @param string[] $headers * @return Response * @throws GuzzleDriverException */ public function request(HttpMethod $method, string $url, array $data = null, array $headers = []) : Response { $postData = null; if ($method->equalsValue(HttpMethod::POST) || $method->equalsValue(HttpMethod::PUT)) { $postData = json_encode($data); } $headers += ['Content-Type' => 'application/json']; $request = new Request($method->getValue(), $url, $headers, $postData); try { $httpResponse = $this->client->send($request, [RequestOptions::HTTP_ERRORS => false, RequestOptions::ALLOW_REDIRECTS => false]); $responseCode = new ResponseCode($httpResponse->getStatusCode()); $responseHeaders = array_map(function ($item) { return !is_array($item) || count($item) > 1 ? $item : array_shift($item); }, $httpResponse->getHeaders()); return new Response($responseCode, json_decode((string) $httpResponse->getBody(), true), $responseHeaders); } catch (\Throwable $e) { throw new GuzzleDriverException($e); } }
/** * @param HttpMethod $httpMethod * @param string $url * @param string $expectedUrl * @param mixed[] $requestData * @param mixed[]|null $expectedRequestData * @param mixed[]|null $responseData * @param ResponseCode $responseCode * @param mixed[] $responseHeaders * * @dataProvider getRequests */ public function testRequests(HttpMethod $httpMethod, string $url, string $expectedUrl, array $requestData, array $expectedRequestData = null, array $responseData = null, ResponseCode $responseCode, array $responseHeaders) { $cryptoService = $this->getMockBuilder(CryptoService::class)->disableOriginalConstructor()->getMock(); $cryptoService->expects(self::any())->method('signData')->willReturn('signature'); $cryptoService->expects(self::any())->method('verifyData')->willReturn(true); /** @var CryptoService $cryptoService */ $apiClientDriver = $this->getMockBuilder(ApiClientDriver::class)->getMock(); if ($httpMethod->equalsValue(HttpMethod::GET)) { $apiClientDriver->expects(self::once())->method('request')->with($httpMethod, $this->matchesRegularExpression(sprintf('~^%s/%s$~', preg_quote(self::API_URL, '~'), $expectedUrl)), $expectedRequestData)->willReturn(new Response($responseCode, ($responseData !== null ? $responseData : []) + ['signature' => 'signature'], $responseHeaders)); } else { $apiClientDriver->expects(self::once())->method('request')->willReturnCallback(function (HttpMethod $method, string $url, array $requestData) use($httpMethod, $expectedUrl, $expectedRequestData, $responseCode, $responseData, $responseHeaders) : Response { $this->assertEquals($httpMethod, $method); $this->assertSame(sprintf('%s/%s', self::API_URL, $expectedUrl), $url); $dttm = $requestData['dttm']; $this->assertRegExp('~^\\d{14}$~', $dttm); unset($requestData['dttm']); $this->assertEquals($expectedRequestData + ['signature' => 'signature'], $requestData); return new Response($responseCode, ($responseData !== null ? $responseData : []) + ['signature' => 'signature'], $responseHeaders); }); } $logger = $this->getMockBuilder(LoggerInterface::class)->disableOriginalConstructor()->getMock(); $logger->expects(self::once())->method('info')->with($this->isType('string'), $this->isType('array')); /** @var ApiClientDriver $apiClientDriver */ $apiClient = new ApiClient($apiClientDriver, $cryptoService, self::API_URL); /** @var LoggerInterface $logger */ $apiClient->setLogger($logger); if ($httpMethod->equalsValue(HttpMethod::GET)) { $response = $apiClient->get($url, $requestData, new SignatureDataFormatter([]), new SignatureDataFormatter([])); } elseif ($httpMethod->equalsValue(HttpMethod::POST)) { $response = $apiClient->post($url, $requestData, new SignatureDataFormatter([]), new SignatureDataFormatter([])); } else { $response = $apiClient->put($url, $requestData, new SignatureDataFormatter([]), new SignatureDataFormatter([])); } $this->assertInstanceOf(Response::class, $response); $this->assertSame($responseCode->getValue(), $response->getResponseCode()->getValue()); $this->assertEquals($responseHeaders, $response->getHeaders()); $this->assertEquals($responseData, $response->getData()); }