Skip to content

Commit dc12154

Browse files
committed
Refactored the API endpoints and client
1 parent 65829b4 commit dc12154

File tree

141 files changed

+3501
-1353
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

141 files changed

+3501
-1353
lines changed

composer.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
},
2121
"autoload-dev": {
2222
"psr-4": {
23+
"spec\\Diglin\\Sylius\\ApiClient\\": "spec/",
2324
"Diglin\\Sylius\\ApiClient\\tests\\": "tests/"
2425
}
2526
},
@@ -33,12 +34,13 @@
3334
"php-http/message-factory": "^v1.0",
3435
"php-http/multipart-stream-builder": "^1.0",
3536
"php-http/client-implementation": "^1.0",
36-
"symfony/expression-language": "^3.0|^4.0|^5.0"
37+
"symfony/expression-language": "^3.0|^4.0|^5.0",
38+
"webmozart/assert": "^1.10"
3739
},
3840
"require-dev": {
3941
"friendsofphp/php-cs-fixer": "^2.14",
40-
"phpunit/phpunit": "^5.7",
41-
"phpspec/phpspec": "^5.0",
42+
"phpunit/phpunit": "^9.0",
43+
"phpspec/phpspec": "^7.1",
4244
"symfony/yaml": "^4.2",
4345
"donatj/mock-webserver": "^2.0",
4446
"php-http/guzzle6-adapter": "^2.0"

spec/Api/AuthenticationApiSpec.php renamed to spec/Api/Legacy/AuthenticationApiSpec.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?php
22

3-
namespace spec\Diglin\Sylius\ApiClient\Api;
3+
namespace spec\Diglin\Sylius\ApiClient\Api\Legacy;
44

5-
use Diglin\Sylius\ApiClient\Api\AuthenticationApi;
6-
use Diglin\Sylius\ApiClient\Api\AuthenticationApiInterface;
5+
use Diglin\Sylius\ApiClient\Api\Legacy\AuthenticationApi;
6+
use Diglin\Sylius\ApiClient\Api\Legacy\AuthenticationApiInterface;
77
use Diglin\Sylius\ApiClient\Client\HttpClient;
88
use Diglin\Sylius\ApiClient\Routing\UriGeneratorInterface;
99
use PhpSpec\ObjectBehavior;

spec/Client/AuthenticatedHttpClientSpec.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace spec\Diglin\Sylius\ApiClient\Client;
44

5-
use Diglin\Sylius\ApiClient\Api\AuthenticationApiInterface;
5+
use Diglin\Sylius\ApiClient\Api\Authentication\AuthenticationApiInterface;
66
use Diglin\Sylius\ApiClient\Client\AuthenticatedHttpClient;
77
use Diglin\Sylius\ApiClient\Client\HttpClient;
88
use Diglin\Sylius\ApiClient\Client\HttpClientInterface;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
<?php
2+
3+
namespace spec\Diglin\Sylius\ApiClient\Client;
4+
5+
use Diglin\Sylius\ApiClient\Api\Legacy\AuthenticationApiInterface;
6+
use Diglin\Sylius\ApiClient\Client\HttpClient;
7+
use Diglin\Sylius\ApiClient\Client\HttpClientInterface;
8+
use Diglin\Sylius\ApiClient\Client\LegacyAuthenticatedHttpClient;
9+
use Diglin\Sylius\ApiClient\Exception\UnauthorizedHttpException;
10+
use Diglin\Sylius\ApiClient\Security\LegacyAuthentication;
11+
use PhpSpec\ObjectBehavior;
12+
use Psr\Http\Message\ResponseInterface;
13+
14+
class LegacyAuthenticatedHttpClientSpec extends ObjectBehavior
15+
{
16+
public function let(
17+
HttpClient $httpClient,
18+
AuthenticationApiInterface $authenticationApi,
19+
LegacyAuthentication $authentication
20+
) {
21+
$this->beConstructedWith($httpClient, $authenticationApi, $authentication);
22+
}
23+
24+
public function it_is_initializable()
25+
{
26+
$this->shouldHaveType(LegacyAuthenticatedHttpClient::class);
27+
$this->shouldImplement(HttpClientInterface::class);
28+
}
29+
30+
public function it_sends_an_authenticated_and_successful_request_when_access_token_is_defined(
31+
$httpClient,
32+
$authentication,
33+
ResponseInterface $response
34+
) {
35+
$authentication->getXauthtokenHeader()->willReturn(null);
36+
$authentication->getAccessToken()->willReturn('bar');
37+
38+
$httpClient->sendRequest(
39+
'POST',
40+
'http://diglin.com/api/rest/v1/products/foo',
41+
['Content-Type' => 'application/json', 'Authorization' => 'Bearer bar'],
42+
'{"identifier": "foo"}'
43+
)->willReturn($response);
44+
45+
$this->sendRequest(
46+
'POST',
47+
'http://diglin.com/api/rest/v1/products/foo',
48+
['Content-Type' => 'application/json'],
49+
'{"identifier": "foo"}'
50+
)->shouldReturn($response);
51+
}
52+
53+
public function it_sends_an_authenticated_and_successful_request_at_first_call(
54+
$httpClient,
55+
$authenticationApi,
56+
$authentication,
57+
ResponseInterface $response
58+
) {
59+
$authentication->getXauthtokenHeader()->willReturn(null);
60+
$authentication->getClientId()->willReturn('client_id');
61+
$authentication->getSecret()->willReturn('secret');
62+
$authentication->getUsername()->willReturn('julia');
63+
$authentication->getPassword()->willReturn('julia_pwd');
64+
$authentication->getAccessToken()->willReturn(null, 'foo');
65+
66+
$authenticationApi
67+
->authenticateByPassword('client_id', 'secret', 'julia', 'julia_pwd')
68+
->willReturn([
69+
'access_token' => 'foo',
70+
'expires_in' => 3600,
71+
'token_type' => 'bearer',
72+
'scope' => null,
73+
'refresh_token' => 'bar',
74+
])
75+
;
76+
77+
$authentication
78+
->setAccessToken('foo')
79+
->shouldBeCalled()
80+
->willReturn($authentication)
81+
;
82+
83+
$authentication
84+
->setRefreshToken('bar')
85+
->shouldBeCalled()
86+
->willReturn($authentication)
87+
;
88+
89+
$httpClient->sendRequest(
90+
'POST',
91+
'http://diglin.com/api/rest/v1/products/foo',
92+
['Content-Type' => 'application/json', 'Authorization' => 'Bearer foo'],
93+
'{"identifier": "foo"}'
94+
)->willReturn($response);
95+
96+
$this->sendRequest(
97+
'POST',
98+
'http://diglin.com/api/rest/v1/products/foo',
99+
['Content-Type' => 'application/json'],
100+
'{"identifier": "foo"}'
101+
)->shouldReturn($response);
102+
}
103+
104+
public function it_sends_an_authenticated_and_successful_request_when_access_token_expired(
105+
$httpClient,
106+
$authenticationApi,
107+
$authentication,
108+
ResponseInterface $response
109+
) {
110+
$authentication->getXauthtokenHeader()->willReturn(null);
111+
$authentication->getClientId()->willReturn('client_id');
112+
$authentication->getSecret()->willReturn('secret');
113+
$authentication->getUsername()->willReturn('julia');
114+
$authentication->getPassword()->willReturn('julia_pwd');
115+
$authentication->getAccessToken()->willReturn('foo', 'foo', 'baz');
116+
$authentication->getRefreshToken()->willReturn('bar');
117+
118+
$httpClient->sendRequest(
119+
'POST',
120+
'http://diglin.com/api/rest/v1/products/foo',
121+
['Content-Type' => 'application/json', 'Authorization' => 'Bearer foo'],
122+
'{"identifier": "foo"}'
123+
)->willThrow(UnauthorizedHttpException::class);
124+
125+
$authenticationApi
126+
->authenticateByRefreshToken('client_id', 'secret', 'bar')
127+
->willReturn([
128+
'access_token' => 'baz',
129+
'expires_in' => 3600,
130+
'token_type' => 'bearer',
131+
'scope' => null,
132+
'refresh_token' => 'foz',
133+
])
134+
;
135+
136+
$authentication
137+
->setAccessToken('baz')
138+
->shouldBeCalled()
139+
->willReturn($authentication)
140+
;
141+
142+
$authentication
143+
->setRefreshToken('foz')
144+
->shouldBeCalled()
145+
->willReturn($authentication)
146+
;
147+
148+
$httpClient->sendRequest(
149+
'POST',
150+
'http://diglin.com/api/rest/v1/products/foo',
151+
['Content-Type' => 'application/json', 'Authorization' => 'Bearer baz'],
152+
'{"identifier": "foo"}'
153+
)->willReturn($response);
154+
155+
$this->sendRequest(
156+
'POST',
157+
'http://diglin.com/api/rest/v1/products/foo',
158+
['Content-Type' => 'application/json'],
159+
'{"identifier": "foo"}'
160+
);
161+
}
162+
}

spec/Client/ResourceClientSpec.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public function it_returns_a_page_when_requesting_a_list_of_resources(
105105
->willReturn(json_encode($resources))
106106
;
107107

108-
$this->getResources('api/rest/v1/categories', [], 10, ['foo' => 'bar'])->shouldReturn($resources);
108+
$this->getResources('api/rest/v1/categories', [], 10, ['foo' => 'bar', 'with_count' => true])->shouldReturn($resources);
109109
}
110110

111111
public function it_returns_a_list_of_resources_without_limit_and_count(

spec/Pagination/PageFactorySpec.php

+9-8
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
use Diglin\Sylius\ApiClient\Pagination\Page;
77
use Diglin\Sylius\ApiClient\Pagination\PageFactory;
88
use Diglin\Sylius\ApiClient\Pagination\PageFactoryInterface;
9+
use Diglin\Sylius\ApiClient\Routing\UriGeneratorInterface;
910
use PhpSpec\ObjectBehavior;
1011

1112
class PageFactorySpec extends ObjectBehavior
1213
{
13-
public function let(HttpClientInterface $httpClient)
14+
public function let(HttpClientInterface $httpClient, UriGeneratorInterface $uriGenerator)
1415
{
15-
$this->beConstructedWith($httpClient);
16+
$this->beConstructedWith($httpClient, $uriGenerator);
1617
}
1718

1819
public function it_is_initializable()
@@ -21,7 +22,7 @@ public function it_is_initializable()
2122
$this->shouldImplement(PageFactoryInterface::class);
2223
}
2324

24-
public function it_creates_a_page_with_all_links($httpClient)
25+
public function it_creates_a_page_with_all_links($httpClient, $uriGenerator)
2526
{
2627
$data = [
2728
'_links' => [
@@ -50,7 +51,7 @@ public function it_creates_a_page_with_all_links($httpClient)
5051
$this->createPage($data)->shouldReturnAnInstanceOf(Page::class);
5152
$this->createPage($data)->shouldBeLike(
5253
new Page(
53-
new PageFactory($httpClient->getWrappedObject()),
54+
new PageFactory($httpClient->getWrappedObject(), $uriGenerator->getWrappedObject()),
5455
$httpClient->getWrappedObject(),
5556
'http://diglin.com/first',
5657
'http://diglin.com/previous',
@@ -64,7 +65,7 @@ public function it_creates_a_page_with_all_links($httpClient)
6465
);
6566
}
6667

67-
public function it_creates_a_page_without_next_and_previous_links($httpClient)
68+
public function it_creates_a_page_without_next_and_previous_links($httpClient, $uriGenerator)
6869
{
6970
$data = [
7071
'_links' => [
@@ -87,7 +88,7 @@ public function it_creates_a_page_without_next_and_previous_links($httpClient)
8788
$this->createPage($data)->shouldReturnAnInstanceOf(Page::class);
8889
$this->createPage($data)->shouldBeLike(
8990
new Page(
90-
new PageFactory($httpClient->getWrappedObject()),
91+
new PageFactory($httpClient->getWrappedObject(), $uriGenerator->getWrappedObject()),
9192
$httpClient->getWrappedObject(),
9293
'http://diglin.com/first',
9394
null,
@@ -101,7 +102,7 @@ public function it_creates_a_page_without_next_and_previous_links($httpClient)
101102
);
102103
}
103104

104-
public function it_creates_a_page_without_count($httpClient)
105+
public function it_creates_a_page_without_count($httpClient, $uriGenerator)
105106
{
106107
$data = [
107108
'_links' => [
@@ -129,7 +130,7 @@ public function it_creates_a_page_without_count($httpClient)
129130
$this->createPage($data)->shouldReturnAnInstanceOf(Page::class);
130131
$this->createPage($data)->shouldBeLike(
131132
new Page(
132-
new PageFactory($httpClient->getWrappedObject()),
133+
new PageFactory($httpClient->getWrappedObject(), $uriGenerator->getWrappedObject()),
133134
$httpClient->getWrappedObject(),
134135
'http://diglin.com/first',
135136
'http://diglin.com/previous',

spec/Routing/UriGeneratorSpec.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public function it_generates_uri_having_search_parameter_encoded_in_json()
8585

8686
$this
8787
->generate('/api', [], $queryParameters)
88-
->shouldReturn(static::BASE_URI.'api?search=%7B%22categories%22%3A%5B%7B%22operator%22%3A%22IN%22%2C%22value%22%3A%22master%22%7D%5D%7D')
88+
->shouldReturn(static::BASE_URI.'api?search%5Bcategories%5D%5B0%5D%5Boperator%5D=IN&search%5Bcategories%5D%5B0%5D%5Bvalue%5D=master')
8989
;
9090
}
9191
}

spec/Security/AuthenticationSpec.php renamed to spec/Security/LegacyAuthenticationSpec.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44

55
use PhpSpec\ObjectBehavior;
66

7-
class AuthenticationSpec extends ObjectBehavior
7+
class LegacyAuthenticationSpec extends ObjectBehavior
88
{
99
public function it_is_initializable_from_a_password()
1010
{
1111
$this->beConstructedThrough('fromPassword', ['client_id', 'secret', 'Julia', 'Julia_pwd']);
12-
$this->shouldHaveType('Diglin\Sylius\ApiClient\Security\Authentication');
12+
$this->shouldHaveType('Diglin\Sylius\ApiClient\Security\LegacyAuthentication');
1313

1414
$this->getUsername()->shouldReturn('Julia');
1515
$this->getPassword()->shouldReturn('Julia_pwd');
@@ -20,7 +20,7 @@ public function it_is_initializable_from_a_password()
2020
public function it_is_initializable_from_a_token()
2121
{
2222
$this->beConstructedThrough('fromToken', ['client_id', 'secret', 'token', 'refresh_token']);
23-
$this->shouldHaveType('Diglin\Sylius\ApiClient\Security\Authentication');
23+
$this->shouldHaveType('Diglin\Sylius\ApiClient\Security\LegacyAuthentication');
2424

2525
$this->getClientId()->shouldReturn('client_id');
2626
$this->getSecret()->shouldReturn('secret');

spec/SyliusClientSpec.php renamed to spec/SyliusLegacyClientSpec.php

+8-8
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
namespace spec\Diglin\Sylius\ApiClient;
44

5-
use Diglin\Sylius\ApiClient\Api;
6-
use Diglin\Sylius\ApiClient\Security\Authentication;
7-
use Diglin\Sylius\ApiClient\SyliusClient;
8-
use Diglin\Sylius\ApiClient\SyliusClientInterface;
5+
use Diglin\Sylius\ApiClient\Api\Legacy as Api;
6+
use Diglin\Sylius\ApiClient\Security\LegacyAuthentication;
7+
use Diglin\Sylius\ApiClient\SyliusLegacyClient;
8+
use Diglin\Sylius\ApiClient\SyliusLegacyClientInterface;
99
use PhpSpec\ObjectBehavior;
1010

11-
class SyliusClientSpec extends ObjectBehavior
11+
class SyliusLegacyClientSpec extends ObjectBehavior
1212
{
1313
public function let(
14-
Authentication $authentication,
14+
LegacyAuthentication $authentication,
1515
Api\CartsApiInterface $cartsApi,
1616
Api\ChannelsApiInterface $channelsApi,
1717
Api\CountriesApiInterface $countriesApi,
@@ -70,8 +70,8 @@ public function let(
7070

7171
public function it_is_initializable()
7272
{
73-
$this->shouldImplement(SyliusClientInterface::class);
74-
$this->shouldHaveType(SyliusClient::class);
73+
$this->shouldImplement(SyliusLegacyClientInterface::class);
74+
$this->shouldHaveType(SyliusLegacyClient::class);
7575
}
7676

7777
public function it_gets_access_token($authentication)

src/Api/Admin/AddressApi.php

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Diglin\Sylius\ApiClient\Api\Admin;
4+
5+
use Diglin\Sylius\ApiClient\Client\ResourceClientInterface;
6+
use Webmozart\Assert\Assert;
7+
8+
final class AddressApi implements AddressApiInterface
9+
{
10+
public function __construct(
11+
private ResourceClientInterface $resourceClient,
12+
) {}
13+
14+
public function get($code): array
15+
{
16+
Assert::integer($code);
17+
return $this->resourceClient->getResource('api/v2/admin/addresses/%d', [$code]);
18+
}
19+
}

src/Api/Admin/AddressApiInterface.php

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Diglin\Sylius\ApiClient\Api\Admin;
4+
5+
use Diglin\Sylius\ApiClient\Api\Operation\GettableResourceInterface;
6+
7+
interface AddressApiInterface extends GettableResourceInterface
8+
{
9+
}

0 commit comments

Comments
 (0)