diff --git a/composer.json b/composer.json
index bbf75a0..19bc629 100644
--- a/composer.json
+++ b/composer.json
@@ -43,7 +43,7 @@
"post-install-cmd": "cghooks add --ignore-lock",
"post-update-cmd": "cghooks update",
"phpunit": "./vendor/bin/phpunit -c phpunit.xml.dist",
- "phpmd": "./vendor/bin/phpmd src text controversial,design,./phpmd.xml",
+ "phpmd": "./vendor/bin/phpmd src text controversial,./phpmd.xml",
"phpcs": "./vendor/bin/phpcs -p src --runtime-set testVersion 7.3",
"lint": "composer run-script phpcs && composer run-script phpmd",
"ci": "composer run-script lint && composer run-script phpunit"
@@ -51,7 +51,6 @@
"extra": {
"hooks": {
"pre-commit": [
- "echo => Running code quality tools...",
"composer run-script lint"
]
}
diff --git a/phpmd.xml b/phpmd.xml
index fee5306..65f6fc3 100644
--- a/phpmd.xml
+++ b/phpmd.xml
@@ -19,11 +19,19 @@
+
+
+
+
+
+
+
+
diff --git a/src/Component/Exception/TopApiException.php b/src/Component/Exception/TopApiException.php
new file mode 100644
index 0000000..463295a
--- /dev/null
+++ b/src/Component/Exception/TopApiException.php
@@ -0,0 +1,70 @@
+
+ * @license MIT
+ * @link http://retailcrm.ru
+ * @see http://help.retailcrm.ru
+ */
+namespace RetailCrm\Component\Exception;
+
+use Exception;
+use RetailCrm\Model\Response\Body\ErrorResponseBody;
+use Throwable;
+
+/**
+ * Class TopApiException
+ *
+ * @category TopApiException
+ * @package RetailCrm\Component\Exception
+ * @author RetailDriver LLC
+ * @license MIT
+ * @link http://retailcrm.ru
+ * @see https://help.retailcrm.ru
+ */
+class TopApiException extends Exception
+{
+ /**
+ * @var string $subCode
+ */
+ private $subCode;
+
+ /**
+ * @var string $requestId
+ */
+ private $requestId;
+
+ /**
+ * TopApiException constructor.
+ *
+ * @param \RetailCrm\Model\Response\Body\ErrorResponseBody $responseBody
+ * @param \Throwable|null $previous
+ */
+ public function __construct(ErrorResponseBody $responseBody, Throwable $previous = null)
+ {
+ parent::__construct($responseBody->msg, $responseBody->code, $previous);
+
+ $this->subCode = $responseBody->subCode;
+ $this->requestId = $responseBody->requestId;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSubCode(): string
+ {
+ return $this->subCode;
+ }
+
+ /**
+ * @return string
+ */
+ public function getRequestId(): string
+ {
+ return $this->requestId;
+ }
+}
diff --git a/src/Component/Exception/TopClientException.php b/src/Component/Exception/TopClientException.php
new file mode 100644
index 0000000..3c8d87d
--- /dev/null
+++ b/src/Component/Exception/TopClientException.php
@@ -0,0 +1,29 @@
+
+ * @license MIT
+ * @link http://retailcrm.ru
+ * @see http://help.retailcrm.ru
+ */
+namespace RetailCrm\Component\Exception;
+
+use Exception;
+
+/**
+ * Class TopClientException
+ *
+ * @category TopClientException
+ * @package RetailCrm\Component\Exception
+ * @author RetailDriver LLC
+ * @license MIT
+ * @link http://retailcrm.ru
+ * @see https://help.retailcrm.ru
+ */
+class TopClientException extends Exception
+{
+}
diff --git a/src/Model/Request/HttpDnsGetRequest.php b/src/Model/Request/HttpDnsGetRequest.php
index ee1b1a6..fe12595 100644
--- a/src/Model/Request/HttpDnsGetRequest.php
+++ b/src/Model/Request/HttpDnsGetRequest.php
@@ -12,6 +12,8 @@
*/
namespace RetailCrm\Model\Request;
+use RetailCrm\Model\Response\BaseResponse;
+
/**
* Class HttpDnsGetRequest
*
@@ -42,6 +44,6 @@ class HttpDnsGetRequest extends BaseRequest
public function getExpectedResponse(): string
{
// TODO: Implement getExpectedResponse() method.
- return '';
+ return BaseResponse::class;
}
}
diff --git a/src/Model/Response/BaseResponse.php b/src/Model/Response/BaseResponse.php
new file mode 100644
index 0000000..9a96e93
--- /dev/null
+++ b/src/Model/Response/BaseResponse.php
@@ -0,0 +1,36 @@
+
+ * @license MIT
+ * @link http://retailcrm.ru
+ * @see http://help.retailcrm.ru
+ */
+namespace RetailCrm\Model\Response;
+
+use JMS\Serializer\Annotation as JMS;
+
+/**
+ * Class BaseResponse
+ *
+ * @category BaseResponse
+ * @package RetailCrm\Model\Response
+ * @author RetailDriver LLC
+ * @license MIT
+ * @link http://retailcrm.ru
+ * @see https://help.retailcrm.ru
+ */
+class BaseResponse
+{
+ /**
+ * @var \RetailCrm\Model\Response\Body\ErrorResponseBody
+ *
+ * @JMS\Type("RetailCrm\Model\Response\Body\ErrorResponseBody")
+ * @JMS\SerializedName("error_response")
+ */
+ public $errorResponse;
+}
diff --git a/src/Model/Response/Body/ErrorResponseBody.php b/src/Model/Response/Body/ErrorResponseBody.php
new file mode 100644
index 0000000..9547773
--- /dev/null
+++ b/src/Model/Response/Body/ErrorResponseBody.php
@@ -0,0 +1,60 @@
+
+ * @license MIT
+ * @link http://retailcrm.ru
+ * @see http://help.retailcrm.ru
+ */
+namespace RetailCrm\Model\Response\Body;
+
+use JMS\Serializer\Annotation as JMS;
+
+/**
+ * Class ErrorResponseBody
+ *
+ * @category ErrorResponseBody
+ * @package RetailCrm\Model\Response\Body
+ * @author RetailDriver LLC
+ * @license MIT
+ * @link http://retailcrm.ru
+ * @see https://help.retailcrm.ru
+ */
+class ErrorResponseBody
+{
+ /**
+ * @var int $code
+ *
+ * @JMS\Type("int")
+ * @JMS\SerializedName("code")
+ */
+ public $code;
+
+ /**
+ * @var string $msg
+ *
+ * @JMS\Type("string")
+ * @JMS\SerializedName("msg")
+ */
+ public $msg;
+
+ /**
+ * @var string $subCode
+ *
+ * @JMS\Type("string")
+ * @JMS\SerializedName("sub_code")
+ */
+ public $subCode;
+
+ /**
+ * @var string $requestId
+ *
+ * @JMS\Type("string")
+ * @JMS\SerializedName("request_id")
+ */
+ public $requestId;
+}
diff --git a/src/TopClient/Client.php b/src/TopClient/Client.php
index 6fb6263..2983c93 100644
--- a/src/TopClient/Client.php
+++ b/src/TopClient/Client.php
@@ -14,11 +14,14 @@ namespace RetailCrm\TopClient;
use JMS\Serializer\SerializerInterface;
use Psr\Http\Client\ClientInterface;
+use RetailCrm\Component\Exception\TopApiException;
+use RetailCrm\Component\Exception\TopClientException;
use RetailCrm\Component\ServiceLocator;
use RetailCrm\Interfaces\AppDataInterface;
use RetailCrm\Interfaces\AuthenticatorInterface;
use RetailCrm\Interfaces\RequestFactoryInterface;
use RetailCrm\Model\Request\BaseRequest;
+use RetailCrm\Model\Response\BaseResponse;
use RetailCrm\Traits\ValidatorAwareTrait;
use Symfony\Component\Validator\Constraints as Assert;
@@ -138,17 +141,32 @@ class Client
/**
* @param \RetailCrm\Model\Request\BaseRequest $request
*
- * @return void
+ * @return \RetailCrm\Model\Response\BaseResponse
* @throws \Psr\Http\Client\ClientExceptionInterface
* @throws \RetailCrm\Component\Exception\ValidationException
* @throws \RetailCrm\Component\Exception\FactoryException
- *
- * @todo Implement this method and remove tag below.
- * @SuppressWarnings(PHPMD)
+ * @throws \RetailCrm\Component\Exception\TopClientException
+ * @throws \RetailCrm\Component\Exception\TopApiException
*/
public function sendRequest(BaseRequest $request)
{
$httpRequest = $this->requestFactory->fromModel($request, $this->appData, $this->authenticator);
- $response = $this->httpClient->sendRequest($httpRequest);
+ $httpResponse = $this->httpClient->sendRequest($httpRequest);
+ /** @var BaseResponse $response */
+ $response = $this->serializer->deserialize(
+ $httpResponse->getBody()->getContents(),
+ $request->getExpectedResponse(),
+ $request->format
+ );
+
+ if (!($response instanceof BaseResponse) && !is_subclass_of($response, BaseResponse::class)) {
+ throw new TopClientException(sprintf('Invalid response class: %s', get_class($response)));
+ }
+
+ if (null !== $response->errorResponse) {
+ throw new TopApiException($response->errorResponse);
+ }
+
+ return $response;
}
}
diff --git a/tests/RetailCrm/Tests/TopClient/ClientTest.php b/tests/RetailCrm/Tests/TopClient/ClientTest.php
index a4d8235..37de4c8 100644
--- a/tests/RetailCrm/Tests/TopClient/ClientTest.php
+++ b/tests/RetailCrm/Tests/TopClient/ClientTest.php
@@ -32,7 +32,7 @@ class ClientTest extends TestCase
{
public function testClientRequest()
{
- self::markTestSkipped('Not implemented yet');
+ self::markTestSkipped('Should be mocked!');
$client = ClientBuilder::create()
->setContainer($this->getContainer())