Skip to content

Commit

Permalink
Merge pull request #59 from vienthuong/1.7.2
Browse files Browse the repository at this point in the history
Release 1.7.2
  • Loading branch information
vienthuong authored Nov 16, 2022
2 parents 69eea5c + 607b0cd commit fef66e5
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 24 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to `shopware-php-sdk` will be documented in this file.

Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.

### 1.7.2
- [Fix EntityCollection is returned for empty result](https://github.com/vienthuong/shopware-php-sdk/issues/58)
- [Fix EntityRepository::searchIds does not throw ShopwareSearchResponseException](https://github.com/vienthuong/shopware-php-sdk/issues/49)

### 1.7.1
- guzzlehttp/guzzle updated to version 7.5

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "A PHP SDK for Shopware 6 Platform",
"type": "library",
"license": "MIT",
"version": "1.7.1",
"version": "1.7.2",
"authors": [
{
"name": "vin",
Expand Down
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ parameters:
tmpDir: ./var/cache/phpstan
paths:
- src

excludePaths:
- src/Service/WebhookAuthenticator.php

excludes_analyse:

Expand All @@ -16,3 +19,4 @@ parameters:
message: '#Unsafe usage of new static\(\)#'
path: src/Data/Collection.php


35 changes: 23 additions & 12 deletions src/Hydrate/EntityHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,31 @@ public function schema(string $entity, Context $context): Schema
return $schema;
}

public function hydrateSearchResult(array $response, Context $context): EntityCollection
/**
* @deprecated - third parameter will be required from next major version 2.0.0
*/
public function hydrateSearchResult(array $response, Context $context, ?string $entityName = null): EntityCollection
{
// Deprecated - Remove this block on next major version 2.0.0
if ($entityName === null && !empty($response) && !empty($response['data'])) {
$data = $response['data'];
$first = current($data);

$entityName = $first['type'];
}

$collectionClass = EntityCollection::class;

if ($entityName !== null) {
$repository = RepositoryFactory::create($entityName);
$collectionClass = $repository->getDefinition()->getEntityCollection();
}

if (empty($response) || empty($response['data'])) {
return new EntityCollection();
/** @var EntityCollection $hydrated */
$hydrated = new $collectionClass([]);

return $hydrated;
}

$entities = [];
Expand All @@ -64,16 +85,6 @@ public function hydrateSearchResult(array $response, Context $context): EntityCo
$entities[$entity->id] = $entity;
}

$collectionClass = EntityCollection::class;

$data = $response['data'];
$first = current($data);

if (!empty($first['type'])) {
$repository = RepositoryFactory::create($first['type']);
$collectionClass = $repository->getDefinition()->getEntityCollection();
}

/** @var EntityCollection $collection */
$collection = new $collectionClass($entities);

Expand Down
2 changes: 1 addition & 1 deletion src/Hydrate/HydratorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ interface HydratorInterface
{
public function schema(string $entity, Context $context): Schema;

public function hydrateSearchResult(array $response, Context $context): EntityCollection;
public function hydrateSearchResult(array $response, Context $context, ?string $entityName): EntityCollection;
}
16 changes: 11 additions & 5 deletions src/Repository/EntityRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function search(Criteria $criteria, Context $context): EntitySearchResult

$aggregations = new AggregationResultCollection($response['aggregations']);

$entities = $this->hydrator->hydrateSearchResult($response, $context);
$entities = $this->hydrator->hydrateSearchResult($response, $context, $this->entityName);

$meta = new SearchResultMeta($response['meta']['total'], $response['meta']['totalCountMode']);

Expand All @@ -91,10 +91,16 @@ public function search(Criteria $criteria, Context $context): EntitySearchResult

public function searchIds(Criteria $criteria, Context $context): IdSearchResult
{
$response = $this->httpClient->post($this->getSearchIdsApiUrl($context->apiEndpoint), [
'headers' => $this->buildHeaders($context),
'body' => json_encode($criteria->parse())
])->getBody()->getContents();
try {
$response = $this->httpClient->post($this->getSearchIdsApiUrl($context->apiEndpoint), [
'headers' => $this->buildHeaders($context),
'body' => json_encode($criteria->parse())
])->getBody()->getContents();
} catch (BadResponseException $exception) {
$message = $exception->getResponse()->getBody()->getContents();

throw new ShopwareSearchResponseException($message, $exception->getResponse()->getStatusCode(), $criteria, $exception);
}

$response = $this->decodeResponse($response);

Expand Down
3 changes: 1 addition & 2 deletions src/Service/AdminSearchService.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ public function search(KeyValuePairs $criteriaCollection, array $additionalHeade

$aggregations = new AggregationResultCollection($itemResponse['aggregations'] ?? []);

$entities = $this->hydrator->hydrateSearchResult($itemResponse, $context);

$entities = $this->hydrator->hydrateSearchResult($itemResponse, $context, $entityName);

$meta = new SearchResultMeta($itemResponse['total'] ?? 0, Criteria::TOTAL_COUNT_MODE_EXACT);

Expand Down
12 changes: 10 additions & 2 deletions src/Service/WebhookAuthenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public function register(App $app): ShopRegistrationResult

parse_str($queryString, $queries);

if (!is_string($queries['shop-id']) || !is_string($queries['shop-url'])) {
throw new \RuntimeException('shop-id and shop-url should be strings');
}

$shop = new Shop($queries['shop-id'], $queries['shop-url']);

$hmac = \hash_hmac('sha256', htmlspecialchars_decode($queryString), $app->getAppSecret());
Expand Down Expand Up @@ -49,14 +53,18 @@ public static function authenticateGetRequest(string $shopSecret): bool

parse_str($queryString, $queries);

if (!is_string($queries['shop-id']) || !is_string($queries['shop-url'])) {
throw new \RuntimeException('shop-id and shop-url should be strings');
}

$shop = new Shop($queries['shop-id'], $queries['shop-url'], $shopSecret);

$queryString = sprintf(
'shop-id=%s&shop-url=%s&timestamp=%s&sw-version=%s',
$shop->getShopId(),
$shop->getShopUrl(),
$queries['timestamp'],
$queries['sw-version'],
$queries['timestamp'] ?? null,
$queries['sw-version'] ?? null,
);

if (array_key_exists('sw-context-language', $queries) && array_key_exists('sw-context-language', $queries)) {
Expand Down
3 changes: 3 additions & 0 deletions tests/AdminAuthenticatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
use Vin\ShopwareSdk\Data\AccessToken;
use Vin\ShopwareSdk\Exception\AuthorizationFailedException;

/**
* @covers \Vin\ShopwareSdk\Client\AdminAuthenticator
*/
class AdminAuthenticatorTest extends TestCase
{
private AdminAuthenticator $authenticator;
Expand Down
3 changes: 3 additions & 0 deletions tests/CriteriaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
use Vin\ShopwareSdk\Data\Filter\SuffixFilter;
use Vin\ShopwareSdk\Data\ScoreQuery\ScoreQuery;

/**
* @covers \Vin\ShopwareSdk\Data\Criteria
*/
class CriteriaTest extends TestCase
{
public function testCriteriaParsed(): void
Expand Down
3 changes: 3 additions & 0 deletions tests/Data/Response/ActionButtonResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
use Vin\ShopwareSdk\Data\Response\OpenNewTabResponse;
use Vin\ShopwareSdk\Data\Response\ReloadDataResponse;

/**
* @covers \Vin\ShopwareSdk\Data\Response\ActionButtonResponse
*/
class ActionButtonResponseTest extends TestCase
{
public function testEmptyResponsestEmptyResponse(): void
Expand Down
3 changes: 3 additions & 0 deletions tests/Data/Response/RegistrationResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
use Vin\ShopwareSdk\Data\Webhook\Shop;
use Vin\ShopwareSdk\Data\Webhook\ShopRegistrationResult;

/**
* @covers \Vin\ShopwareSdk\Data\Response\RegistrationResponse
*/
class RegistrationResponseTest extends TestCase
{
public function testResponse(): void
Expand Down
75 changes: 75 additions & 0 deletions tests/EntityHydratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

declare(strict_types=1);

namespace Vin\ShopwareSdkTest;

use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use PHPUnit\Framework\TestCase;
use Vin\ShopwareSdk\Data\AccessToken;
use Vin\ShopwareSdk\Data\Context;
use Vin\ShopwareSdk\Data\Entity\EntityCollection;
use Vin\ShopwareSdk\Data\Entity\Product\ProductCollection;
use Vin\ShopwareSdk\Data\Entity\Product\ProductDefinition;
use Vin\ShopwareSdk\Data\Entity\Product\ProductEntity;
use Vin\ShopwareSdk\Data\Uuid\Uuid;
use Vin\ShopwareSdk\Factory\RepositoryFactory;
use Vin\ShopwareSdk\Hydrate\EntityHydrator;
use Vin\ShopwareSdk\Client\Client;

/**
* @covers \Vin\ShopwareSdk\Hydrate\EntityHydrator
*/
class EntityHydratorTest extends TestCase
{
private EntityHydrator $entityHydrator;
private MockHandler $mock;
private Context $context;

protected function setUp(): void
{
$this->context = new Context('http://test.com', new AccessToken('mock-token'));
$this->mock = new MockHandler();

$handlerStack = HandlerStack::create($this->mock);

$client = Client::create(['handler' => $handlerStack]);

$this->entityHydrator = new EntityHydrator(false);
$this->productRepository = RepositoryFactory::create(ProductDefinition::ENTITY_NAME);

$this->productRepository->setHttpClient($client);
}

public function testHydrateSearchResultWithEmptyResult(): void
{
$result = $this->entityHydrator->hydrateSearchResult([], $this->context);

static::assertInstanceOf(EntityCollection::class, $result);

$result = $this->entityHydrator->hydrateSearchResult([], $this->context, 'product');

static::assertInstanceOf(ProductCollection::class, $result);
}

public function testHydrateSearchResultWithResult(): void
{
$productId = Uuid::randomHex();
$result = $this->entityHydrator->hydrateSearchResult([
'data' => [
[
'attributes' => [
'name' => 'Test Product',
],
'type' => 'product',
'id' => $productId,
]
],
], $this->context, 'product');

static::assertInstanceOf(ProductCollection::class, $result);
static::assertCount(1, $result);
static::assertInstanceOf(ProductEntity::class, $result->get($productId));
}
}
16 changes: 15 additions & 1 deletion tests/EntityRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
use Vin\ShopwareSdk\Repository\Struct\IdSearchResult;
use Vin\ShopwareSdk\Client\Client;

/**
* @covers \Vin\ShopwareSdk\Repository\EntityRepository
*/
class EntityRepositoryTest extends TestCase
{
private EntityRepository $productRepository;
Expand All @@ -49,7 +52,7 @@ protected function setUp(): void
$this->productRepository->setHttpClient($client);
}

public function testBadResponse(): void
public function testSearchBadResponse(): void
{
static::expectException(ShopwareResponseException::class);
static::expectExceptionMessage('Unauthenticated');
Expand Down Expand Up @@ -136,6 +139,17 @@ public function testSearchIds(): void
static::assertEquals(69, $result->getTotal());
}

public function testSearchShouldThrowShopwareHttpException(): void
{
static::expectException(ShopwareResponseException::class);
static::expectExceptionMessage('Unauthenticated');
static::expectExceptionCode(401);

$this->mock->append(new BadResponseException('Unauthenticated', new Request('POST', 'test'), new Response(401, [], 'Unauthenticated')));

$this->productRepository->searchIds(new Criteria(), $this->context);
}

public function testCreateNew(): void
{
$this->mock->append(new Response(200, [], file_get_contents(__DIR__ . '/stubs/product-ids.json')));
Expand Down
3 changes: 3 additions & 0 deletions tests/GrantTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
use Vin\ShopwareSdk\Client\GrantType\ClientCredentialsGrantType;
use Vin\ShopwareSdk\Client\GrantType\RefreshTokenGrantType;

/**
* @covers \Vin\ShopwareSdk\Client\GrantType\GrantType
*/
class GrantTypeTest extends TestCase
{
public function testCreateFromInvalidConfig(): void
Expand Down
3 changes: 3 additions & 0 deletions tests/InfoServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
use Vin\ShopwareSdk\Data\Schema\Schema;
use Vin\ShopwareSdk\Service\InfoService;

/**
* @covers \Vin\ShopwareSdk\Service\InfoService
*/
class InfoServiceTest extends TestCase
{
public function testGetSchema(): void
Expand Down
3 changes: 3 additions & 0 deletions tests/RepositoryFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
use Vin\ShopwareSdk\Factory\RepositoryFactory;
use Vin\ShopwareSdk\Repository\EntityRepository;

/**
* @covers \Vin\ShopwareSdk\Factory\RepositoryFactory
*/
class RepositoryFactoryTest extends TestCase
{
public function testCreateEntity(): void
Expand Down

0 comments on commit fef66e5

Please sign in to comment.