diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f644f3e..52ec7af 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - php-version: ['8.1', '8.2', '8.3'] + php-version: ['8.1', '8.2', '8.3', '8.4'] steps: - uses: actions/checkout@v4 diff --git a/.gitignore b/.gitignore index 3da4004..3633017 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ ###> symfony/phpunit-bridge ### .phpunit +.phpunit.cache .phpunit.result.cache /phpunit.xml ###< symfony/phpunit-bridge ### diff --git a/.idea/api-client.iml b/.idea/api-client.iml index da31970..23aab67 100644 --- a/.idea/api-client.iml +++ b/.idea/api-client.iml @@ -7,7 +7,6 @@ - @@ -70,6 +69,10 @@ + + + + diff --git a/.idea/php-test-framework.xml b/.idea/php-test-framework.xml index c9ae647..c08c38a 100644 --- a/.idea/php-test-framework.xml +++ b/.idea/php-test-framework.xml @@ -7,6 +7,7 @@ + diff --git a/.idea/php.xml b/.idea/php.xml index bc2cccf..a8d53c2 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -44,7 +44,6 @@ - @@ -78,6 +77,10 @@ + + + + diff --git a/CHANGELOG.md b/CHANGELOG.md index 66dc773..1178f97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Change Log ========== +2024-11-27 - 4.1.1 +------------------ + + * Fix PHP 8.4 deprecations + * Switch to symfony/string instead of pragmarx/ia-str + 2024-02-24 - 4.1.0 ------------------ diff --git a/composer.json b/composer.json index 41de31c..82f0ab1 100644 --- a/composer.json +++ b/composer.json @@ -6,18 +6,19 @@ "require": { "php": ">=8.1", "ext-json": "*", - "beberlei/assert": "^3.0", - "psr/log": "^1|^2|^3", + "beberlei/assert": "^3.3", "pagerfanta/pagerfanta": "^3.5", + "psr/log": "^1|^2|^3", "somnambulist/attribute-model": "^3.0", - "somnambulist/collection": "^5.3", + "somnambulist/collection": "^5.5", "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-client": "^6.4|^7.0", - "symfony/routing": "^6.4|^7.0" + "symfony/routing": "^6.4|^7.0", + "symfony/string": "^6.4|^7.0" }, "require-dev": { "phpunit/phpunit": "^10.5", - "somnambulist/domain": "^5.0", + "somnambulist/domain": "^6.0", "symfony/framework-bundle": "^6.4", "symfony/phpunit-bridge": "^6.4", "symfony/var-dumper": "^6.4" diff --git a/src/Client/Decorators/RecordResponseDecorator.php b/src/Client/Decorators/RecordResponseDecorator.php index a5586de..659bcb4 100644 --- a/src/Client/Decorators/RecordResponseDecorator.php +++ b/src/Client/Decorators/RecordResponseDecorator.php @@ -19,7 +19,7 @@ class RecordResponseDecorator extends AbstractDecorator private string $mode; - public function __construct(ConnectionInterface $client, string $mode = null) + public function __construct(ConnectionInterface $client, ?string $mode = null) { $this->connection = $client; $this->mode = in_array($mode, [self::RECORD, self::PLAYBACK, self::PASSTHRU], true) ? $mode : self::PASSTHRU; diff --git a/src/Client/Query/Behaviours/EncodeSimpleFilterConditions.php b/src/Client/Query/Behaviours/EncodeSimpleFilterConditions.php index 2fcc115..0ff021a 100644 --- a/src/Client/Query/Behaviours/EncodeSimpleFilterConditions.php +++ b/src/Client/Query/Behaviours/EncodeSimpleFilterConditions.php @@ -35,8 +35,8 @@ public function encode(QueryBuilder $builder): array abstract protected function sort(array &$args = []): void; abstract protected function createFilters(?CompositeExpression $expression): array; abstract protected function createInclude(array $includes = []): array; - abstract protected function createLimit(int $limit = null, string $marker = null): array; + abstract protected function createLimit(?int $limit = null, ?string $marker = null): array; abstract protected function createOrderBy(array $orderBy = []): array; abstract protected function createPagination(int $page = 1, int $perPage = 30): array; - abstract protected function createPaginationFromLimitAndOffset(int $limit = null, int $offset = null): array; + abstract protected function createPaginationFromLimitAndOffset(?int $limit = null, ?int $offset = null): array; } diff --git a/src/Client/Query/Encoders/AbstractEncoder.php b/src/Client/Query/Encoders/AbstractEncoder.php index 20e4de2..5e23583 100644 --- a/src/Client/Query/Encoders/AbstractEncoder.php +++ b/src/Client/Query/Encoders/AbstractEncoder.php @@ -13,6 +13,7 @@ use function ksort; use function max; use function strtolower; +use function Symfony\Component\String\u; abstract class AbstractEncoder implements QueryEncoderInterface { @@ -56,13 +57,13 @@ protected function createInclude(array $includes = []): array } if ($this->snakeCaseIncludes) { - $includes = array_map(fn($include) => Str::snake($include), $includes); + $includes = array_map(fn($include) => u($include)->replace('.', 'aaadotaaa')->snake()->replace('aaadotaaa', '.')->toString(), $includes); } return [$this->mappings[self::INCLUDE] => implode(',', $includes)]; } - protected function createLimit(int $limit = null, string $marker = null): array + protected function createLimit(?int $limit = null, ?string $marker = null): array { if (is_null($limit) && is_null($marker)) { return []; @@ -88,7 +89,7 @@ protected function createOrderBy(array $orderBy = []): array return [$this->mappings[self::ORDER_BY] => implode(',', $sort)]; } - protected function createPagination(int $page = null, int $perPage = null): array + protected function createPagination(?int $page = null, ?int $perPage = null): array { if (is_null($page) && is_null($perPage)) { return []; @@ -100,7 +101,7 @@ protected function createPagination(int $page = null, int $perPage = null): arra return [$this->mappings[self::PAGE] => $page, $this->mappings[self::PER_PAGE] => $perPage]; } - protected function createPaginationFromLimitAndOffset(int $limit = null, int $offset = null): array + protected function createPaginationFromLimitAndOffset(?int $limit = null, ?int $offset = null): array { if (is_null($limit) && is_null($offset)) { return []; diff --git a/src/Client/Query/Encoders/JsonApiEncoder.php b/src/Client/Query/Encoders/JsonApiEncoder.php index 120f948..91a7c34 100644 --- a/src/Client/Query/Encoders/JsonApiEncoder.php +++ b/src/Client/Query/Encoders/JsonApiEncoder.php @@ -62,17 +62,17 @@ protected function createFilters(?CompositeExpression $expression): array return [$this->mappings[self::FILTERS] => $filters]; } - protected function createPagination(int $page = null, int $perPage = null): array + protected function createPagination(?int $page = null, ?int $perPage = null): array { return ['page' => parent::createPagination($page, $perPage)]; } - protected function createPaginationFromLimitAndOffset(int $limit = null, int $offset = null): array + protected function createPaginationFromLimitAndOffset(?int $limit = null, ?int $offset = null): array { return ['page' => parent::createPaginationFromLimitAndOffset($limit, $offset)]; } - protected function createLimit(int $limit = null, string $marker = null): array + protected function createLimit(?int $limit = null, ?string $marker = null): array { return ['page' => parent::createLimit($limit, $marker)]; } diff --git a/src/Client/Query/Encoders/OpenStackApiEncoder.php b/src/Client/Query/Encoders/OpenStackApiEncoder.php index 5d547e7..b41db6f 100644 --- a/src/Client/Query/Encoders/OpenStackApiEncoder.php +++ b/src/Client/Query/Encoders/OpenStackApiEncoder.php @@ -92,12 +92,12 @@ protected function createOrderBy(array $orderBy = []): array return [$this->mappings[self::ORDER_BY] => implode(',', $sort)]; } - protected function createPagination(int $page = null, int $perPage = null): array + protected function createPagination(?int $page = null, ?int $perPage = null): array { return []; } - protected function createPaginationFromLimitAndOffset(int $limit = null, int $offset = null): array + protected function createPaginationFromLimitAndOffset(?int $limit = null, ?int $offset = null): array { return []; } diff --git a/src/Client/Query/Expression/Expression.php b/src/Client/Query/Expression/Expression.php index 17fe22e..c69068a 100644 --- a/src/Client/Query/Expression/Expression.php +++ b/src/Client/Query/Expression/Expression.php @@ -46,7 +46,7 @@ public function getValue(): mixed return $this->value; } - public function toString(string $operator = null): string + public function toString(?string $operator = null): string { $val = $this->getValueAsString(); diff --git a/src/Client/Query/QueryBuilder.php b/src/Client/Query/QueryBuilder.php index e221ea4..5251159 100644 --- a/src/Client/Query/QueryBuilder.php +++ b/src/Client/Query/QueryBuilder.php @@ -157,28 +157,28 @@ public function addOrderBy(string $field, string $dir = 'asc'): self return $this; } - public function page(int $page = null): self + public function page(?int $page = null): self { $this->page = !is_null($page) ? max($page, 1) : null; return $this; } - public function perPage(int $perPage = null): self + public function perPage(?int $perPage = null): self { $this->perPage = !is_null($perPage) ? ($perPage < 1 ? 30 : $perPage) : null; return $this; } - public function limit(int $limit = null): self + public function limit(?int $limit = null): self { $this->limit = is_null($limit) ? null : ($limit < 1 ? 100 : $limit); return $this; } - public function offset(string $offset = null): self + public function offset(?string $offset = null): self { $this->offset = $offset; diff --git a/src/Client/ResponseStore.php b/src/Client/ResponseStore.php index 005a66c..e64682c 100644 --- a/src/Client/ResponseStore.php +++ b/src/Client/ResponseStore.php @@ -29,12 +29,12 @@ class ResponseStore private static ?ResponseStore $instance = null; private ?string $store; - private function __construct(string $store = null) + private function __construct(?string $store = null) { $this->store = $store; } - public static function instance(string $store = null): self + public static function instance(?string $store = null): self { if (!self::$instance instanceof ResponseStore) { self::$instance = new ResponseStore($store); diff --git a/src/EntityLocator.php b/src/EntityLocator.php index 23f5100..293ee62 100644 --- a/src/EntityLocator.php +++ b/src/EntityLocator.php @@ -39,7 +39,7 @@ public function findOrFail($id): object return $this->query()->findOrFail($id); } - public function findBy(array $criteria = [], array $orderBy = [], int $limit = null, int $offset = null): Collection + public function findBy(array $criteria = [], array $orderBy = [], ?int $limit = null, ?int $offset = null): Collection { return $this->query()->findBy($criteria, $orderBy, $limit, (string)$offset); } diff --git a/src/ModelBuilder.php b/src/ModelBuilder.php index 4a75d95..165e4a3 100644 --- a/src/ModelBuilder.php +++ b/src/ModelBuilder.php @@ -28,6 +28,7 @@ use function strlen; use function strtolower; use function substr; +use function Symfony\Component\String\u; /** * Builds queries to fetch models from the configured API endpoint. @@ -39,10 +40,10 @@ * @method ModelBuilder orWhere(ExpressionInterface ...$predicates) * @method ModelBuilder orderBy(string $field, string $dir = 'asc') * @method ModelBuilder addOrderBy(string $field, string $dir = 'asc') - * @method ModelBuilder page(int $page = null) - * @method ModelBuilder perPage(int $perPage = null) - * @method ModelBuilder limit(int $limit = null) - * @method ModelBuilder offset(string $offset = null) + * @method ModelBuilder page(?int $page = null) + * @method ModelBuilder perPage(?int $perPage = null) + * @method ModelBuilder limit(?int $limit = null) + * @method ModelBuilder offset(?string $offset = null) * @method ModelBuilder routeRequires(array $params) * * @method array getIncludes() @@ -111,7 +112,7 @@ public function find(mixed $id): ?Model * * @return Collection */ - public function findBy(array $criteria = [], array $orderBy = [], int $limit = null, string $offset = null): Collection + public function findBy(array $criteria = [], array $orderBy = [], ?int $limit = null, ?string $offset = null): Collection { foreach ($criteria as $field => $value) { $this->whereField($field, 'eq', $value); @@ -291,7 +292,8 @@ private function findNestedRelationshipsFor(string $relation): array // the given top-level relationship. We will just check for any relations // that start with the given top relations and add them to our arrays. foreach ($this->eagerLoad as $name) { - if (Str::contains($name, '.') && Str::startsWith($name, $relation . '.')) { + $str = u($name); + if ($str->containsAny('.') && $str->startsWith($relation . '.')) { $nested[] = substr($name, strlen($relation . '.')); } } @@ -362,7 +364,7 @@ public function __call($name, $arguments) if (method_exists($this->query, $name)) { $ret = $this->query->{$name}(...$arguments); - if (Str::startsWith($name, 'get') || 'expr' === $name) { + if (u($name)->startsWith('get') || 'expr' === $name) { return $ret; } diff --git a/src/Persistence/ActionPersister.php b/src/Persistence/ActionPersister.php index 979561c..083e2b8 100755 --- a/src/Persistence/ActionPersister.php +++ b/src/Persistence/ActionPersister.php @@ -40,7 +40,7 @@ class ActionPersister implements ActionPersisterInterface, LoggerAwareInterface protected ConnectionInterface $connection; protected ResponseDecoderInterface $decoder; - public function __construct(ConnectionInterface $connection, ResponseDecoderInterface $decoder = null) + public function __construct(ConnectionInterface $connection, ?ResponseDecoderInterface $decoder = null) { $this->connection = $connection; $this->decoder = $decoder ?? new SimpleJsonDecoder(); diff --git a/src/Persistence/Actions/AbstractAction.php b/src/Persistence/Actions/AbstractAction.php index 54f14b5..8d2e525 100644 --- a/src/Persistence/Actions/AbstractAction.php +++ b/src/Persistence/Actions/AbstractAction.php @@ -11,7 +11,7 @@ abstract class AbstractAction implements ApiActionInterface use HasObjectData; use HasRouteData; - public function __construct(string $class, array $properties = [], string $route = '', array $params = [], string $method = null) + public function __construct(string $class, array $properties = [], string $route = '', array $params = [], ?string $method = null) { $this->class = $class; $this->properties = $properties; diff --git a/src/Persistence/Behaviours/HasRouteData.php b/src/Persistence/Behaviours/HasRouteData.php index fcf66a3..f9c62a8 100644 --- a/src/Persistence/Behaviours/HasRouteData.php +++ b/src/Persistence/Behaviours/HasRouteData.php @@ -22,7 +22,7 @@ protected function validateHttpMethod(?string $method): ?string return in_array(strtolower(trim($method)), ['get', 'post', 'put', 'patch', 'delete', 'head']) ? $method : null; } - public function route(string $route, array $params = [], string $method = null): self + public function route(string $route, array $params = [], ?string $method = null): self { $this->route = $route; $this->params = $params; diff --git a/src/Relationships/AbstractRelationship.php b/src/Relationships/AbstractRelationship.php index 95dc87b..8c42651 100644 --- a/src/Relationships/AbstractRelationship.php +++ b/src/Relationships/AbstractRelationship.php @@ -9,13 +9,14 @@ use Somnambulist\Components\ApiClient\ModelBuilder; use Somnambulist\Components\Collection\Contracts\Collection; use function sprintf; +use function Symfony\Component\String\u; /** * @method AbstractRelationship include(string ...$relationship) - * @method AbstractRelationship limit(int $limit = null) - * @method AbstractRelationship offset(string $offset = null) - * @method AbstractRelationship page(int $page = null) - * @method AbstractRelationship perPage(int $perPage = null) + * @method AbstractRelationship limit(?int $limit = null) + * @method AbstractRelationship offset(?string $offset = null) + * @method AbstractRelationship page(?int $page = null) + * @method AbstractRelationship perPage(?int $perPage = null) * * @method array getIncludes() * @method array getOrderBy() @@ -68,7 +69,7 @@ public function __call($name, $arguments) { $allowed = ['include', 'limit', 'offset', 'page', 'perPage']; - if (in_array($name, $allowed) || Str::startsWith($name, 'get')) { + if (in_array($name, $allowed) || u($name)->startsWith('get')) { $ret = $this->query->{$name}(...$arguments); if (!$ret instanceof $this->query) { diff --git a/tests/Persistence/ActionPersisterTest.php b/tests/Persistence/ActionPersisterTest.php index 930ff20..0b01df1 100755 --- a/tests/Persistence/ActionPersisterTest.php +++ b/tests/Persistence/ActionPersisterTest.php @@ -29,6 +29,7 @@ use Symfony\Contracts\HttpClient\ResponseInterface; use function file_get_contents; +use function Symfony\Component\String\u; /** * @group client @@ -69,19 +70,20 @@ protected function setUp(): void ]); $callback = function ($method, $url, $options) use ($new, $updated, $deleted, $error) { - $useError = Str::contains($options['body'] ?? '', '&error=1'); + $useError = u($options['body'] ?? '')->containsAny('&error=1'); + $url = u($url); - switch ($url) { - case 'PUT' === $method && Str::contains($url, '/users/c8259b3b-8603-3098-8361-425325078c9a'): + switch (true) { + case 'PUT' === $method && $url->containsAny('/users/c8259b3b-8603-3098-8361-425325078c9a'): return $updated; - case 'DELETE' === $method && Str::contains($url, '/users/c8259b3b-8603-3098-8361-425325078c9a'): + case 'DELETE' === $method && $url->containsAny('/users/c8259b3b-8603-3098-8361-425325078c9a'): return $deleted; - case 'POST' === $method && Str::contains($url, '/users') && $useError: + case 'POST' === $method && $url->containsAny('/users') && $useError: return $error; - case 'POST' === $method && Str::contains($url, '/users'): + case 'POST' === $method && $url->containsAny('/users'): return $new; } }; diff --git a/tests/Support/Behaviours/AssertRequestMade.php b/tests/Support/Behaviours/AssertRequestMade.php index 4544513..3054056 100644 --- a/tests/Support/Behaviours/AssertRequestMade.php +++ b/tests/Support/Behaviours/AssertRequestMade.php @@ -57,7 +57,7 @@ protected function assertRouteWasNotCalledWith(string $expectedRoute, array $exp * @param string|null $expectedBody the response string to compare with * @param array $expectedHeaders array of key => value pairs to check for */ - protected function assertResponseContains(string $expectedBody = null, array $expectedHeaders = []): void + protected function assertResponseContains(?string $expectedBody = null, array $expectedHeaders = []): void { Manager::instance()->connect(new User)->onAfterRequest(function (ResponseInterface $response) use ($expectedBody, $expectedHeaders) { foreach ($expectedHeaders as $key => $value) { @@ -74,7 +74,7 @@ protected function assertResponseContains(string $expectedBody = null, array $ex * @param string|null $expectedBody the response string that should not appear * @param array $expectedHeaders array of key => value pairs to check dont exist */ - protected function assertResponseDoesNotContain(string $expectedBody = null, array $expectedHeaders = []): void + protected function assertResponseDoesNotContain(?string $expectedBody = null, array $expectedHeaders = []): void { Manager::instance()->connect(new User)->onAfterRequest(function (ResponseInterface $response) use ($expectedBody, $expectedHeaders) { foreach ($expectedHeaders as $key => $value) { diff --git a/tests/Support/Factory.php b/tests/Support/Factory.php index 9e801ff..8933a5e 100755 --- a/tests/Support/Factory.php +++ b/tests/Support/Factory.php @@ -19,25 +19,29 @@ use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\String\UnicodeString; use function file_get_contents; use function is_callable; use function sprintf; +use function Symfony\Component\String\u; class Factory { - public function makeManager(callable $decoratorFactory = null): Manager + public function makeManager(?callable $decoratorFactory = null): Manager { $host = 'http://api.example.dev/users/v1'; - $callback = function ($method, $url, $options) { - switch ($url) { - case Str::contains($url, '/v1/users'): return $this->userRoutes($method, $url, $options); - case Str::contains($url, '/v1/accounts'): return $this->accountRoutes($method, $url, $options); + $callback = function (string $method, string $url, array $options = []) { + $url = u($url); - case Str::contains($url, '/v1/groups/1?include=permissions'): + switch (true) { + case $url->containsAny('/v1/users'): return $this->userRoutes($method, $url, $options); + case $url->containsAny('/v1/accounts'): return $this->accountRoutes($method, $url, $options); + + case $url->containsAny('/v1/groups/1?include=permissions'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/group_view_with_permissions.json')); - case Str::contains($url, '/v1/foobar'): + case $url->containsAny('/v1/foobar'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_foobar.json')); } @@ -75,79 +79,79 @@ public function makeManager(callable $decoratorFactory = null): Manager ); } - private function accountRoutes($method, $url, $options): MockResponse + private function accountRoutes(string $method, UnicodeString $url, array $options = []): MockResponse { - switch ($url) { - case Str::contains($url, '/v1/accounts/1228ec03-1a58-4e51-8cea-cb787104aa3d?include=related_accounts'): + switch (true) { + case $url->containsAny('/v1/accounts/1228ec03-1a58-4e51-8cea-cb787104aa3d?include=related_accounts'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/account_view_1228ec03_with_related_accounts.json')); - case Str::contains($url, '/v1/accounts/1228ec03-1a58-4e51-8cea-cb787104aa3d?include=related'): + case $url->containsAny('/v1/accounts/1228ec03-1a58-4e51-8cea-cb787104aa3d?include=related'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/account_view_1228ec03_with_related.json')); - case Str::contains($url, '/v1/accounts/1228ec03-1a58-4e51-8cea-cb787104aa3d'): + case $url->containsAny('/v1/accounts/1228ec03-1a58-4e51-8cea-cb787104aa3d'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/account_view_1228ec03.json')); - case Str::contains($url, '/v1/accounts/8c4ba4ea-c4f6-43ad-b97c-cb84f4314fa8'): + case $url->containsAny('/v1/accounts/8c4ba4ea-c4f6-43ad-b97c-cb84f4314fa8'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/account_view_8c4ba4ea.json')); } throw new RuntimeException(sprintf('No response configured for request: %s %s', $method, $url)); } - private function userRoutes($method, $url, $options): MockResponse + private function userRoutes(string $method, UnicodeString $url, array $options = []): MockResponse { - switch ($url) { - case Str::contains($url, '/v1/users/468185d5-4238-44bb-ae34-44909e35e4fe?include=address3'): + switch (true) { + case $url->containsAny('/v1/users/468185d5-4238-44bb-ae34-44909e35e4fe?include=address3'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_view_with_no_address.json')); - case Str::contains($url, '/v1/users/1e335331-ee15-4871-a419-c6778e190a54?include=account.related.related'): + case $url->containsAny('/v1/users/1e335331-ee15-4871-a419-c6778e190a54?include=account.related.related'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_view_with_account_relations.json')); - case Str::contains($url, '/v1/users/1e335331-ee15-4871-a419-c6778e190a54?include=contacts'): + case $url->containsAny('/v1/users/1e335331-ee15-4871-a419-c6778e190a54?include=contacts'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_view_with_contacts.json')); - case Str::contains($url, '/v1/users/1e335331-ee15-4871-a419-c6778e190a54'): + case $url->containsAny('/v1/users/1e335331-ee15-4871-a419-c6778e190a54'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_view_1e335331.json')); - case Str::contains($url, '/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=addresses,contacts'): + case $url->containsAny('/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=addresses,contacts'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_view_with_addresses_contacts.json')); - case Str::contains($url, '/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=addresses'): + case $url->containsAny('/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=addresses'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_view_with_addresses.json')); - case Str::contains($url, '/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=address,contacts'): + case $url->containsAny('/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=address,contacts'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_view_with_address_contacts.json')); - case Str::contains($url, '/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=address'): + case $url->containsAny('/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=address'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_view_with_address.json')); - case Str::contains($url, '/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=groups,groups.permissions'): - case Str::contains($url, '/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=groups.permissions'): + case $url->containsAny('/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=groups,groups.permissions'): + case $url->containsAny('/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=groups.permissions'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_view_with_groups_permissions.json')); - case Str::contains($url, '/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=groups'): + case $url->containsAny('/v1/users/c8259b3b-8603-3098-8361-425325078c9a?include=groups'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_view_with_groups.json')); - case Str::contains($url, '/v1/users/c8259b3b-8603-3098-8361-425325078c9a'): + case $url->containsAny('/v1/users/c8259b3b-8603-3098-8361-425325078c9a'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_view_c8259b3b.json')); - case Str::contains($url, '/v1/users/c8259b3b-0000-0000-0000-425325078c9a'): + case $url->containsAny('/v1/users/c8259b3b-0000-0000-0000-425325078c9a'): return new MockResponse('{"message":"Record not found"}', ['http_code' => 404]); - case Str::contains($url, '/v1/users?email=noresults@example.com'): + case $url->containsAny('/v1/users?email=noresults@example.com'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_list_no_result.json')); - case Str::contains($url, '/v1/users?email=hodkiewicz.anastasia@feest.org'): - case Str::contains($url, '/v1/users?id=c8259b3b-8603-3098-8361-425325078c9a&per_page=10&page=1'): - case Str::contains($url, '/v1/users?id=c8259b3b-8603-3098-8361-425325078c9a&order=-name,created_at'): - case Str::contains($url, '/v1/users?id=c8259b3b-8603-3098-8361-425325078c9a&include=addresses,contacts'): - case Str::contains($url, '/v1/users?id=c8259b3b-8603-3098-8361-425325078c9a'): + case $url->containsAny('/v1/users?email=hodkiewicz.anastasia@feest.org'): + case $url->containsAny('/v1/users?id=c8259b3b-8603-3098-8361-425325078c9a&per_page=10&page=1'): + case $url->containsAny('/v1/users?id=c8259b3b-8603-3098-8361-425325078c9a&order=-name,created_at'): + case $url->containsAny('/v1/users?id=c8259b3b-8603-3098-8361-425325078c9a&include=addresses,contacts'): + case $url->containsAny('/v1/users?id=c8259b3b-8603-3098-8361-425325078c9a'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_list_single.json')); - case Str::contains($url, '/v1/users?include=addresses,contacts'): + case $url->containsAny('/v1/users?include=addresses,contacts'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_list_with_addresses_contacts.json')); - case Str::contains($url, '/v1/users'): + case $url->containsAny('/v1/users'): return new MockResponse(file_get_contents(__DIR__ . '/Stubs/json/user_list.json')); }