diff --git a/composer.json b/composer.json index cafe155..5a298c1 100644 --- a/composer.json +++ b/composer.json @@ -12,11 +12,16 @@ "src/Client.php", "src/Settings.php", "src/Collection.php" - ] + ], + "psr-4": { + "Pb\\": "src/", + "Pb\\Exception\\": "src/exception" + } }, "require": { "php": "^8.1|^8.2", - "ext-curl": "*" + "ext-curl": "*", + "guzzlehttp/guzzle": "^7.9" }, "require-dev": { "phpunit/phpunit": "^11.5", diff --git a/composer.lock b/composer.lock index 45efed8..044b50f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,605 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e3ef1b1407a46f944e79ec18eb6f6a9b", - "packages": [], + "content-hash": "31d1044e8ec00497f8c8aba87b9118b1", + "packages": [ + { + "name": "guzzlehttp/guzzle", + "version": "7.9.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.3", + "guzzlehttp/psr7": "^2.7.0", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "guzzle/client-integration-tests": "3.0.2", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "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": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "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.9.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2024-07-24T11:22:20+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455", + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2024-10-17T10:06:22+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "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/2.7.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2024-07-18T11:15:46+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.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": "https://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" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.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": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://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/2.0" + }, + "time": "2023-04-04T09:54: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": "symfony/deprecation-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + } + ], "packages-dev": [ { "name": "myclabs/deep-copy", diff --git a/src/AuthTest.php b/src/AuthTest.php deleted file mode 100644 index 5acaff2..0000000 --- a/src/AuthTest.php +++ /dev/null @@ -1,46 +0,0 @@ -url = getenv('POCKETBASE_URL') ?: 'https://admin.pocketbase.dev'; - $this->collection = new Collection($this->url, 'users'); - } - public function testAuthUser(): void - { - $actual = $this->collection->authAsUser('support@jonathan-martz.de', 'rockt'); - $expected = '{"data":{},"message":"Failed to authenticate.","status":400}'; - - $this->assertEquals($expected, trim($actual, PHP_EOL)); - } - - public function testAuthSuperUser(): void - { - $this->collection = new Collection($this->url, '_superusers'); - $actual = $this->collection->authAsAdmin('admin@jonathan-martz.de', 'rockt'); - $expected = '{"data":{},"message":"Failed to authenticate.","status":400}'; - - $this->assertEquals($expected, trim($actual, PHP_EOL)); - } - - public function testAuthSuperUser2(): void - { - $this->collection = new Collection($this->url, '_superusers'); - - $actual = $this->collection->authAsAdmin('admin@jonathan-martz.de', 'rockt'); - - $data = json_decode($actual,true); - $this->assertArrayHasKey('record',$data); - $this->assertArrayHasKey('token',$data); - $this->assertCount(8,$data['record']); - } -} \ No newline at end of file diff --git a/src/Collection.php b/src/Collection.php index 8e411a4..a20d3e1 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -2,6 +2,8 @@ namespace Pb; +use GuzzleHttp\Exception\GuzzleException; + /** * */ @@ -27,7 +29,10 @@ class Collection * @param string $collection * @param string $token */ - public function __construct(string $url, string $collection, string $token = '') + public function __construct(string $url, + string $collection, + string $token = '' + ) { $this->url = $url; $this->collection = $collection; @@ -111,10 +116,18 @@ class Collection */ public function getFirstListItem(string $filter, array $queryParams = []): array { + // TODO filter $queryParams['perPage'] = 1; + $queryParams['filter'] = $filter; $getParams = !empty($queryParams) ? http_build_query($queryParams) : ""; $response = $this->doRequest($this->url . "/api/collections/" . $this->collection . "/records?" . $getParams, 'GET'); - return json_decode($response, JSON_FORCE_OBJECT)['items'][0]; + + $data = json_decode($response, JSON_FORCE_OBJECT); + if(empty($data['items']) || count($data['items']) < 1){ + throw new exception\FirstListItemNotFoundException('First doesnt exists'); + } + + return $data['items'][0] ?? []; } /** @@ -146,40 +159,19 @@ class Collection */ public function delete(string $recordId, array $queryParams = []): void { + // TODO params ? $this->doRequest($this->url . "/api/collections/" . $this->collection . "/records/" . $recordId, 'DELETE'); } - /** - * @param string $recordId - * @param string $url - * @param string $method - * @return bool|string - */ public function doRequest(string $url, string $method, $bodyParams = []): string { - // TODO move doRequestIntoService ? - // TODO replace curl with HttpClient - $ch = curl_init(); - if (self::$token != '') { - $headers = array( - 'Content-Type:application/json', - 'Authorization: ' . self::$token - ); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + // TODO token ? } - if ($bodyParams) { - curl_setopt($ch, CURLOPT_POSTFIELDS, $bodyParams); - } - - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); - $output = curl_exec($ch); - curl_close($ch); - - return $output; + $client = new \GuzzleHttp\Client(); + $response = $client->request($method, $url,$bodyParams); + return $response->getBody()->getContents() ?? ''; } /** @@ -189,20 +181,16 @@ class Collection */ public function getOne(string $recordId, array $queryParams = []): array { + // TODO params ? $output = $this->doRequest($this->url . "/api/collections/" . $this->collection . "/records/" . $recordId, 'GET'); return json_decode($output, JSON_FORCE_OBJECT); } - - /** - * @param string $email - * @param string $password - * @return void - */ public function authAsAdmin(string $email, string $password): string { $bodyParams['identity'] = $email; $bodyParams['password'] = $password; $output = $this->doRequest($this->url . "/api/collections/_superusers/auth-with-password", 'POST', $bodyParams); + $token = json_decode($output, true)['token']; if ($token) { self::$token = $token; diff --git a/src/exception/FirstListItemNotFoundException.php b/src/exception/FirstListItemNotFoundException.php new file mode 100644 index 0000000..2453a96 --- /dev/null +++ b/src/exception/FirstListItemNotFoundException.php @@ -0,0 +1,14 @@ +url = getenv('POCKETBASE_URL') ?: 'https://admin.pocketbase.dev'; + $this->collection = new Collection($this->url, 'users'); + } + public function testAuthUser(): void + { + $this->expectException(ClientException::class); + $this->collection->authAsUser('support@jonathan-martz.de', 'rockt'); + } + + public function testAuthSuperUser(): void + { + $this->collection = new Collection($this->url, '_superusers'); + $this->expectException(ClientException::class); + $this->collection->authAsAdmin('admin@jonathan-martz.de', 'rockt'); + } + + public function testAuthSuperUser2(): void + { + $this->collection = new Collection($this->url, '_superusers'); + + $this->expectException(ClientException::class); + $this->collection->authAsAdmin('admin@jmartz.de', 'rockt123?!'); + } +} \ No newline at end of file diff --git a/tests/CollectionGetFirstListItemTest.php b/tests/CollectionGetFirstListItemTest.php index 7b77875..2327eba 100644 --- a/tests/CollectionGetFirstListItemTest.php +++ b/tests/CollectionGetFirstListItemTest.php @@ -1,6 +1,7 @@ collection = new Collection($url, 'users'); } + /** + * @throws FirstListItemNotFoundException + */ public function test_getOne(): void { $id = '6588yk36406qqv1'; $actual = $this->collection->getFirstListItem('id="'.$id.'"'); - $expected = [ - 'avatar' => '', - 'collectionId' => '_pb_users_auth_', - 'collectionName' => 'users', - 'created' => '2025-01-21 21:22:47.002Z', - 'emailVisibility' => false, - 'id' => '6588yk36406qqv1', - 'name' => 'Jonathan Martz', - 'updated' => '2025-01-21 21:22:47.002Z', - 'verified' => true - ]; - $this->assertEquals($expected, $actual); + $this->assertEquals($id, $actual['id']); $this->assertCount(9, $actual); } public function test_getOneWrongId(): void { - $id = '6588yk36406qqva'; - $actual = $this->collection->getFirstListItem('id="'.$id.'"'); - $expected = [ - 'avatar' => '', - 'collectionId' => '_pb_users_auth_', - 'collectionName' => 'users', - 'created' => '2025-01-21 21:22:47.002Z', - 'emailVisibility' => false, - 'id' => '6588yk36406qqv1', - 'name' => 'Jonathan Martz', - 'updated' => '2025-01-21 21:22:47.002Z', - 'verified' => true - ]; - - $this->assertEquals($expected, $actual); - $this->assertCount(9,$actual); + $id = '6588yk36406qqvb'; + $this->expectException(FirstListItemNotFoundException::class); + $this->collection->getFirstListItem('id="'.$id.'"'); } } \ No newline at end of file diff --git a/tests/CollectionGetOneTest.php b/tests/CollectionGetOneTest.php index f92d2ed..8399e9a 100644 --- a/tests/CollectionGetOneTest.php +++ b/tests/CollectionGetOneTest.php @@ -1,5 +1,6 @@ collection->getOne($id); - $expected = [ - 'avatar' => '', - 'collectionId' => '_pb_users_auth_', - 'collectionName' => 'users', - 'created' => '2025-01-21 21:22:47.002Z', - 'emailVisibility' => false, - 'id' => '6588yk36406qqv1', - 'name' => 'Jonathan Martz', - 'updated' => '2025-01-21 21:22:47.002Z', - 'verified' => true - ]; - $this->assertEquals($expected, $actual); + $this->assertEquals($id, $actual['id']); $this->assertCount(9, $actual); } public function test_getOneWrongId(): void { $id = '6588yk36406qqva'; - $actual = $this->collection->getOne($id); - $expected = [ - 'data' => [], - 'message' => "The requested resource wasn't found.", - 'status' => 404, - ]; - $this->assertEquals($expected, $actual); - $this->assertCount(3,$actual); + $this->expectException(ClientException::class); + + $this->collection->getOne($id); } } \ No newline at end of file