diff --git a/src/Api/Catalog/InventoryDomain.php b/src/Api/Catalog/InventoryDomain.php index dde4101..10b38e0 100644 --- a/src/Api/Catalog/InventoryDomain.php +++ b/src/Api/Catalog/InventoryDomain.php @@ -1,20 +1,19 @@ link->get([], ['query' => ['reference' => $reference]]); - if ($resource->getProperty('count') > 0) { - return new ApiCatalog\InventoryResource( + if ($resource && $resource->getProperty('count') > 0) { + return new InventoryResource( $resource->getFirstResource('inventory'), false ); diff --git a/src/Api/Order/OrderDomain.php b/src/Api/Order/OrderDomain.php index 7f7a254..67d762b 100644 --- a/src/Api/Order/OrderDomain.php +++ b/src/Api/Order/OrderDomain.php @@ -1,21 +1,21 @@ resource->getFirstResource('account')) { + return $account->getProperty('id'); + } + + return null; + } + + /** + * @return array A list of named roles + */ + public function getRoles() + { + return $this->getProperty('roles') ?: []; + } + /** * @return string */ public function getLogin() { - return $this->resource->getProperty('login'); + return (string) $this->resource->getProperty('login'); } /** @@ -19,7 +39,7 @@ public function getLogin() */ public function getEmail() { - return $this->resource->getProperty('email'); + return (string) $this->resource->getProperty('email'); } /** @@ -27,11 +47,11 @@ public function getEmail() */ public function getToken() { - return $this->resource->getProperty('token'); + return (string) $this->resource->getProperty('token'); } /** - * @return Store\StoreCollection + * @return Store\StoreCollection|Store\StoreResource[] */ public function getStores() { @@ -40,6 +60,21 @@ public function getStores() ); } + /** + * Return the language tag, as following: + * + * - en_US + * - fr_FR + * + * ...etc + * + * @return string + */ + public function getLanguageTag() + { + return (string) $this->resource->getProperty('language'); + } + /** * @param int|string $idOrName * diff --git a/src/Api/Store/StoreChannelDomain.php b/src/Api/Store/StoreChannelDomain.php index cb5222e..63ff4a2 100644 --- a/src/Api/Store/StoreChannelDomain.php +++ b/src/Api/Store/StoreChannelDomain.php @@ -8,6 +8,7 @@ * @method StoreChannelResource[] getAll($criteria = []) * @method StoreChannelResource[] getPage(array $criteria = []) * @method StoreChannelResource[] getPages(array $criteria = []) + * @method StoreChannelResource getOne($identity) */ class StoreChannelDomain extends Resource\AbstractDomainResource { diff --git a/src/Api/Store/StoreChannelResource.php b/src/Api/Store/StoreChannelResource.php index 5386853..63d989a 100644 --- a/src/Api/Store/StoreChannelResource.php +++ b/src/Api/Store/StoreChannelResource.php @@ -66,7 +66,9 @@ public function isInstalled() public function getChannel() { if (null === $this->channel) { - $this->channel = new Channel\ChannelResource($this->resource->getFirstResource('channel')); + $this->channel = new Channel\ChannelResource( + $this->resource->getFirstResource('channel') + ); } return $this->channel; diff --git a/src/Api/Store/StoreResource.php b/src/Api/Store/StoreResource.php index c686dbf..e71e6a8 100644 --- a/src/Api/Store/StoreResource.php +++ b/src/Api/Store/StoreResource.php @@ -31,6 +31,18 @@ public function isActive() return $this->getProperty('status') === 'active'; } + /** + * @return string One of the following status: + * - active + * - demo + * - deleted + * - suspended + */ + public function getStatus() + { + return $this->getProperty('status'); + } + /** * @return string */ diff --git a/src/Hal/HalLink.php b/src/Hal/HalLink.php index 83f0e8b..852d051 100644 --- a/src/Hal/HalLink.php +++ b/src/Hal/HalLink.php @@ -107,12 +107,23 @@ public function getTitle() return $this->title; } + /** + * @param $path + * + * @return HalLink + */ + public function withAddedHref($path) + { + $instance = clone $this; + $instance->href = rtrim($instance->href, '/') . '/' . ltrim($path, '/'); + + return $instance; + } + /** * @param array $variables * * @return null|string|string[] - * - * @throws \QL\UriTemplate\Exception */ public function getUri(array $variables) { diff --git a/src/Resource/AbstractDomainResource.php b/src/Resource/AbstractDomainResource.php index c9600ff..316f19a 100644 --- a/src/Resource/AbstractDomainResource.php +++ b/src/Resource/AbstractDomainResource.php @@ -25,6 +25,21 @@ public function __construct(Hal\HalLink $link) $this->link = $link; } + /** + * Get the resource by it's identity + * + * @param mixed $identity a scalar value that identity the resource + * + * @return AbstractResource + */ + public function getOne($identity) + { + $link = $this->link->withAddedHref($identity); + $class = $this->resourceClass; + + return new $class($link->get()); + } + /** * @param array $criteria * diff --git a/tests/unit/Api/AbstractResourceTest.php b/tests/unit/Api/AbstractResourceTest.php index fbe34ad..cc41010 100644 --- a/tests/unit/Api/AbstractResourceTest.php +++ b/tests/unit/Api/AbstractResourceTest.php @@ -42,7 +42,7 @@ protected function initHalResourceProperties(array $props = []) $resource = $this->initHalResource(); $resource - ->expects($this->exactly(count($props))) + ->expects($this->any()) ->method('getProperty') ->with($this->logicalOr(...array_keys($props))) ->will($this->returnCallback(function($prop) use($props) { diff --git a/tests/unit/Api/Session/SessionResourceTest.php b/tests/unit/Api/Session/SessionResourceTest.php index bf56744..786022f 100644 --- a/tests/unit/Api/Session/SessionResourceTest.php +++ b/tests/unit/Api/Session/SessionResourceTest.php @@ -12,11 +12,14 @@ class SessionResourceTest extends Sdk\Test\Api\AbstractResourceTest public function setUp() { - $this->props = [ - 'login' => 'username', - 'email' => 'user@mail.com', - 'token' => 'fd9cf7c178a1efd30bb1aad0e302abde', + $this->props = [ + 'login' => 'username', + 'email' => 'user@mail.com', + 'token' => 'fd9cf7c178a1efd30bb1aad0e302abde', + 'language' => 'en_US', + 'roles' => ['user'], ]; + $this->resources = [ $this->createMock(Sdk\Hal\HalResource::class), $this->createMock(Sdk\Hal\HalResource::class), @@ -33,6 +36,31 @@ public function testPropertiesGetters() $this->assertEquals($this->props['email'], $instance->getEmail()); $this->assertEquals($this->props['login'], $instance->getLogin()); $this->assertEquals($this->props['token'], $instance->getToken()); + $this->assertEquals($this->props['roles'], $instance->getRoles()); + $this->assertEquals($this->props['language'], $instance->getLanguageTag()); + } + + public function testGetAccountIdWithMatchedOrNullAccount() + { + $halResource = $this->createMock(Sdk\Hal\HalResource::class); + $halResource + ->expects($this->exactly(2)) + ->method('getFirstResource') + ->with('account') + ->willReturnOnConsecutiveCalls( + $halResource, + null + ); + + $halResource + ->expects($this->once()) + ->method('getProperty') + ->with('id') + ->willReturn(12); + + $instance = new Sdk\Api\Session\SessionResource($halResource); + $this->assertSame(12, $instance->getId(), 'First call resource will return mock'); + $this->assertNull($instance->getId(), 'Second resource call return NULL'); } public function testGetStores() diff --git a/tests/unit/Api/Store/StoreResourceTest.php b/tests/unit/Api/Store/StoreResourceTest.php index e3b5393..a0809e8 100644 --- a/tests/unit/Api/Store/StoreResourceTest.php +++ b/tests/unit/Api/Store/StoreResourceTest.php @@ -21,9 +21,10 @@ public function testPropertiesGetters() $instance = new Sdk\Api\Store\StoreResource($this->halResource); - $this->assertEquals($this->props['id'], $instance->getId()); - $this->assertEquals($this->props['name'], $instance->getName()); - $this->assertEquals($this->props['country'], $instance->getCountryCode()); + $this->assertSame($this->props['id'], $instance->getId()); + $this->assertSame($this->props['name'], $instance->getName()); + $this->assertSame($this->props['country'], $instance->getCountryCode()); + $this->assertSame('active', $instance->getStatus()); $this->assertTrue($instance->isActive()); } diff --git a/tests/unit/Hal/HalLinkTest.php b/tests/unit/Hal/HalLinkTest.php index 1d248be..28e46ff 100644 --- a/tests/unit/Hal/HalLinkTest.php +++ b/tests/unit/Hal/HalLinkTest.php @@ -11,11 +11,20 @@ class HalLinkTest extends TestCase { + /** + * @var \PHPUnit_Framework_MockObject_MockObject|HalClient + */ + private $client; + + public function setUp() + { + $this->client = $this->createMock(HalClient::class); + } + public function testSetters() { - $client = $this->createMock(HalClient::class); $instance = new HalLink( - $client, + $this->client, 'http://base.url', [ 'templated' => true, @@ -37,8 +46,7 @@ public function testSetters() */ public function testHttpClientCalls() { - $client = $this->createMock(HalClient::class); - $client + $this->client ->expects($this->exactly(5)) ->method('send') ->willReturn( @@ -47,7 +55,7 @@ public function testHttpClientCalls() $instance = $this ->getMockBuilder(HalLink::class) - ->setConstructorArgs([$client, 'http://base.url']) + ->setConstructorArgs([$this->client, 'http://base.url']) ->setMethods(['createRequest']) ->getMock(); @@ -67,8 +75,7 @@ public function testHttpClientCalls() public function testSend() { - $client = $this->createMock(HalClient::class); - $client + $this->client ->expects($this->once()) ->method('send') ->willReturn( @@ -77,7 +84,7 @@ public function testSend() $instance = $this ->getMockBuilder(HalLink::class) - ->setConstructorArgs([$client, 'http://base.url']) + ->setConstructorArgs([$this->client, 'http://base.url']) ->setMethods(['createRequest']) ->getMock(); @@ -88,8 +95,7 @@ public function testSend() public function testGetCreateRequest() { - $client = $this->createMock(HalClient::class); - $client + $this->client ->expects($this->once()) ->method('createRequest') ->willReturn( @@ -98,7 +104,7 @@ public function testGetCreateRequest() $instance = $this ->getMockBuilder(HalLink::class) - ->setConstructorArgs([$client, 'http://base.url']) + ->setConstructorArgs([$this->client, 'http://base.url']) ->setMethods(['getUri']) ->getMock(); @@ -112,8 +118,7 @@ public function testGetCreateRequest() public function testCreateRequestWithContent() { - $client = $this->createMock(HalClient::class); - $client + $this->client ->expects($this->exactly(3)) ->method('createRequest') ->willReturn( @@ -122,7 +127,7 @@ public function testCreateRequestWithContent() $instance = $this ->getMockBuilder(HalLink::class) - ->setConstructorArgs([$client, 'http://base.url']) + ->setConstructorArgs([$this->client, 'http://base.url']) ->setMethods(['getUri']) ->getMock(); @@ -139,8 +144,7 @@ public function testCreateRequestWithContent() public function testBatchSend() { $request = ['request']; - $client = $this->createMock(HalClient::class); - $client + $this->client ->expects($this->once()) ->method('batchSend') ->with( @@ -151,7 +155,7 @@ function ($requests) use ($request) { ) ); - $instance = new HalLink($client, 'http://base.url'); + $instance = new HalLink($this->client, 'http://base.url'); $instance->batchSend($request); } @@ -160,8 +164,7 @@ public function testBatchSendWithOption() { $request = ['request']; $options = ['test' => 'option']; - $client = $this->createMock(HalClient::class); - $client + $this->client ->expects($this->once()) ->method('batchSend') ->with( @@ -177,7 +180,7 @@ function ($config) use ($options) { ) ); - $instance = new HalLink($client, 'http://base.url'); + $instance = new HalLink($this->client, 'http://base.url'); $instance->batchSend($request, null, null, $options); } @@ -189,8 +192,7 @@ public function testBatchSendWithSuccessCallbacks() $success = function () { echo 'Success'; }; - $client = $this->createMock(HalClient::class); - $client + $this->client ->expects($this->once()) ->method('batchSend') ->with( @@ -208,7 +210,7 @@ function ($config) use ($test) { ) ); - $instance = new HalLink($client, 'http://base.url'); + $instance = new HalLink($this->client, 'http://base.url'); $instance->batchSend($request, $success, null); } @@ -220,8 +222,7 @@ public function testBatchSendWithErrorCallback() $error = function () { echo 'Error'; }; - $client = $this->createMock(HalClient::class); - $client + $this->client ->expects($this->once()) ->method('batchSend') ->with( @@ -240,17 +241,16 @@ function ($config) use ($test) { ) ); - $instance = new HalLink($client, 'http://base.url'); + $instance = new HalLink($this->client, 'http://base.url'); $instance->batchSend($request, null, $error); } public function testGetUriDefault() { - $client = $this->createMock(HalClient::class); $instance = $this ->getMockBuilder(HalLink::class) - ->setConstructorArgs([$client, 'http://base.url']) + ->setConstructorArgs([$this->client, 'http://base.url']) ->setMethods(['getHref']) ->getMock(); @@ -264,9 +264,31 @@ public function testGetUriDefault() public function testGetUriTemplated() { - $client = $this->createMock(HalClient::class); - $instance = new HalLink($client, 'http://base.url', ['templated' => true]); + $instance = new HalLink($this->client, 'http://base.url', ['templated' => true]); $this->assertInternalType('string', $instance->getUri([])); } + + /** + * @dataProvider addedHrefProvider + */ + public function testWithAddedHref($href, $added, $expected) + { + $instance = new HalLink($this->client, $href); + $this->assertSame( + $instance->withAddedHref($added)->getHref(), + $expected + ); + } + + public function addedHrefProvider() + { + return [ + ['http://base.url/v1', '12', 'http://base.url/v1/12'], + ['http://base.url/v1/', '12', 'http://base.url/v1/12'], + ['http://base.url/v1/', '/12', 'http://base.url/v1/12'], + ['http://base.url/v1', '/12', 'http://base.url/v1/12'], + ['http://base.url/v1', '/12/', 'http://base.url/v1/12/'], + ]; + } } diff --git a/tests/unit/Resource/AbstractDomainResourceTest.php b/tests/unit/Resource/AbstractDomainResourceTest.php index 3233265..888df32 100644 --- a/tests/unit/Resource/AbstractDomainResourceTest.php +++ b/tests/unit/Resource/AbstractDomainResourceTest.php @@ -2,8 +2,11 @@ namespace ShoppingFeed\Sdk\Test\Resource; use PHPUnit\Framework\TestCase; +use ShoppingFeed\Sdk\Hal; use ShoppingFeed\Sdk\Hal\HalLink; use ShoppingFeed\Sdk\Hal\HalResource; +use ShoppingFeed\Sdk\Resource\AbstractDomainResource; +use ShoppingFeed\Sdk\Resource\AbstractResource; use ShoppingFeed\Sdk\Resource\PaginatedResourceCollection; class AbstractDomainResourceTest extends TestCase @@ -155,4 +158,43 @@ private function getPaginatedResource(&$i = 0, $pageFrom = 1, $perPage = 10, $to return $resource; } + + public function testGetOneLinkToSingleResource() + { + $link = $this->createMock(HalLink::class); + $resource = $this->createMock(HalResource::class); + + $link + ->expects($this->once()) + ->method('withAddedHref') + ->with('123') + ->willReturnSelf(); + + $link + ->expects($this->once()) + ->method('get') + ->willReturn($resource); + + $instance = new AbstractDomainResourceStub($link); + $instance->resourceClass = AbstractDomainResourceResourceStub::class; + + $result = $instance->getOne('123'); + $this->assertInstanceOf(AbstractDomainResourceResourceStub::class, $result); + $this->assertSame($resource, $result->halResource); + } +} + +class AbstractDomainResourceStub extends AbstractDomainResource +{ + public $resourceClass; +} + +class AbstractDomainResourceResourceStub extends AbstractResource +{ + public $halResource; + + public function __construct(Hal\HalResource $resource) + { + $this->halResource = $resource; + } }