From 80ad77d6c2a43dcaa2816491d0de0d40294f5337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Krzaczkowski?= Date: Fri, 6 Aug 2021 12:47:22 +0200 Subject: [PATCH] feat: implement collections endpoint (#44) (#45) --- src/Client.php | 12 ++- src/Endpoint/Base.php | 10 ++ src/Endpoint/Collections.php | 149 +++++++++++++++++++++++++++++ tests/ClientTest.php | 4 + tests/CollectionsTest.php | 179 +++++++++++++++++++++++++++++++++++ 5 files changed, 353 insertions(+), 1 deletion(-) create mode 100644 src/Endpoint/Collections.php create mode 100644 tests/CollectionsTest.php diff --git a/src/Client.php b/src/Client.php index 3e73a53..916bf9a 100644 --- a/src/Client.php +++ b/src/Client.php @@ -67,6 +67,9 @@ class Client /** @var Endpoint\Send */ public $send; + /** @var Endpoint\Collections */ + public $collection; + /** * Client constructor. * @param string $apiKey Api Key @@ -88,6 +91,7 @@ public function __construct(string $apiKey, string $siteId, array $options = []) $this->activities = new Endpoint\Activities($this); $this->senderIdentities = new Endpoint\SenderIdentities($this); $this->send = new Endpoint\Send($this); + $this->collection = new Endpoint\Collections($this); $this->apiKey = $apiKey; $this->siteId = $siteId; @@ -171,6 +175,10 @@ public function get(string $endpoint, array $params = []) $response = $this->httpClient->request('GET', $apiEndpoint.$endpoint, $options); + if (isset($params['raw'])) { + return (string)$response->getBody(); + } + return $this->handleResponse($response); } @@ -235,7 +243,9 @@ protected function request(string $method, string $path, array $json): ResponseI $options = $this->getDefaultParams($apiEndpoint); $url = $apiEndpoint.$path; - $options['json'] = $json; + if (!empty($json)) { + $options['json'] = $json; + } return $this->httpClient->request($method, $url, $options); } diff --git a/src/Endpoint/Base.php b/src/Endpoint/Base.php index 31c75a6..3101c2a 100644 --- a/src/Endpoint/Base.php +++ b/src/Endpoint/Base.php @@ -101,6 +101,16 @@ protected function activitiesPath($id = null, array $extra = []): string return $this->generatePath('activities', $id, $extra); } + /** + * @param int|null $id + * @param array $extras + * @return string + */ + protected function collectionsPath(?int $id = null, array $extras = []): string + { + return $this->generatePath('collections', $id, $extras); + } + /** * @param null $id * @param array $extra diff --git a/src/Endpoint/Collections.php b/src/Endpoint/Collections.php new file mode 100644 index 0000000..6b45ffb --- /dev/null +++ b/src/Endpoint/Collections.php @@ -0,0 +1,149 @@ +collectionsPath(); + + return $this->client->get($path, $options); + } + + /** + * Get collection + * @see https://customer.io/docs/api/#operation/getCollection + * @param array $options + * @return mixed + * @throws GuzzleException + */ + public function get(array $options) + { + if (!isset($options['id'])) { + $this->mockException('Collection id is required!', 'GET'); + } // @codeCoverageIgnore + + $path = $this->collectionsPath($options['id']); + unset($options['id']); + + return $this->client->get($path, $options); + } + + /** + * Create collection + * @see https://customer.io/docs/api/#operation/addCollection + * @param array $options + * @return mixed + * @throws GuzzleException + */ + public function create(array $options) + { + if (!isset($options['name'])) { + $this->mockException('Collection name is required!', 'POST'); + } + + if (!isset($options['data']) && !isset($options['url'])) { + $this->mockException('Collection data or url is required!', 'POST'); + } // @codeCoverageIgnore + + $path = $this->collectionsPath(); + $options['endpoint'] = $this->client->getRegion()->betaUri(); + + return $this->client->post($path, $options); + } + + /** + * Delete a collection + * @see https://customer.io/docs/api/#operation/deleteCollection + * @param array $options + * @return mixed + * @throws GuzzleException + */ + public function delete(array $options) + { + if (!isset($options['collection_id'])) { + $this->mockException('Collection collection_id is required!', 'POST'); + } + + $path = $this->collectionsPath($options['collection_id']); + unset($options['collection_id']); + $options['endpoint'] = $this->client->getRegion()->betaUri(); + + return $this->client->delete($path, $options); + } + + /** + * Update a collection name or data + * @see https://customer.io/docs/api/#operation/updateCollection + * @param array $options + * @return mixed + * @throws GuzzleException + */ + public function update(array $options) + { + if (!isset($options['collection_id'])) { + $this->mockException('Collection collection_id is required!', 'POST'); + } + + $path = $this->collectionsPath($options['collection_id']); + unset($options['collection_id']); + $options['endpoint'] = $this->client->getRegion()->betaUri(); + + return $this->client->put($path, $options); + } + + /** + * Get collection content + * @see https://customer.io/docs/api/#operation/getCollectionContents + * @param array $options + * @return mixed + * @throws GuzzleException + */ + public function content(array $options) + { + if (!isset($options['collection_id'])) { + $this->mockException('Collection collection_id is required!', 'POST'); + } + + $path = $this->collectionsPath($options['collection_id'], ['content']); + unset($options['collection_id']); + $options['raw'] = true; + + return $this->client->get($path, $options); + } + + /** + * Update collection data + * @see https://customer.io/docs/api/#operation/updateCollectionContents + * @param array $options + * @return mixed + * @throws GuzzleException + */ + public function updateContent(array $options) + { + if (!isset($options['collection_id'])) { + $this->mockException('Collection collection_id is required!', 'POST'); + } + + if (!isset($options['data'])) { + $this->mockException('Collection data is required!', 'POST'); + } // @codeCoverageIgnore + + $path = $this->collectionsPath($options['collection_id'], ['content']); + $options = $options['data']; + $options['endpoint'] = $this->client->getRegion()->betaUri(); + + return $this->client->put($path, $options); + } +} diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 995cf6f..8d57cfd 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -21,6 +21,7 @@ public function testBasicClientUs() new Response(200, ['X-Foo' => 'Bar'], "{\"foo\":\"bar\"}"), new Response(200, ['X-Foo' => 'Bar'], "{\"foo\":\"bar\"}"), new Response(200, ['X-Foo' => 'Bar'], "{\"foo\":\"bar\"}"), + new Response(200, ['X-Foo' => 'Bar'], "{\"foo\":\"bar\"}"), ]); $container = []; $history = Middleware::history($container); @@ -35,6 +36,9 @@ public function testBasicClientUs() $client->customers->get([ 'email' => 'test@customer.io', ]); + $client->collection->content([ + 'collection_id' => 1, + ]); $client->customers->add([ 'id' => 10, 'email' => 'test@customer.io', diff --git a/tests/CollectionsTest.php b/tests/CollectionsTest.php new file mode 100644 index 0000000..a24d6c4 --- /dev/null +++ b/tests/CollectionsTest.php @@ -0,0 +1,179 @@ +getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('get')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->search([ + ])); + } + + public function testCollectionGet() + { + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('get')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->get([ + 'id' => 1, + ])); + } + + public function testCollectionGetMissingId() + { + $this->expectException(GuzzleException::class); + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('get')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->get([ + ])); + } + + public function testCollectionCreate() + { + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('post')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->create([ + 'name' => 'example collection', + 'data' => [ + [ + 'name' => 'example', + ], + ], + ])); + } + + public function testCollectionCreateMissingData() + { + $this->expectException(GuzzleException::class); + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('post')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->create([ + 'name' => 'example collection', + ])); + } + + public function testCollectionCreateMissinName() + { + $this->expectException(GuzzleException::class); + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('post')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->create([ + 'url' => 'https://example.com/file.json', + ])); + } + + public function testCollectionDelete() + { + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('delete')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->delete([ + 'collection_id' => 1, + ])); + } + + public function testCollectionDeleteIdMissing() + { + $this->expectException(GuzzleException::class); + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('delete')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->delete([ + 'id' => 1, + ])); + } + + public function testCollectionUpdate() + { + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('put')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->update([ + 'collection_id' => 1, + ])); + } + + public function testCollectionUpdateIdMissing() + { + $this->expectException(GuzzleException::class); + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('put')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->update([ + 'name' => 'example name', + ])); + } + + public function testCollectionContent() + { + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('get')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->content([ + 'collection_id' => 1 + ])); + } + + public function testCollectionContentMissingId() + { + $this->expectException(GuzzleException::class); + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('get')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->content([ + 'id' => 1, + ])); + } + + public function testCollectionContentUpdate() + { + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('put')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->updateContent([ + 'collection_id' => 1, + 'data' => [ + 'x', + 'y', + ], + ])); + } + + public function testCollectionContentUpdateMissingId() + { + $this->expectException(GuzzleException::class); + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('put')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->updateContent([ + 'data' => [ + 'x', + 'y', + ], + ])); + } + + public function testCollectionContentUpdateMissingData() + { + $this->expectException(GuzzleException::class); + $stub = $this->getMockBuilder('Customerio\Client')->disableOriginalConstructor()->getMock(); + $stub->method('put')->willReturn('foo'); + $collections = new Collections($stub); + $this->assertEquals('foo', $collections->updateContent([ + 'collection_id' => 1, + ])); + } +}