Skip to content

Commit 607b0cd

Browse files
Le ThuongLe Thuong
Le Thuong
authored and
Le Thuong
committed
Release 1.7.2
1 parent 69eea5c commit 607b0cd

17 files changed

+166
-24
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to `shopware-php-sdk` will be documented in this file.
44

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

7+
### 1.7.2
8+
- [Fix EntityCollection is returned for empty result](https://github.com/vienthuong/shopware-php-sdk/issues/58)
9+
- [Fix EntityRepository::searchIds does not throw ShopwareSearchResponseException](https://github.com/vienthuong/shopware-php-sdk/issues/49)
10+
711
### 1.7.1
812
- guzzlehttp/guzzle updated to version 7.5
913

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "A PHP SDK for Shopware 6 Platform",
44
"type": "library",
55
"license": "MIT",
6-
"version": "1.7.1",
6+
"version": "1.7.2",
77
"authors": [
88
{
99
"name": "vin",

phpstan.neon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ parameters:
88
tmpDir: ./var/cache/phpstan
99
paths:
1010
- src
11+
12+
excludePaths:
13+
- src/Service/WebhookAuthenticator.php
1114

1215
excludes_analyse:
1316

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

22+

src/Hydrate/EntityHydrator.php

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,31 @@ public function schema(string $entity, Context $context): Schema
5151
return $schema;
5252
}
5353

54-
public function hydrateSearchResult(array $response, Context $context): EntityCollection
54+
/**
55+
* @deprecated - third parameter will be required from next major version 2.0.0
56+
*/
57+
public function hydrateSearchResult(array $response, Context $context, ?string $entityName = null): EntityCollection
5558
{
59+
// Deprecated - Remove this block on next major version 2.0.0
60+
if ($entityName === null && !empty($response) && !empty($response['data'])) {
61+
$data = $response['data'];
62+
$first = current($data);
63+
64+
$entityName = $first['type'];
65+
}
66+
67+
$collectionClass = EntityCollection::class;
68+
69+
if ($entityName !== null) {
70+
$repository = RepositoryFactory::create($entityName);
71+
$collectionClass = $repository->getDefinition()->getEntityCollection();
72+
}
73+
5674
if (empty($response) || empty($response['data'])) {
57-
return new EntityCollection();
75+
/** @var EntityCollection $hydrated */
76+
$hydrated = new $collectionClass([]);
77+
78+
return $hydrated;
5879
}
5980

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

67-
$collectionClass = EntityCollection::class;
68-
69-
$data = $response['data'];
70-
$first = current($data);
71-
72-
if (!empty($first['type'])) {
73-
$repository = RepositoryFactory::create($first['type']);
74-
$collectionClass = $repository->getDefinition()->getEntityCollection();
75-
}
76-
7788
/** @var EntityCollection $collection */
7889
$collection = new $collectionClass($entities);
7990

src/Hydrate/HydratorInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ interface HydratorInterface
1212
{
1313
public function schema(string $entity, Context $context): Schema;
1414

15-
public function hydrateSearchResult(array $response, Context $context): EntityCollection;
15+
public function hydrateSearchResult(array $response, Context $context, ?string $entityName): EntityCollection;
1616
}

src/Repository/EntityRepository.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public function search(Criteria $criteria, Context $context): EntitySearchResult
8282

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

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

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

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

9292
public function searchIds(Criteria $criteria, Context $context): IdSearchResult
9393
{
94-
$response = $this->httpClient->post($this->getSearchIdsApiUrl($context->apiEndpoint), [
95-
'headers' => $this->buildHeaders($context),
96-
'body' => json_encode($criteria->parse())
97-
])->getBody()->getContents();
94+
try {
95+
$response = $this->httpClient->post($this->getSearchIdsApiUrl($context->apiEndpoint), [
96+
'headers' => $this->buildHeaders($context),
97+
'body' => json_encode($criteria->parse())
98+
])->getBody()->getContents();
99+
} catch (BadResponseException $exception) {
100+
$message = $exception->getResponse()->getBody()->getContents();
101+
102+
throw new ShopwareSearchResponseException($message, $exception->getResponse()->getStatusCode(), $criteria, $exception);
103+
}
98104

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

src/Service/AdminSearchService.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,7 @@ public function search(KeyValuePairs $criteriaCollection, array $additionalHeade
9090

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

93-
$entities = $this->hydrator->hydrateSearchResult($itemResponse, $context);
94-
93+
$entities = $this->hydrator->hydrateSearchResult($itemResponse, $context, $entityName);
9594

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

src/Service/WebhookAuthenticator.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ public function register(App $app): ShopRegistrationResult
1818

1919
parse_str($queryString, $queries);
2020

21+
if (!is_string($queries['shop-id']) || !is_string($queries['shop-url'])) {
22+
throw new \RuntimeException('shop-id and shop-url should be strings');
23+
}
24+
2125
$shop = new Shop($queries['shop-id'], $queries['shop-url']);
2226

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

5054
parse_str($queryString, $queries);
5155

56+
if (!is_string($queries['shop-id']) || !is_string($queries['shop-url'])) {
57+
throw new \RuntimeException('shop-id and shop-url should be strings');
58+
}
59+
5260
$shop = new Shop($queries['shop-id'], $queries['shop-url'], $shopSecret);
5361

5462
$queryString = sprintf(
5563
'shop-id=%s&shop-url=%s&timestamp=%s&sw-version=%s',
5664
$shop->getShopId(),
5765
$shop->getShopUrl(),
58-
$queries['timestamp'],
59-
$queries['sw-version'],
66+
$queries['timestamp'] ?? null,
67+
$queries['sw-version'] ?? null,
6068
);
6169

6270
if (array_key_exists('sw-context-language', $queries) && array_key_exists('sw-context-language', $queries)) {

tests/AdminAuthenticatorTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
use Vin\ShopwareSdk\Data\AccessToken;
1717
use Vin\ShopwareSdk\Exception\AuthorizationFailedException;
1818

19+
/**
20+
* @covers \Vin\ShopwareSdk\Client\AdminAuthenticator
21+
*/
1922
class AdminAuthenticatorTest extends TestCase
2023
{
2124
private AdminAuthenticator $authenticator;

tests/CriteriaTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
use Vin\ShopwareSdk\Data\Filter\SuffixFilter;
2727
use Vin\ShopwareSdk\Data\ScoreQuery\ScoreQuery;
2828

29+
/**
30+
* @covers \Vin\ShopwareSdk\Data\Criteria
31+
*/
2932
class CriteriaTest extends TestCase
3033
{
3134
public function testCriteriaParsed(): void

tests/Data/Response/ActionButtonResponseTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
use Vin\ShopwareSdk\Data\Response\OpenNewTabResponse;
1313
use Vin\ShopwareSdk\Data\Response\ReloadDataResponse;
1414

15+
/**
16+
* @covers \Vin\ShopwareSdk\Data\Response\ActionButtonResponse
17+
*/
1518
class ActionButtonResponseTest extends TestCase
1619
{
1720
public function testEmptyResponsestEmptyResponse(): void

tests/Data/Response/RegistrationResponseTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
use Vin\ShopwareSdk\Data\Webhook\Shop;
1010
use Vin\ShopwareSdk\Data\Webhook\ShopRegistrationResult;
1111

12+
/**
13+
* @covers \Vin\ShopwareSdk\Data\Response\RegistrationResponse
14+
*/
1215
class RegistrationResponseTest extends TestCase
1316
{
1417
public function testResponse(): void

tests/EntityHydratorTest.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Vin\ShopwareSdkTest;
6+
7+
use GuzzleHttp\Handler\MockHandler;
8+
use GuzzleHttp\HandlerStack;
9+
use PHPUnit\Framework\TestCase;
10+
use Vin\ShopwareSdk\Data\AccessToken;
11+
use Vin\ShopwareSdk\Data\Context;
12+
use Vin\ShopwareSdk\Data\Entity\EntityCollection;
13+
use Vin\ShopwareSdk\Data\Entity\Product\ProductCollection;
14+
use Vin\ShopwareSdk\Data\Entity\Product\ProductDefinition;
15+
use Vin\ShopwareSdk\Data\Entity\Product\ProductEntity;
16+
use Vin\ShopwareSdk\Data\Uuid\Uuid;
17+
use Vin\ShopwareSdk\Factory\RepositoryFactory;
18+
use Vin\ShopwareSdk\Hydrate\EntityHydrator;
19+
use Vin\ShopwareSdk\Client\Client;
20+
21+
/**
22+
* @covers \Vin\ShopwareSdk\Hydrate\EntityHydrator
23+
*/
24+
class EntityHydratorTest extends TestCase
25+
{
26+
private EntityHydrator $entityHydrator;
27+
private MockHandler $mock;
28+
private Context $context;
29+
30+
protected function setUp(): void
31+
{
32+
$this->context = new Context('http://test.com', new AccessToken('mock-token'));
33+
$this->mock = new MockHandler();
34+
35+
$handlerStack = HandlerStack::create($this->mock);
36+
37+
$client = Client::create(['handler' => $handlerStack]);
38+
39+
$this->entityHydrator = new EntityHydrator(false);
40+
$this->productRepository = RepositoryFactory::create(ProductDefinition::ENTITY_NAME);
41+
42+
$this->productRepository->setHttpClient($client);
43+
}
44+
45+
public function testHydrateSearchResultWithEmptyResult(): void
46+
{
47+
$result = $this->entityHydrator->hydrateSearchResult([], $this->context);
48+
49+
static::assertInstanceOf(EntityCollection::class, $result);
50+
51+
$result = $this->entityHydrator->hydrateSearchResult([], $this->context, 'product');
52+
53+
static::assertInstanceOf(ProductCollection::class, $result);
54+
}
55+
56+
public function testHydrateSearchResultWithResult(): void
57+
{
58+
$productId = Uuid::randomHex();
59+
$result = $this->entityHydrator->hydrateSearchResult([
60+
'data' => [
61+
[
62+
'attributes' => [
63+
'name' => 'Test Product',
64+
],
65+
'type' => 'product',
66+
'id' => $productId,
67+
]
68+
],
69+
], $this->context, 'product');
70+
71+
static::assertInstanceOf(ProductCollection::class, $result);
72+
static::assertCount(1, $result);
73+
static::assertInstanceOf(ProductEntity::class, $result->get($productId));
74+
}
75+
}

tests/EntityRepositoryTest.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
use Vin\ShopwareSdk\Repository\Struct\IdSearchResult;
3030
use Vin\ShopwareSdk\Client\Client;
3131

32+
/**
33+
* @covers \Vin\ShopwareSdk\Repository\EntityRepository
34+
*/
3235
class EntityRepositoryTest extends TestCase
3336
{
3437
private EntityRepository $productRepository;
@@ -49,7 +52,7 @@ protected function setUp(): void
4952
$this->productRepository->setHttpClient($client);
5053
}
5154

52-
public function testBadResponse(): void
55+
public function testSearchBadResponse(): void
5356
{
5457
static::expectException(ShopwareResponseException::class);
5558
static::expectExceptionMessage('Unauthenticated');
@@ -136,6 +139,17 @@ public function testSearchIds(): void
136139
static::assertEquals(69, $result->getTotal());
137140
}
138141

142+
public function testSearchShouldThrowShopwareHttpException(): void
143+
{
144+
static::expectException(ShopwareResponseException::class);
145+
static::expectExceptionMessage('Unauthenticated');
146+
static::expectExceptionCode(401);
147+
148+
$this->mock->append(new BadResponseException('Unauthenticated', new Request('POST', 'test'), new Response(401, [], 'Unauthenticated')));
149+
150+
$this->productRepository->searchIds(new Criteria(), $this->context);
151+
}
152+
139153
public function testCreateNew(): void
140154
{
141155
$this->mock->append(new Response(200, [], file_get_contents(__DIR__ . '/stubs/product-ids.json')));

tests/GrantTypeTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
use Vin\ShopwareSdk\Client\GrantType\ClientCredentialsGrantType;
1111
use Vin\ShopwareSdk\Client\GrantType\RefreshTokenGrantType;
1212

13+
/**
14+
* @covers \Vin\ShopwareSdk\Client\GrantType\GrantType
15+
*/
1316
class GrantTypeTest extends TestCase
1417
{
1518
public function testCreateFromInvalidConfig(): void

tests/InfoServiceTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
use Vin\ShopwareSdk\Data\Schema\Schema;
1111
use Vin\ShopwareSdk\Service\InfoService;
1212

13+
/**
14+
* @covers \Vin\ShopwareSdk\Service\InfoService
15+
*/
1316
class InfoServiceTest extends TestCase
1417
{
1518
public function testGetSchema(): void

tests/RepositoryFactoryTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
use Vin\ShopwareSdk\Factory\RepositoryFactory;
2020
use Vin\ShopwareSdk\Repository\EntityRepository;
2121

22+
/**
23+
* @covers \Vin\ShopwareSdk\Factory\RepositoryFactory
24+
*/
2225
class RepositoryFactoryTest extends TestCase
2326
{
2427
public function testCreateEntity(): void

0 commit comments

Comments
 (0)