diff --git a/.gitignore b/.gitignore index 331c58f..8c8076f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea -vendor \ No newline at end of file +vendor +.phpunit.result.cache \ No newline at end of file diff --git a/composer.json b/composer.json index a4982f0..4147069 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,11 @@ "description": "Laravel Wrapper for the Notion API", "keywords": [ "fiveam-code", - "laravel-notion-api" + "laravel-notion-api", + "laravel", + "notion", + "notion-api", + "api-wrapper" ], "homepage": "https://github.com/fiveam-code/laravel-notion-api", "license": "MIT", @@ -13,10 +17,16 @@ "name": "Diana Scharf", "email": "hello@dianaweb.dev", "role": "Developer" + }, + { + "name": "Johannes Güntner", + "email": "johannes.guentner@it-guentner.de", + "role": "Developer" } ], "require": { "php": "^7.4|^8.0", + "guzzlehttp/guzzle": "^7.0.1", "illuminate/support": "^8.0" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 3e8ce65..7cf46ea 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "faa1217f26f9df0055b5d9492d218ea6", + "content-hash": "94864a46b2ed30ca407dad8b6d542eb3", "packages": [ { "name": "brick/math", @@ -432,6 +432,239 @@ ], "time": "2020-04-13T13:17:36+00:00" }, + { + "name": "guzzlehttp/guzzle", + "version": "7.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "7008573787b430c1c1f650e3722d9bba59967628" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7008573787b430c1c1f650e3722d9bba59967628", + "reference": "7008573787b430c1c1f650e3722d9bba59967628", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.4", + "guzzlehttp/psr7": "^1.7 || ^2.0", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.5 || ^9.3.5", + "psr/log": "^1.1" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.3-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.3.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://github.com/alexeyshockov", + "type": "github" + }, + { + "url": "https://github.com/gmponos", + "type": "github" + } + ], + "time": "2021-03-23T11:33:13+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d", + "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.4.1" + }, + "time": "2021-03-07T09:25:29+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "dc960a912984efb74d0a90222870c72c87f10c91" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91", + "reference": "dc960a912984efb74d0a90222870c72c87f10c91", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.8.2" + }, + "time": "2021-04-26T09:17:50+00:00" + }, { "name": "laravel/framework", "version": "v8.41.0", @@ -1273,6 +1506,111 @@ }, "time": "2019-01-08T18:20:26+00:00" }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, + "time": "2016-08-06T14:39:51+00:00" + }, { "name": "psr/log", "version": "1.1.4", @@ -1374,6 +1712,50 @@ }, "time": "2017-10-23T01:57:42+00:00" }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, { "name": "ramsey/collection", "version": "1.1.3", @@ -4189,81 +4571,6 @@ }, "time": "2021-03-30T06:27:33+00:00" }, - { - "name": "guzzlehttp/psr7", - "version": "1.8.2", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "dc960a912984efb74d0a90222870c72c87f10c91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91", - "reference": "dc960a912984efb74d0a90222870c72c87f10c91", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0", - "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Schultze", - "homepage": "https://github.com/Tobion" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" - ], - "support": { - "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/1.8.2" - }, - "time": "2021-04-26T09:17:50+00:00" - }, { "name": "hamcrest/hamcrest-php", "version": "v2.0.1", @@ -5410,103 +5717,6 @@ ], "time": "2021-03-23T07:16:29+00:00" }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/master" - }, - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" - }, - "type": "library", - "autoload": { - "files": [ - "src/getallheaders.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" - } - ], - "description": "A polyfill for getallheaders.", - "support": { - "issues": "https://github.com/ralouphie/getallheaders/issues", - "source": "https://github.com/ralouphie/getallheaders/tree/develop" - }, - "time": "2019-03-08T08:55:37+00:00" - }, { "name": "sebastian/cli-parser", "version": "1.0.1", diff --git a/src/Endpoints/Block.php b/src/Endpoints/Block.php index a3fae6d..00c87f1 100644 --- a/src/Endpoints/Block.php +++ b/src/Endpoints/Block.php @@ -3,7 +3,7 @@ namespace FiveamCode\LaravelNotionApi\Endpoints; use FiveamCode\LaravelNotionApi\Entities\Collections\BlockCollection; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; use Illuminate\Support\Collection; @@ -46,9 +46,8 @@ private function collectChildren(): BlockCollection $response = $this->get( $this->url(Endpoint::BLOCKS . "/" . $this->blockId . "/children" . "?{$this->buildPaginationQuery()}") ); - if (!$response->ok()) - throw WrapperException::instance("Block not found.", ["blockId" => $this->blockId]); + throw HandlingException::instance("Block not found.", ["blockId" => $this->blockId]); $blockCollection = new BlockCollection($response->json()); diff --git a/src/Endpoints/Database.php b/src/Endpoints/Database.php index c3336a7..8f172df 100644 --- a/src/Endpoints/Database.php +++ b/src/Endpoints/Database.php @@ -8,7 +8,7 @@ use FiveamCode\LaravelNotionApi\Query\Filter; use FiveamCode\LaravelNotionApi\Query\Sorting; use FiveamCode\LaravelNotionApi\Query\StartCursor; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use Symfony\Component\VarDumper\Cloner\Data; class Database extends Endpoint diff --git a/src/Endpoints/Databases.php b/src/Endpoints/Databases.php index 26150f4..c819e29 100644 --- a/src/Endpoints/Databases.php +++ b/src/Endpoints/Databases.php @@ -4,7 +4,7 @@ use FiveamCode\LaravelNotionApi\Entities\Database; use FiveamCode\LaravelNotionApi\Entities\Collections\DatabaseCollection; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; use FiveamCode\LaravelNotionApi\Query\StartCursor; use Illuminate\Support\Collection; @@ -46,6 +46,7 @@ public function allRaw(): array return $this->collect()->getRawResults(); } + // TODO rename this function - receive, access, fetch? private function collect(): DatabaseCollection { $resultData = $this->getJson($this->url(Endpoint::DATABASES) . "?{$this->buildPaginationQuery()}"); @@ -60,17 +61,13 @@ private function collect(): DatabaseCollection * * @param string $databaseId * @return Database - * @throws WrapperException + * @throws HandlingException */ public function find(string $databaseId): Database { - $response = $this->get( - $this->url(Endpoint::DATABASES . "/{$databaseId}") - ); + $result = $this + ->getJson($this->url(Endpoint::DATABASES . "/{$databaseId}")); - if (!$response->ok()) - throw WrapperException::instance("Database not found.", ["databaseId" => $databaseId]); - - return new Database($response->json()); + return new Database($result); } } diff --git a/src/Endpoints/Endpoint.php b/src/Endpoints/Endpoint.php index a8eeaaf..b8451a4 100644 --- a/src/Endpoints/Endpoint.php +++ b/src/Endpoints/Endpoint.php @@ -2,10 +2,13 @@ namespace FiveamCode\LaravelNotionApi\Endpoints; -use FiveamCode\LaravelNotionApi\Query\StartCursor; -use Illuminate\Support\Collection; +use Illuminate\Http\Client\Response; use FiveamCode\LaravelNotionApi\Notion; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use GuzzleHttp\Promise\PromiseInterface; +use FiveamCode\LaravelNotionApi\Query\StartCursor; +use FiveamCode\LaravelNotionApi\Exceptions\NotionException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; +use FiveamCode\LaravelNotionApi\Exceptions\LaravelNotionAPIException; class Endpoint { @@ -17,27 +20,24 @@ class Endpoint const SEARCH = 'search'; public Notion $notion; - private Collection $validVersions; - protected ?StartCursor $startCursor = null; protected int $pageSize = 100; - public function __construct(Notion $notion) - { - $this->validVersions = collect(["v1"]); - $this->notion = $notion; - } + protected ?Response $response = null; /** - * Checks if given version for notion-api is valid - * - * @param string $version + * Endpoint constructor. + * @param Notion $notion + * @throws HandlingException + * @throws LaravelNotionAPIException */ - public function checkValidVersion(string $version): void + public function __construct(Notion $notion) { - if (!$this->validVersions->contains($version)) { - throw WrapperException::instance("invalid version for notion-api", ['invalidVersion' => $version]); + $this->notion = $notion; + + if ($this->notion->getConnection() === null) { + throw HandlingException::instance("Connection could not be established, please check your token."); } } @@ -57,22 +57,36 @@ protected function url(string $endpoint): string * * @param string $url * @return array + * @throws NotionException|HandlingException */ protected function getJson(string $url): array { - return $this->get($url)->json(); + if ($this->response === null) + $this->get($url); + + return $this->response->json(); } /** - * + * @param string $url + * @throws HandlingException + * @throws NotionException */ protected function get(string $url) { - return $this->notion->getConnection()->get($url); + $response = $this->notion->getConnection()->get($url); + + if ($response->failed()) + throw NotionException::fromResponse($response); + + $this->response = $response; + return $response; } /** - * + * @param string $url + * @param array $body + * @return PromiseInterface|Response */ protected function post(string $url, array $body) { @@ -80,6 +94,9 @@ protected function post(string $url, array $body) } + /** + * @return string + */ protected function buildPaginationQuery(): string { $paginationQuery = ""; @@ -93,6 +110,10 @@ protected function buildPaginationQuery(): string return $paginationQuery; } + /** + * @param int $limit + * @return $this + */ public function limit(int $limit): Endpoint { $this->pageSize = min($limit, 100); @@ -100,13 +121,16 @@ public function limit(int $limit): Endpoint return $this; } + /** + * @param StartCursor $startCursor + * @return Endpoint + * @throws HandlingException + * @throws LaravelNotionAPIException + */ public function offset(StartCursor $startCursor): Endpoint { // toDo - throw WrapperException::instance("Not implemented yet."); - - $this->startCursor = $startCursor; - return $this; + throw HandlingException::instance("Not implemented yet."); } } diff --git a/src/Endpoints/Pages.php b/src/Endpoints/Pages.php index 8ac3245..99d0306 100644 --- a/src/Endpoints/Pages.php +++ b/src/Endpoints/Pages.php @@ -3,7 +3,7 @@ namespace FiveamCode\LaravelNotionApi\Endpoints; use FiveamCode\LaravelNotionApi\Entities\Page; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; class Pages extends Endpoint implements EndpointInterface @@ -24,7 +24,7 @@ public function find(string $pageId): Page ); if(!$response->ok()) - throw WrapperException::instance("Page not found.", ["pageId" => $pageId]); + throw HandlingException::instance("Page not found.", ["pageId" => $pageId]); return new Page($response->json()); } diff --git a/src/Endpoints/Users.php b/src/Endpoints/Users.php index e7af617..b89266d 100644 --- a/src/Endpoints/Users.php +++ b/src/Endpoints/Users.php @@ -4,7 +4,7 @@ use FiveamCode\LaravelNotionApi\Entities\User; use FiveamCode\LaravelNotionApi\Entities\Collections\UserCollection; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; use FiveamCode\LaravelNotionApi\Query\StartCursor; use Illuminate\Support\Collection; @@ -60,7 +60,7 @@ public function find(string $userId): User ); if (!$response->ok()) - throw WrapperException::instance("User not found.", ["userId" => $userId]); + throw HandlingException::instance("User not found.", ["userId" => $userId]); return new User($response->json()); diff --git a/src/Entities/Blocks/Block.php b/src/Entities/Blocks/Block.php index fdda978..152ca62 100644 --- a/src/Entities/Blocks/Block.php +++ b/src/Entities/Blocks/Block.php @@ -4,7 +4,7 @@ use DateTime; use FiveamCode\LaravelNotionApi\Entities\Entity; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; use Illuminate\Support\Arr; @@ -19,7 +19,7 @@ class Block extends Entity protected function setResponseData(array $responseData): void { parent::setResponseData($responseData); - if ($responseData['object'] !== 'block') throw WrapperException::instance("invalid json-array: the given object is not a block"); + if ($responseData['object'] !== 'block') throw HandlingException::instance("invalid json-array: the given object is not a block"); $this->fillFromRaw(); } diff --git a/src/Entities/Collections/BlockCollection.php b/src/Entities/Collections/BlockCollection.php index 3c67636..2cfb833 100644 --- a/src/Entities/Collections/BlockCollection.php +++ b/src/Entities/Collections/BlockCollection.php @@ -3,7 +3,7 @@ namespace FiveamCode\LaravelNotionApi\Entities\Collections; use FiveamCode\LaravelNotionApi\Entities\Blocks\Block; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; use Illuminate\Support\Arr; use Illuminate\Support\Collection; diff --git a/src/Entities/Collections/DatabaseCollection.php b/src/Entities/Collections/DatabaseCollection.php index 545f093..a6a5082 100644 --- a/src/Entities/Collections/DatabaseCollection.php +++ b/src/Entities/Collections/DatabaseCollection.php @@ -3,7 +3,7 @@ namespace FiveamCode\LaravelNotionApi\Entities\Collections; use FiveamCode\LaravelNotionApi\Entities\Database; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; use Illuminate\Support\Arr; use Illuminate\Support\Collection; diff --git a/src/Entities/Collections/EntityCollection.php b/src/Entities/Collections/EntityCollection.php index ba2df12..0e09613 100644 --- a/src/Entities/Collections/EntityCollection.php +++ b/src/Entities/Collections/EntityCollection.php @@ -2,13 +2,12 @@ namespace FiveamCode\LaravelNotionApi\Entities\Collections; -use FiveamCode\LaravelNotionApi\Entities\Database; -use FiveamCode\LaravelNotionApi\Entities\Entity; -use FiveamCode\LaravelNotionApi\Entities\Page; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; -use FiveamCode\LaravelNotionApi\Notion; + use Illuminate\Support\Arr; use Illuminate\Support\Collection; +use FiveamCode\LaravelNotionApi\Entities\Page; +use FiveamCode\LaravelNotionApi\Entities\Database; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; class EntityCollection @@ -24,9 +23,9 @@ public function __construct(array $reponseData = null) protected function setResponseData(array $reponseData): void { - if (!Arr::exists($reponseData, 'object')) throw WrapperException::instance("invalid json-array: no object given"); - if (!Arr::exists($reponseData, 'results')) throw WrapperException::instance("invalid json-array: no results given"); - if ($reponseData['object'] !== 'list') throw WrapperException::instance("invalid json-array: the given object is not a list"); + if (!Arr::exists($reponseData, 'object')) throw HandlingException::instance("invalid json-array: no object given"); + if (!Arr::exists($reponseData, 'results')) throw HandlingException::instance("invalid json-array: no results given"); + if ($reponseData['object'] !== 'list') throw HandlingException::instance("invalid json-array: the given object is not a list"); $this->responseData = $reponseData; $this->fillFromRaw(); diff --git a/src/Entities/Collections/PageCollection.php b/src/Entities/Collections/PageCollection.php index fddf518..4537fd6 100644 --- a/src/Entities/Collections/PageCollection.php +++ b/src/Entities/Collections/PageCollection.php @@ -3,7 +3,7 @@ namespace FiveamCode\LaravelNotionApi\Entities\Collections; use FiveamCode\LaravelNotionApi\Entities\Page; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; use Illuminate\Support\Arr; use Illuminate\Support\Collection; diff --git a/src/Entities/Collections/UserCollection.php b/src/Entities/Collections/UserCollection.php index 9f30cb4..ab4ad56 100644 --- a/src/Entities/Collections/UserCollection.php +++ b/src/Entities/Collections/UserCollection.php @@ -3,7 +3,7 @@ namespace FiveamCode\LaravelNotionApi\Entities\Collections; use FiveamCode\LaravelNotionApi\Entities\User; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; use Illuminate\Support\Arr; use Illuminate\Support\Collection; diff --git a/src/Entities/Database.php b/src/Entities/Database.php index e791cac..ae20729 100644 --- a/src/Entities/Database.php +++ b/src/Entities/Database.php @@ -3,7 +3,7 @@ namespace FiveamCode\LaravelNotionApi\Entities; use DateTime; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; use Illuminate\Support\Arr; @@ -21,7 +21,8 @@ class Database extends Entity protected function setResponseData(array $responseData): void { parent::setResponseData($responseData); - if ($responseData['object'] !== 'database') throw WrapperException::instance("invalid json-array: the given object is not a database"); + if ($responseData['object'] !== 'database') + throw HandlingException::instance("invalid json-array: the given object is not a database"); $this->fillFromRaw(); } diff --git a/src/Entities/Entity.php b/src/Entities/Entity.php index c19c2e5..ee61f2b 100644 --- a/src/Entities/Entity.php +++ b/src/Entities/Entity.php @@ -2,7 +2,8 @@ namespace FiveamCode\LaravelNotionApi\Entities; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; +use FiveamCode\LaravelNotionApi\Exceptions\NotionException; use FiveamCode\LaravelNotionApi\Notion; use Illuminate\Support\Arr; use Carbon\Carbon; @@ -20,8 +21,21 @@ public function __construct(array $responseData = null) protected function setResponseData(array $responseData): void { - if (!Arr::exists($responseData, 'object')) throw WrapperException::instance("invalid json-array: no object given"); - if (!Arr::exists($responseData, 'id')) throw WrapperException::instance("invalid json-array: no id provided"); + if (!Arr::exists($responseData, 'object')) + throw new HandlingException("invalid json-array: no object given"); + + // TODO + // Currently, the API returns not-found objects with status code 200 - + // so we have to check here on the given status code in the paylaod, + // if the object was not found. + if( + $responseData['object'] === 'error' + && Arr::exists($responseData, 'status') && $responseData['status'] === 404 + ) { + throw NotionException::instance("Not found", compact("responseData")); + } + + if (!Arr::exists($responseData, 'id')) throw HandlingException::instance("invalid json-array: no id provided"); $this->responseData = $responseData; } diff --git a/src/Entities/Page.php b/src/Entities/Page.php index c578e94..59c24b0 100644 --- a/src/Entities/Page.php +++ b/src/Entities/Page.php @@ -4,7 +4,7 @@ use DateTime; use FiveamCode\LaravelNotionApi\Entities\Properties\Property; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; use Illuminate\Support\Arr; use Illuminate\Support\Collection; @@ -22,7 +22,7 @@ class Page extends Entity protected function setResponseData(array $responseData): void { parent::setResponseData($responseData); - if ($responseData['object'] !== 'page') throw WrapperException::instance("invalid json-array: the given object is not a page"); + if ($responseData['object'] !== 'page') throw HandlingException::instance("invalid json-array: the given object is not a page"); $this->fillFromRaw(); } diff --git a/src/Entities/Properties/Property.php b/src/Entities/Properties/Property.php index b1d42c7..662eb47 100644 --- a/src/Entities/Properties/Property.php +++ b/src/Entities/Properties/Property.php @@ -4,7 +4,7 @@ use DateTime; use FiveamCode\LaravelNotionApi\Entities\Entity; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; use Illuminate\Support\Arr; @@ -23,7 +23,7 @@ public function __construct(string $title, array $responseData) protected function setResponseData(array $responseData): void { - if (!Arr::exists($responseData, 'id')) throw WrapperException::instance("invalid json-array: no id provided"); + if (!Arr::exists($responseData, 'id')) throw HandlingException::instance("invalid json-array: no id provided"); $this->responseData = $responseData; $this->fillFromRaw(); } diff --git a/src/Entities/User.php b/src/Entities/User.php index 3a2dde8..574fc43 100644 --- a/src/Entities/User.php +++ b/src/Entities/User.php @@ -2,7 +2,7 @@ namespace FiveamCode\LaravelNotionApi\Entities; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use FiveamCode\LaravelNotionApi\Notion; use Illuminate\Support\Arr; @@ -14,7 +14,7 @@ class User extends Entity protected function setResponseData(array $responseData): void { parent::setResponseData($responseData); - if ($responseData['object'] !== 'user') throw WrapperException::instance("invalid json-array: the given object is not a user"); + if ($responseData['object'] !== 'user') throw HandlingException::instance("invalid json-array: the given object is not a user"); $this->fillFromRaw(); } diff --git a/src/Exceptions/HandlingException.php b/src/Exceptions/HandlingException.php new file mode 100644 index 0000000..1809c68 --- /dev/null +++ b/src/Exceptions/HandlingException.php @@ -0,0 +1,15 @@ +payload = $payload; + + return $e; + } +} \ No newline at end of file diff --git a/src/Exceptions/LaravelNotionAPIException.php b/src/Exceptions/LaravelNotionAPIException.php new file mode 100644 index 0000000..4f13bcc --- /dev/null +++ b/src/Exceptions/LaravelNotionAPIException.php @@ -0,0 +1,39 @@ +payload; + } +} \ No newline at end of file diff --git a/src/Exceptions/NotionException.php b/src/Exceptions/NotionException.php new file mode 100644 index 0000000..1c3bde6 --- /dev/null +++ b/src/Exceptions/NotionException.php @@ -0,0 +1,35 @@ +payload = $payload; + + return $e; + } + /** + * Handy method to create a NotionException + * from a failed request. + * + * @param string $message + * @param array $payload + * @return HandlingException + */ + public static function fromResponse(Response $response): NotionException + { + $e = new NotionException( + $response->getReasonPhrase(), 0, + $response->toException() + ); + + return $e; + } + +} \ No newline at end of file diff --git a/src/Exceptions/WrapperException.php b/src/Exceptions/WrapperException.php deleted file mode 100644 index 98fe9a0..0000000 --- a/src/Exceptions/WrapperException.php +++ /dev/null @@ -1,37 +0,0 @@ -payload = $payload; - - return $e; - } - - public function getPayload(): array - { - return $this->payload; - } - -} \ No newline at end of file diff --git a/src/Notion.php b/src/Notion.php index 205135a..ed7200c 100644 --- a/src/Notion.php +++ b/src/Notion.php @@ -2,6 +2,8 @@ namespace FiveamCode\LaravelNotionApi; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Http; use Illuminate\Http\Client\PendingRequest; use FiveamCode\LaravelNotionApi\Endpoints\Pages; @@ -18,8 +20,9 @@ class Notion private Endpoint $endpoint; private string $version; private string $token; - private PendingRequest $connection; + private ?PendingRequest $connection = null; + private Collection $validVersions; /** * Notion constructor. @@ -30,11 +33,16 @@ public function __construct(string $version = null, string $token = null) { if ($token !== null) { $this->setToken($token); - } else { - $this->setToken(config('laravel-notion-api.notion-api-token')); + } elseif ($token === null) { + + // check if Notion integration token is set in config + $token = config('laravel-notion-api.notion-api-token'); + + if ($token !== null) + $this->setToken($token); } - $this->endpoint = new Endpoint($this); + $this->validVersions = collect(["v1"]); if ($version !== null) { $this->setVersion($version); @@ -61,7 +69,7 @@ private function connect(): Notion */ public function setVersion(string $version): Notion { - $this->endpoint->checkValidVersion($version); + $this->checkValidVersion($version); $this->version = $version; return $this; } @@ -149,10 +157,22 @@ public function getVersion(): string } /** - * @return PendingRequest + * @return PendingRequest|null */ - public function getConnection(): PendingRequest + public function getConnection(): ?PendingRequest { return $this->connection; } + + /** + * Checks if given version for notion-api is valid + * + * @param string $version + */ + public function checkValidVersion(string $version): void + { + if (!$this->validVersions->contains($version)) { + throw HandlingException::instance("invalid version for notion-api", ['invalidVersion' => $version]); + } + } } diff --git a/src/Query/CompoundFilter.php b/src/Query/CompoundFilter.php index 02945a0..a368129 100644 --- a/src/Query/CompoundFilter.php +++ b/src/Query/CompoundFilter.php @@ -2,7 +2,7 @@ namespace FiveamCode\LaravelNotionApi\Query; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; class CompoundFilter extends QueryHelper { @@ -11,6 +11,6 @@ class CompoundFilter extends QueryHelper public function __construct() { parent::__construct(); - throw new WrapperException("not implemented yet."); + throw new HandlingException("not implemented yet."); } } \ No newline at end of file diff --git a/src/Query/Filter.php b/src/Query/Filter.php index 73d31f1..027fc6b 100644 --- a/src/Query/Filter.php +++ b/src/Query/Filter.php @@ -2,7 +2,7 @@ namespace FiveamCode\LaravelNotionApi\Query; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use Illuminate\Support\Collection; class Filter extends QueryHelper @@ -75,7 +75,7 @@ public function toArray(): array ]; } else - throw WrapperException::instance("Invalid filter definition.", ["invalidFilter" => $this]); + throw HandlingException::instance("Invalid filter definition.", ["invalidFilter" => $this]); } diff --git a/src/Query/Sorting.php b/src/Query/Sorting.php index ce561f7..171297c 100644 --- a/src/Query/Sorting.php +++ b/src/Query/Sorting.php @@ -2,7 +2,7 @@ namespace FiveamCode\LaravelNotionApi\Query; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use Illuminate\Support\Collection; class Sorting extends QueryHelper @@ -16,13 +16,13 @@ public function __construct(string $direction, string $property = null, string $ parent::__construct(); if ($timestamp !== null && !$this->validTimestamps->contains($timestamp)) - throw WrapperException::instance( + throw HandlingException::instance( "Invalid sorting timestamp provided.", ["invalidTimestamp" => $timestamp] ); if (!$this->validDirections->contains($direction)) - throw WrapperException::instance( + throw HandlingException::instance( "Invalid sorting direction provided.", ["invalidDirection" => $direction] ); diff --git a/src/Query/StartCursor.php b/src/Query/StartCursor.php index 3b91d9e..213d357 100644 --- a/src/Query/StartCursor.php +++ b/src/Query/StartCursor.php @@ -2,7 +2,7 @@ namespace FiveamCode\LaravelNotionApi\Query; -use FiveamCode\LaravelNotionApi\Exceptions\WrapperException; +use FiveamCode\LaravelNotionApi\Exceptions\HandlingException; use Illuminate\Support\Collection; class StartCursor { diff --git a/tests/EndpointDatabaseTest.php b/tests/EndpointDatabaseTest.php new file mode 100644 index 0000000..bc166eb --- /dev/null +++ b/tests/EndpointDatabaseTest.php @@ -0,0 +1,146 @@ + Http::response( + json_decode(file_get_contents('tests/stubs/endpoints/databases/response_all_200.json'), true), + 200, + ['Headers'] + ) + ]); + + $notion = new Notion(); + $notion->v1()->setToken("secret_*"); + + $result = $notion->databases()->all(); + + $this->assertIsIterable($result); + $this->assertCount(2, $result); + } + + /** @test */ + public function it_returns_an_empty_list() + { + // successful but empty /v1/databases + Http::fake([ + 'https://api.notion.com/v1/databases*' + => Http::response( + json_decode(file_get_contents('tests/stubs/endpoints/databases/response_empty_200.json'), true), + 200, + ['Headers'] + ) + ]); + + $notion = new Notion(); + $notion->v1()->setToken("secret_*"); + + $result = $notion->databases()->all(); + + // TODO check class here + $this->assertIsIterable($result); + $this->assertCount(0, $result); + } + + /** @test */ + public function it_throws_a_notion_exception_bad_request() + { + // failing /v1/databases + Http::fake([ + 'https://api.notion.com/v1/databases*' + => Http::response( + json_decode('{}', true), + 400, + ['Headers'] + ) + ]); + $notion = new Notion(); + $notion->v1()->setToken("secret_*"); + + + $this->expectException(NotionException::class); + $this->expectExceptionMessage("Bad Request"); + + $result = $notion->databases()->all(); + } + + /** @test */ + public function it_returns_database_entity_with_filled_properties() + { + // successful /v1/databases/DATABASE_DOES_EXIST + Http::fake([ + 'https://api.notion.com/v1/databases/668d797c-76fa-4934-9b05-ad288df2d136' + => Http::response( + json_decode(file_get_contents('tests/stubs/endpoints/databases/response_specific_200.json'), true), + 200, + ['Headers'] + ) + ]); + + $notion = new Notion(); + $notion->v1()->setToken("secret_*"); + + $databaseResult = $notion->databases()->find("668d797c-76fa-4934-9b05-ad288df2d136"); + + $this->assertInstanceOf(Database::class, $databaseResult); + + // check properties + $this->assertSame("Grocery List", $databaseResult->getTitle()); + $this->assertSame("database", $databaseResult->getObjectType()); + + $this->assertCount(1, $databaseResult->getRawTitle()); + $this->assertCount(12, $databaseResult->getRawProperties()); + + $this->assertInstanceOf(Carbon::class, $databaseResult->getCreatedTime()); + $this->assertInstanceOf(Carbon::class, $databaseResult->getLastEditedTime()); + } + + /** @test */ + public function it_throws_a_notion_exception_not_found() + { + // failing /v1/databases/DATABASE_DOES_NOT_EXIST + Http::fake([ + 'https://api.notion.com/v1/databases/b55c9c91-384d-452b-81db-d1ef79372b79' + => Http::response( + json_decode(file_get_contents('tests/stubs/endpoints/databases/response_specific_404.json'), true), + 200, + ['Headers'] + ) + ]); + + $notion = new Notion(); + $notion->v1()->setToken("secret_*"); + + $this->expectException(NotionException::class); + $this->expectExceptionMessage("Not found"); + $databaseResult = $notion->databases()->find("b55c9c91-384d-452b-81db-d1ef79372b79"); + + } + +} \ No newline at end of file diff --git a/tests/HandlingExceptionTest.php b/tests/HandlingExceptionTest.php new file mode 100644 index 0000000..319320e --- /dev/null +++ b/tests/HandlingExceptionTest.php @@ -0,0 +1,38 @@ + "bar"]); + + $this->assertInstanceOf( + HandlingException::class, + $wrapperException + ); + + $this->assertNotEmpty($wrapperException->getPayload()); + + } + + /** @test */ + public function it_returns_a_handling_exception_instance_without_payload() + { + $wrapperException = HandlingException::instance('An error occured.'); + + $this->assertInstanceOf( + HandlingException::class, + $wrapperException + ); + + $this->assertEmpty($wrapperException->getPayload()); + } +} \ No newline at end of file diff --git a/tests/NotionTest.php b/tests/NotionTest.php index 417eb6b..da65828 100644 --- a/tests/NotionTest.php +++ b/tests/NotionTest.php @@ -12,10 +12,10 @@ class NotionTest extends TestCase public function it_returns_notion_instance_with_set_token_and_connection() { $notion = new Notion(); - $notion->v1()->setToken("secret_*"); $this->assertInstanceOf(Notion::class, $notion); + $this->assertNotEmpty($notion->getConnection()); } } \ No newline at end of file diff --git a/tests/WrapperExceptionTest.php b/tests/WrapperExceptionTest.php deleted file mode 100644 index e6d427f..0000000 --- a/tests/WrapperExceptionTest.php +++ /dev/null @@ -1,38 +0,0 @@ - "bar"]); - - $this->assertInstanceOf( - WrapperException::class, - $wrapperException - ); - - $this->assertNotEmpty($wrapperException->getPayload()); - - } - - /** @test */ - public function it_returns_a_wrapper_exception_instance_without_payload() - { - $wrapperException = WrapperException::instance('An error occured.'); - - $this->assertInstanceOf( - WrapperException::class, - $wrapperException - ); - - $this->assertEmpty($wrapperException->getPayload()); - } -} \ No newline at end of file diff --git a/tests/stubs/endpoints/databases/response_all_200.json b/tests/stubs/endpoints/databases/response_all_200.json new file mode 100644 index 0000000..674e078 --- /dev/null +++ b/tests/stubs/endpoints/databases/response_all_200.json @@ -0,0 +1,37 @@ +{ + "object": "list", + "results": [ + { + "object": "database", + "id": "668d797c-76fa-4934-9b05-ad288df2d136", + "title": "Grocery list", + "properties": { + "Name": { + "type": "title", + "title": {} + }, + "Description": { + "type": "text", + "text": {} + } + } + }, + { + "object": "database", + "id": "74ba0cb2-732c-4d2f-954a-fcaa0d93a898", + "title": "Pantry", + "properties": { + "Name": { + "type": "title", + "title": {} + }, + "Description": { + "type": "rich_text", + "rich_text": {} + } + } + } + ], + "next_cursor": "MTY3NDE4NGYtZTdiYy00NzFlLWE0NjctODcxOTIyYWU3ZmM3", + "has_more": false +} \ No newline at end of file diff --git a/tests/stubs/endpoints/databases/response_empty_200.json b/tests/stubs/endpoints/databases/response_empty_200.json new file mode 100644 index 0000000..e608649 --- /dev/null +++ b/tests/stubs/endpoints/databases/response_empty_200.json @@ -0,0 +1,6 @@ +{ + "object": "list", + "results": [], + "next_cursor": "", + "has_more": false +} \ No newline at end of file diff --git a/tests/stubs/endpoints/databases/response_specific_200.json b/tests/stubs/endpoints/databases/response_specific_200.json new file mode 100644 index 0000000..fac7137 --- /dev/null +++ b/tests/stubs/endpoints/databases/response_specific_200.json @@ -0,0 +1,141 @@ +{ + "object": "database", + "id": "668d797c-76fa-4934-9b05-ad288df2d136", + "created_time": "2020-03-17T19:10:04.968Z", + "last_edited_time": "2020-03-17T21:49:37.913Z", + "title": [ + { + "type": "text", + "text": { + "content": "Grocery List", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "Grocery List", + "href": null + } + ], + "properties": { + "Name": { + "id": "title", + "type": "title", + "title": {} + }, + "Description": { + "id": "J@cS", + "type": "text", + "text": {} + }, + "In stock": { + "id": "{xY`", + "type": "checkbox", + "checkbox": {} + }, + "Food group": { + "id": "TJmr", + "type": "select", + "select": { + "options": [ + { + "id": "96eb622f-4b88-4283-919d-ece2fbed3841", + "name": "🥦Vegetable", + "color": "green" + }, + { + "id": "bb443819-81dc-46fb-882d-ebee6e22c432", + "name": "🍎Fruit", + "color": "red" + }, + { + "id": "7da9d1b9-8685-472e-9da3-3af57bdb221e", + "name": "💪Protein", + "color": "yellow" + } + ] + } + }, + "Price": { + "id": "cU^N", + "type": "number", + "number": { + "format": "dollar" + } + }, + "Cost of next trip": { + "id": "p:sC", + "type": "formula", + "formula": { + "value": "if(prop(\"In stock\"), 0, prop(\"Price\"))" + } + }, + "Last ordered": { + "id": "]\\R[", + "type": "date", + "date": {} + }, + "Meals": { + "type": "relation", + "relation": { + "database": "668d797c-76fa-4934-9b05-ad288df2d136", + "synced_property_name": null + } + }, + "Number of meals": { + "id": "Z\\Eh", + "type": "rollup", + "rollup": { + "rollup_property_name": "Name", + "relation_property_name": "Meals", + "rollup_property_id": "title", + "relation_property_id": "mxp^", + "function": "count" + } + }, + "Store availability": { + "type": "multi_select", + "multi_select": { + "options": [ + [ + { + "id": "d209b920-212c-4040-9d4a-bdf349dd8b2a", + "name": "Duc Loi Market", + "color": "blue" + }, + { + "id": "70104074-0f91-467b-9787-00d59e6e1e41", + "name": "Rainbow Grocery", + "color": "gray" + }, + { + "id": "e6fd4f04-894d-4fa7-8d8b-e92d08ebb604", + "name": "Nijiya Market", + "color": "purple" + }, + { + "id": "6c3867c5-d542-4f84-b6e9-a420c43094e7", + "name": "Gus's Community Market", + "color": "yellow" + } + ] + ] + } + }, + "+1": { + "id": "aGut", + "type": "people", + "people": {} + }, + "Photo": { + "id": "aTIT", + "type": "files", + "files": {} + } + } +} \ No newline at end of file diff --git a/tests/stubs/endpoints/databases/response_specific_404.json b/tests/stubs/endpoints/databases/response_specific_404.json new file mode 100644 index 0000000..3e4945a --- /dev/null +++ b/tests/stubs/endpoints/databases/response_specific_404.json @@ -0,0 +1,6 @@ +{ + "object": "error", + "status": 404, + "code": "object_not_found", + "message": "Could not find database with ID: b55c9c91-384d-452b-81db-d1ef79372b79." +} \ No newline at end of file