commercetools-8.x-1.2-alpha1/tests/modules/commercetools_test/src/CommercetoolsHttpClientFactoryMock.php
tests/modules/commercetools_test/src/CommercetoolsHttpClientFactoryMock.php
<?php
declare(strict_types=1);
namespace Drupal\commercetools_test;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\State\StateInterface;
use Drupal\test_helpers_http_client_mock\HttpClientFactoryMock;
use GraphQL\Language\Parser;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
/**
* Overridden version of the HttpClientFactoryMock.
*/
class CommercetoolsHttpClientFactoryMock extends HttpClientFactoryMock {
const CART_CONTEXT_KEY = 'ctCart-context';
const CART_CONTEXT_STATE_KEY = 'ct-cart-context';
/**
* {@inheritdoc}
*/
public function __construct(
HandlerStack $stack,
protected StateInterface $state,
protected ConfigFactoryInterface $configFactory,
protected LockBackendInterface $lock,
protected ?string $requestMockMode = NULL,
protected ?string $responsesStorageDirectory = NULL,
protected ?string $testName = NULL,
protected ?string $uriRegexp = NULL,
) {
parent::__construct(
$stack,
$state,
$configFactory,
$lock,
$requestMockMode,
$responsesStorageDirectory,
$testName,
);
$commercetoolsRequestsHandler = function (callable $handler) {
return function ($request, array $options) use ($handler) {
$data = json_decode($request->getBody()->getContents(), TRUE);
if ($data === NULL || !isset($data['query'])) {
return $handler($request, $options);
}
$graphQlQueryOperation = $this->getGraphQlOperation($data['query']);
switch ($graphQlQueryOperation) {
case 'updateCart':
$id = $data['variables']['id'] ?? NULL;
$version = $data['variables']['version'] ?? NULL;
if ($id && $version) {
$keyParts = [
$this->stubGetContext(),
self::CART_CONTEXT_KEY,
$id,
$version,
];
$key = implode('-', array_filter($keyParts));
$this->acquireLockWithWait($key);
$this->stubSetContext($key);
$contextData = $this->state->get(self::CART_CONTEXT_STATE_KEY, []);
$contextData[$id] = $version;
$this->state->set(self::CART_CONTEXT_STATE_KEY, $contextData);
$this->lock->release($key);
}
return $handler($request, $options);
case 'getCart':
$id = $data['variables']['id'] ?? NULL;
$this->state->resetCache();
if ($contextData = $this->state->get(self::CART_CONTEXT_STATE_KEY)) {
if (isset($contextData[$id])) {
$version = $contextData[$id]++;
$keyParts = [
$this->stubGetContext(),
self::CART_CONTEXT_KEY,
$id,
$version,
];
$key = implode('-', array_filter($keyParts));
$this->stubSetContext($key);
}
}
return $handler($request, $options);
case 'messages':
$response = [
'data' => [
'messages' => [
'total' => 0,
'results' => [],
],
],
];
return new Response(200, [], json_encode($response));
default:
return $handler($request, $options);
}
};
};
$this->stubSetCustomHandler($commercetoolsRequestsHandler);
}
/**
* Extracts the operation name from a GraphQL query as string.
*
* @param string $query
* A GraphQL query as string.
* @param int $delta
* The operation delta, 0 by default.
*
* @return string
* The operation name.
*/
protected function getGraphQlOperation(string $query, int $delta = 0): string {
$queryObject = Parser::parse($query);
$queryRootNodes = $queryObject->toArray()['definitions'];
$node = $queryRootNodes->offsetGet($delta);
$operation = $node->selectionSet->selections->offsetGet(0)->name->value;
return $operation;
}
/**
* Extends the parent to format the stored requests for commercetools testing.
*
* {@inheritdoc}
*/
protected function stubGetRequestMetadata($request): array {
$metadata = parent::stubGetRequestMetadata($request);
$metadata = CommerceToolsTesting::formatCtRequestAssetMetadata($metadata);
return $metadata;
}
}
