Skip to content

Commit 7512ea0

Browse files
committed
Add tests
1 parent d2fc0be commit 7512ea0

22 files changed

+787
-57
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/vendor/
22
/var/*
33
.idea
4+
.phpunit.result.cache

composer.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
"Vin\\ShopwareSdk\\": "src"
3030
}
3131
},
32+
"autoload-dev": {
33+
"psr-4": {
34+
"Vin\\ShopwareSdk\\": "tests/"
35+
}
36+
},
3237
"scripts": {
3338
"ecs": "vendor/bin/ecs check src",
3439
"check-style": "phpcs src",

phpunit.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<phpunit bootstrap="vendor/autoload.php" colors="true">
4+
<testsuites>
5+
<testsuite name="Shopware SDK Test Suite">
6+
<directory>./tests/</directory>
7+
</testsuite>
8+
</testsuites>
9+
10+
<php>
11+
<ini name="date.timezone" value="UTC"/>
12+
</php>
13+
</phpunit>

script/src/CodeGenerator.php

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,6 @@ private static function generateDefinitionClass(string $entityNamespace, string
125125
->setDocblock($docblock);
126126
$foo->addUse(EntityDefinition::class);
127127

128-
// $foo->addUse('Vin\ShopwareSdk\Data\Entity\\' . $entityName . '\\' . $entityName . 'Entity');
129-
// $foo->addUse('Vin\ShopwareSdk\Data\Entity\\' . $entityName . '\\' . $entityName . 'Collection');
130-
131128
$foo->getMethod('getEntityClass')->setBody('return ' . $entityName . 'Entity::class;');
132129
$foo->getMethod('getEntityCollection')->setBody('return ' . $entityName . 'Collection::class;');
133130

@@ -173,26 +170,25 @@ private static function getTypedProperty(string $entityNamespace, string $entity
173170
return $prefix . $refClass;
174171
}
175172

176-
if ($property->type === 'int') {
177-
return $prefix . 'int';
178-
}
179-
180-
if ($property->type === 'float') {
181-
return $prefix . 'float';
182-
}
183-
184-
if ($property->type === 'boolean' || $property->type === 'bool') {
185-
return $prefix . 'bool';
186-
}
187-
188-
if ($property->type === 'date') {
189-
return $prefix . \DateTimeInterface::class;
190-
}
191-
192173
if ($property->isJsonField()) {
193174
return $prefix . 'array';
194175
}
195-
196-
return null;
176+
177+
switch ($property->type) {
178+
case 'bool':
179+
case 'float':
180+
case 'int': {
181+
return $prefix . $property->type;
182+
}
183+
case 'boolean': {
184+
return $prefix . 'bool';
185+
}
186+
case 'date': {
187+
return $prefix . \DateTimeInterface::class;
188+
}
189+
default: {
190+
return null;
191+
}
192+
}
197193
}
198194
}

src/Client/AdminAuthenticator.php

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -61,42 +61,29 @@ public function fetchAccessToken(): AccessToken
6161

6262
$tokenPayload = \json_decode($response, true) ?? [];
6363

64-
if ($this->isTokenExpired($tokenPayload['access_token'])) {
65-
return $this->refreshToken();
64+
if (empty($tokenPayload['access_token'])) {
65+
throw new AuthorizationFailedException('Access token is invalid format', 401);
6666
}
6767

68-
return new AccessToken(
68+
$callback = $this->tokenCallback;
69+
70+
$token = new AccessToken(
6971
$tokenPayload['access_token'],
70-
$tokenPayload['expires_in'],
71-
$tokenPayload['token_type'],
72+
$tokenPayload['expires_in'] ?? 600,
73+
$tokenPayload['token_type'] ?? null,
7274
$tokenPayload['refresh_token'] ?? null
7375
);
74-
}
75-
76-
public function setTokenCallback(callable $callback): void
77-
{
78-
$this->tokenCallback = $callback;
79-
}
80-
81-
public function refreshToken(): AccessToken
82-
{
83-
$response = $this->fetchAccessToken();
84-
85-
$callback = $this->tokenCallback;
8676

8777
if ($callback && is_callable($callback)) {
88-
$callback($response);
78+
$callback($token, $tokenPayload);
8979
}
9080

91-
return $response;
81+
return $token;
9282
}
9383

94-
public function isTokenExpired(string $accessToken) : bool
84+
public function setTokenCallback(callable $callback): void
9585
{
96-
$payload = json_decode(base64_decode(explode('.', $accessToken)[1]), true);
97-
$expiresAt = $payload['exp'];
98-
99-
return $expiresAt + $this->config['sec_before_refresh'] * 1000 < time();
86+
$this->tokenCallback = $callback;
10087
}
10188

10289
private function buildFormParams(): array

src/Client/GrantType/GrantType.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function __construct(string $grantType, string $clientId)
2929
$this->clientId = $clientId;
3030
}
3131

32-
public static function createFromConfig(array $config): self
32+
public static function createFromConfig(array $config): GrantType
3333
{
3434
if (empty($config['grant_type'])) {
3535
throw new \InvalidArgumentException('Grant type is not provided in the config', 400);
@@ -45,7 +45,7 @@ public static function createFromConfig(array $config): self
4545
return new ClientCredentialsGrantType($config['client_id'], $config['client_secret']);
4646
}
4747
case self::PASSWORD: {
48-
return new PasswordGrantType($config['username'], $config['password'], $config['scopes']);
48+
return new PasswordGrantType($config['username'], $config['password'], $config['scopes'] ?? 'write');
4949
}
5050
default: {
5151
throw new \InvalidArgumentException('Grant type ' . $grantType . ' is not supported', 400);

src/Data/AccessToken.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,12 @@ public function __construct(string $accessToken, int $expiresIn = 600, string $t
1919
$this->tokenType = $tokenType;
2020
$this->refreshToken = $refreshToken;
2121
}
22+
23+
public function isExpired() : bool
24+
{
25+
$payload = json_decode(base64_decode(explode('.', $this->accessToken)[1]), true);
26+
$expiresAt = $payload['exp'];
27+
28+
return $expiresAt * 1000 < time();
29+
}
2230
}

src/Data/Criteria.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,21 @@
2020

2121
class Criteria implements ParseAware
2222
{
23+
/**
24+
* no total count will be selected. Should be used if no pagination required (fastest)
25+
*/
26+
public const TOTAL_COUNT_MODE_NONE = 0;
27+
28+
/**
29+
* exact total count will be selected. Should be used if an exact pagination is required (slow)
30+
*/
31+
public const TOTAL_COUNT_MODE_EXACT = 1;
32+
33+
/**
34+
* fetches limit * 5 + 1. Should be used if pagination can work with "next page exists" (fast)
35+
*/
36+
public const TOTAL_COUNT_MODE_NEXT_PAGES = 2;
37+
2338
private int $page;
2439

2540
private int $limit;

src/Data/Filter/Filter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
abstract class Filter implements ParseAware
1010
{
11-
public const TYPE_MULTI = 'prefix';
11+
public const TYPE_MULTI = 'multi';
1212

1313
public const TYPE_PREFIX = 'prefix';
1414

src/Factory/RepositoryFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ private static function getDefinition(string $entity): EntityDefinition
3131
}
3232

3333
if (!array_key_exists($entity, self::$mapping)) {
34-
throw new \Exception('Definition not found for Entity ' . $entity);
34+
throw new \Exception('Definition not found for Entity: ' . $entity);
3535
}
3636

3737
$definitionClass = self::$mapping[$entity];

src/Repository/EntityRepository.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,11 @@ public function search(Criteria $criteria, Context $context): EntitySearchResult
7979

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

82-
$result = $this->hydrateSearchResult($response, $context);
82+
$entities = $this->hydrateSearchResult($response, $context);
8383

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

86-
return new EntitySearchResult($this->entityName, $meta, $result, $aggregations, $criteria, $context);
86+
return new EntitySearchResult($this->entityName, $meta, $entities, $aggregations, $criteria, $context);
8787
}
8888

8989
public function searchIds(Criteria $criteria, Context $context): IdSearchResult

src/Repository/Struct/IdSearchResult.php

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88

99
class IdSearchResult
1010
{
11-
public int $total;
11+
private int $total;
1212

13-
public Criteria $criteria;
13+
private Criteria $criteria;
1414

15-
public Context $context;
15+
private Context $context;
1616

17-
public array $ids = [];
17+
private array $ids = [];
1818

19-
public array $data = [];
19+
private array $data = [];
2020

2121
public function __construct(int $total, array $ids, Criteria $criteria, Context $context)
2222
{
@@ -27,6 +27,56 @@ public function __construct(int $total, array $ids, Criteria $criteria, Context
2727
$this->context = $context;
2828
}
2929

30+
public function getTotal(): int
31+
{
32+
return $this->total;
33+
}
34+
35+
public function setTotal(int $total): void
36+
{
37+
$this->total = $total;
38+
}
39+
40+
public function getCriteria(): Criteria
41+
{
42+
return $this->criteria;
43+
}
44+
45+
public function setCriteria(Criteria $criteria): void
46+
{
47+
$this->criteria = $criteria;
48+
}
49+
50+
public function getContext(): Context
51+
{
52+
return $this->context;
53+
}
54+
55+
public function setContext(Context $context): void
56+
{
57+
$this->context = $context;
58+
}
59+
60+
public function getIds(): array
61+
{
62+
return $this->ids;
63+
}
64+
65+
public function setIds(array $ids): void
66+
{
67+
$this->ids = $ids;
68+
}
69+
70+
public function getData(): array
71+
{
72+
return $this->data;
73+
}
74+
75+
public function setData(array $data): void
76+
{
77+
$this->data = $data;
78+
}
79+
3080
public function firstId(): ?string
3181
{
3282
if (empty($this->ids)) {

src/Repository/Traits/EntityHydrator.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,14 @@ private function hydrateSearchResult(array $response, Context $context): EntityC
3434
$entities[$entity->id] = $entity;
3535
}
3636

37-
return new EntityCollection($entities);
37+
$collectionClass = EntityCollection::class;
38+
39+
if (!empty($response['data'][0]['type'])) {
40+
$repository = RepositoryFactory::create($response['data'][0]['type']);
41+
$collectionClass = $repository->getDefinition()->getEntityCollection();
42+
}
43+
44+
return new $collectionClass($entities);
3845
}
3946

4047
private function hydrateEntity(string $entityName, array $entityRaw, array $data, Context $context): Entity

0 commit comments

Comments
 (0)