Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ vendor
.php-cs-fixer.cache
.phpunit.cache
composer.lock
test-request.php
playground.php
8 changes: 7 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 4 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
35 changes: 15 additions & 20 deletions src/Api/GetContactsData.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<Contact> $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{
Expand All @@ -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;
}
}
35 changes: 15 additions & 20 deletions src/Api/GetMessageTemplatesData.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<MessageTemplate> $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{
Expand All @@ -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;
}
}
18 changes: 18 additions & 0 deletions src/Api/ResponseData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Wati\Api;

abstract class ResponseData
{
final public function hasMore(): bool
{
return property_exists($this, 'nextPage') && $this->nextPage !== null;
}

final public function isSuccessful(): bool
{
return property_exists($this, 'result') && $this->result === 'success';
}
}
23 changes: 9 additions & 14 deletions src/Api/SendTemplateMessageData.php
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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;
}
}
61 changes: 61 additions & 0 deletions tests/Api/ResponseDataTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

declare(strict_types=1);

namespace Tests\Api;

use Wati\Api\ResponseData;

describe('ResponseData', function (): void {
describe('hasMore', function (): void {
it('returns true when nextPage is not null', function (): void {
$response = new class extends ResponseData
{
public ?string $nextPage = 'https://api.example.com?page=2';
};

expect($response->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();
});
});
});