diff --git a/.gitignore b/.gitignore index a950b14..461ae7e 100755 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,4 @@ vendor .php-cs-fixer.cache .phpunit.cache composer.lock -test-request.php +playground.php diff --git a/changelog.md b/changelog.md index 39cffa2..d835d31 100644 --- a/changelog.md +++ b/changelog.md @@ -2,7 +2,13 @@ All notable changes to `phpjuice/wati-sdk` will be documented in this file. -## 1.0.0 - 2026-02-21 +## 1.0.1 + +- Add `ResponseData` base class with `hasMore()` and `isSuccessful()` methods +- Refactor response data classes to extend `ResponseData` +- Add unit tests for `ResponseData` + +## 1.0.0 - Initial release of Wati SDK - Pre-built API classes for Wati API: diff --git a/rector.php b/rector.php index 6efc176..4a95693 100644 --- a/rector.php +++ b/rector.php @@ -2,10 +2,14 @@ declare(strict_types=1); +use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector; use Rector\Config\RectorConfig; use Rector\TypeDeclaration\Rector\StmtsAwareInterface\DeclareStrictTypesRector; return RectorConfig::configure() + ->withSkip([ + CompleteDynamicPropertiesRector::class, + ]) ->withPaths([ __DIR__.'/src', __DIR__.'/tests', diff --git a/src/Api/GetContactsData.php b/src/Api/GetContactsData.php index ad87ac8..ad7a217 100644 --- a/src/Api/GetContactsData.php +++ b/src/Api/GetContactsData.php @@ -4,25 +4,25 @@ namespace Wati\Api; -use Psr\Http\Message\ResponseInterface; use Wati\Api\Dto\Contact; +use Wati\Http\WatiResponse; -final readonly class GetContactsData +final class GetContactsData extends ResponseData { /** * @param array $contacts */ public function __construct( - public string $result, - public int $total, - public int $pageNumber, - public int $pageSize, - public ?string $prevPage, - public ?string $nextPage, - public array $contacts, + public readonly array $contacts, + public readonly string $result, + public readonly int $total, + public readonly int $pageNumber, + public readonly int $pageSize, + public readonly ?string $prevPage, + public readonly ?string $nextPage, ) {} - public static function fromResponse(ResponseInterface $response): self + public static function fromResponse(WatiResponse $response): self { /** * @var array{ @@ -37,26 +37,21 @@ public static function fromResponse(ResponseInterface $response): self * } * } $data */ - $data = json_decode($response->getBody()->getContents(), true) ?? []; + $data = $response->json() ?? []; $link = $data['link'] ?? []; return new self( + contacts: array_map( + Contact::fromArray(...), + $data['contact_list'] ?? [] + ), result: data_get_str($data, 'result') ?? '', total: data_get_int($link, 'total'), pageNumber: data_get_int($link, 'pageNumber', 1), pageSize: data_get_int($link, 'pageSize', 50), prevPage: data_get_str($link, 'prevPage'), nextPage: data_get_str($link, 'nextPage'), - contacts: array_map( - Contact::fromArray(...), - $data['contact_list'] ?? [] - ), ); } - - public function hasMore(): bool - { - return $this->nextPage !== null; - } } diff --git a/src/Api/GetMessageTemplatesData.php b/src/Api/GetMessageTemplatesData.php index 160045a..efba87e 100644 --- a/src/Api/GetMessageTemplatesData.php +++ b/src/Api/GetMessageTemplatesData.php @@ -4,25 +4,25 @@ namespace Wati\Api; -use Psr\Http\Message\ResponseInterface; use Wati\Api\Dto\MessageTemplate; +use Wati\Http\WatiResponse; -final readonly class GetMessageTemplatesData +final class GetMessageTemplatesData extends ResponseData { /** * @param array $messageTemplates */ public function __construct( - public string $result, - public int $total, - public int $pageNumber, - public int $pageSize, - public ?string $prevPage, - public ?string $nextPage, - public array $messageTemplates, + public readonly array $messageTemplates, + public readonly string $result, + public readonly int $total, + public readonly int $pageNumber, + public readonly int $pageSize, + public readonly ?string $prevPage, + public readonly ?string $nextPage, ) {} - public static function fromResponse(ResponseInterface $response): self + public static function fromResponse(WatiResponse $response): self { /** * @var array{ @@ -37,26 +37,21 @@ public static function fromResponse(ResponseInterface $response): self * } * } $data */ - $data = json_decode($response->getBody()->getContents(), true) ?? []; + $data = $response->json() ?? []; $link = $data['link'] ?? []; return new self( + messageTemplates: array_map( + MessageTemplate::fromArray(...), + $data['messageTemplates'] ?? [] + ), result: data_get_str($data, 'result') ?? '', total: data_get_int($link, 'total'), pageNumber: data_get_int($link, 'pageNumber', 1), pageSize: data_get_int($link, 'pageSize', 50), prevPage: data_get_str($link, 'prevPage'), nextPage: data_get_str($link, 'nextPage'), - messageTemplates: array_map( - MessageTemplate::fromArray(...), - $data['messageTemplates'] ?? [] - ), ); } - - public function hasMore(): bool - { - return $this->nextPage !== null; - } } diff --git a/src/Api/ResponseData.php b/src/Api/ResponseData.php new file mode 100644 index 0000000..4c82661 --- /dev/null +++ b/src/Api/ResponseData.php @@ -0,0 +1,18 @@ +nextPage !== null; + } + + final public function isSuccessful(): bool + { + return property_exists($this, 'result') && $this->result === 'success'; + } +} diff --git a/src/Api/SendTemplateMessageData.php b/src/Api/SendTemplateMessageData.php index ce23a68..574e720 100644 --- a/src/Api/SendTemplateMessageData.php +++ b/src/Api/SendTemplateMessageData.php @@ -4,18 +4,18 @@ namespace Wati\Api; -use Psr\Http\Message\ResponseInterface; +use Wati\Http\WatiResponse; -final readonly class SendTemplateMessageData +final class SendTemplateMessageData extends ResponseData { public function __construct( - public bool $result, - public ?string $message = null, - public ?string $id = null, - public ?string $phone = null, + public readonly string $result, + public readonly ?string $message = null, + public readonly ?string $id = null, + public readonly ?string $phone = null, ) {} - public static function fromResponse(ResponseInterface $response): self + public static function fromResponse(WatiResponse $response): self { /** * @var array{ @@ -25,18 +25,13 @@ public static function fromResponse(ResponseInterface $response): self * phone?: string|null, * } $data */ - $data = json_decode($response->getBody()->getContents(), true) ?? []; + $data = $response->json() ?? []; return new self( - result: data_get_bool($data, 'result'), + result: data_get_str($data, 'result') ?? '', message: data_get_str($data, 'message'), id: data_get_str($data, 'id'), phone: data_get_str($data, 'phone'), ); } - - public function isSuccess(): bool - { - return $this->result; - } } diff --git a/tests/Api/ResponseDataTest.php b/tests/Api/ResponseDataTest.php new file mode 100644 index 0000000..34a3d67 --- /dev/null +++ b/tests/Api/ResponseDataTest.php @@ -0,0 +1,61 @@ +hasMore())->toBeTrue(); + }); + + it('returns false when nextPage is null', function (): void { + $response = new class extends ResponseData + { + public ?string $nextPage = null; + }; + + expect($response->hasMore())->toBeFalse(); + }); + + it('returns false when nextPage property does not exist', function (): void { + $response = new class extends ResponseData {}; + + expect($response->hasMore())->toBeFalse(); + }); + }); + + describe('isSuccessful', function (): void { + it('returns true when result is success', function (): void { + $response = new class extends ResponseData + { + public string $result = 'success'; + }; + + expect($response->isSuccessful())->toBeTrue(); + }); + + it('returns false when result is not success', function (): void { + $response = new class extends ResponseData + { + public string $result = 'error'; + }; + + expect($response->isSuccessful())->toBeFalse(); + }); + + it('returns false when result property does not exist', function (): void { + $response = new class extends ResponseData {}; + + expect($response->isSuccessful())->toBeFalse(); + }); + }); +});