From b4422a3541c0bfddf89063a735a6497a6201f21e Mon Sep 17 00:00:00 2001 From: Mohammed Elhaouari Date: Sun, 22 Feb 2026 22:10:35 +0100 Subject: [PATCH 1/2] --wip-- [skip ci] --- AGENTS.md | 3 + README.md | 1 + src/Api/Dto/Contact.php | 18 +-- src/Api/Dto/MessageTemplate.php | 12 +- src/Api/GetContactsData.php | 12 +- src/Api/GetMessageTemplatesData.php | 12 +- src/Api/SendTemplateMessage.php | 39 +++++ src/Api/SendTemplateMessageData.php | 42 ++++++ src/helpers.php | 59 ++++++-- tests/Api/SendTemplateMessageTest.php | 60 ++++++++ tests/helpersTest.php | 199 ++++++++++++++++++++------ 11 files changed, 378 insertions(+), 79 deletions(-) create mode 100644 src/Api/SendTemplateMessage.php create mode 100644 src/Api/SendTemplateMessageData.php create mode 100644 tests/Api/SendTemplateMessageTest.php diff --git a/AGENTS.md b/AGENTS.md index d8b9f9e..81a3909 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -40,6 +40,7 @@ $data = json_decode($response->getBody()->getContents(), true); |----------------------|--------|------------------------------| | `GetContacts` | GET | `/api/v1/getContacts` | | `GetMessageTemplates`| GET | `/api/v1/getMessageTemplates`| +| `SendTemplateMessage`| POST | `/api/v1/sendTemplateMessage`| ## Testing @@ -58,6 +59,8 @@ src/ ├── GetContactsData.php ├── GetMessageTemplates.php ├── GetMessageTemplatesData.php + ├── SendTemplateMessage.php + ├── SendTemplateMessageData.php └── Dto/ ├── Contact.php └── MessageTemplate.php diff --git a/README.md b/README.md index 757903f..3f5bbb8 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,7 @@ class ContactController | Class | Method | Endpoint | |-----------------------|--------|-------------------------------| | `GetMessageTemplates` | GET | `/api/v1/getMessageTemplates` | +| `SendTemplateMessage` | POST | `/api/v1/sendTemplateMessage` | ## Usage diff --git a/src/Api/Dto/Contact.php b/src/Api/Dto/Contact.php index d8130d2..e7bd090 100644 --- a/src/Api/Dto/Contact.php +++ b/src/Api/Dto/Contact.php @@ -24,15 +24,15 @@ public function __construct( public static function fromArray(array $data): self { return new self( - id: data_get_str($data, 'id', ''), - phone: data_get_str($data, 'phone', ''), - fullName: data_get_str($data, 'fullName', ''), - wAid: is_string($v = data_get_str($data, 'wAid')) ? $v : null, - firstName: is_string($v = data_get_str($data, 'firstName')) ? $v : null, - email: is_string($v = data_get_str($data, 'email')) ? $v : null, - contactStatus: is_string($v = data_get_str($data, 'contactStatus')) ? $v : null, - created: is_string($v = data_get_str($data, 'created')) ? $v : null, - lastUpdated: is_string($v = data_get_str($data, 'lastUpdated')) ? $v : null, + id: data_get_str($data, 'id') ?? '', + phone: data_get_str($data, 'phone') ?? '', + fullName: data_get_str($data, 'fullName') ?? '', + wAid: data_get_str($data, 'wAid'), + firstName: data_get_str($data, 'firstName'), + email: data_get_str($data, 'email'), + contactStatus: data_get_str($data, 'contactStatus'), + created: data_get_str($data, 'created'), + lastUpdated: data_get_str($data, 'lastUpdated'), ); } } diff --git a/src/Api/Dto/MessageTemplate.php b/src/Api/Dto/MessageTemplate.php index 45005a7..1861e23 100644 --- a/src/Api/Dto/MessageTemplate.php +++ b/src/Api/Dto/MessageTemplate.php @@ -21,12 +21,12 @@ public function __construct( public static function fromArray(array $data): self { return new self( - id: data_get_str($data, 'id', ''), - elementName: data_get_str($data, 'elementName', ''), - category: is_string($v = data_get_str($data, 'category')) ? $v : null, - status: is_string($v = data_get_str($data, 'status')) ? $v : null, - language: is_string($v = data_get_str($data, 'language')) ? $v : null, - body: is_string($v = data_get_str($data, 'body')) ? $v : null, + id: data_get_str($data, 'id') ?? '', + elementName: data_get_str($data, 'elementName') ?? '', + category: data_get_str($data, 'category'), + status: data_get_str($data, 'status'), + language: data_get_str($data, 'language'), + body: data_get_str($data, 'body'), ); } } diff --git a/src/Api/GetContactsData.php b/src/Api/GetContactsData.php index c97a03a..ad87ac8 100644 --- a/src/Api/GetContactsData.php +++ b/src/Api/GetContactsData.php @@ -42,12 +42,12 @@ public static function fromResponse(ResponseInterface $response): self $link = $data['link'] ?? []; return new self( - result: is_string($data['result'] ?? null) ? $data['result'] : '', - total: (int) ($link['total'] ?? 0), - pageNumber: (int) ($link['pageNumber'] ?? 1), - pageSize: (int) ($link['pageSize'] ?? 50), - prevPage: is_string($link['prevPage'] ?? null) ? $link['prevPage'] : null, - nextPage: is_string($link['nextPage'] ?? null) ? $link['nextPage'] : null, + 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'] ?? [] diff --git a/src/Api/GetMessageTemplatesData.php b/src/Api/GetMessageTemplatesData.php index d1406ae..160045a 100644 --- a/src/Api/GetMessageTemplatesData.php +++ b/src/Api/GetMessageTemplatesData.php @@ -42,12 +42,12 @@ public static function fromResponse(ResponseInterface $response): self $link = $data['link'] ?? []; return new self( - result: is_string($data['result'] ?? null) ? $data['result'] : '', - total: (int) ($link['total'] ?? 0), - pageNumber: (int) ($link['pageNumber'] ?? 1), - pageSize: (int) ($link['pageSize'] ?? 50), - prevPage: is_string($link['prevPage'] ?? null) ? $link['prevPage'] : null, - nextPage: is_string($link['nextPage'] ?? null) ? $link['nextPage'] : null, + 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'] ?? [] diff --git a/src/Api/SendTemplateMessage.php b/src/Api/SendTemplateMessage.php new file mode 100644 index 0000000..398e5f6 --- /dev/null +++ b/src/Api/SendTemplateMessage.php @@ -0,0 +1,39 @@ + $parameters Template parameters + */ + public function __construct( + public readonly string $whatsappNumber, + public readonly string $templateName, + public readonly string $broadcastName, + public readonly array $parameters = [] + ) { + $body = json_encode([ + 'template_name' => $templateName, + 'broadcast_name' => $broadcastName, + 'parameters' => $parameters, + ]) ?: '{}'; + + parent::__construct( + 'POST', + "/api/v1/sendTemplateMessage?whatsappNumber={$whatsappNumber}", + [ + 'Accept' => 'application/json', + 'Content-Type' => 'application/json', + ], + $body + ); + } +} diff --git a/src/Api/SendTemplateMessageData.php b/src/Api/SendTemplateMessageData.php new file mode 100644 index 0000000..ce23a68 --- /dev/null +++ b/src/Api/SendTemplateMessageData.php @@ -0,0 +1,42 @@ +getBody()->getContents(), true) ?? []; + + return new self( + result: data_get_bool($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/src/helpers.php b/src/helpers.php index d290c33..642bd18 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -7,21 +7,62 @@ * * @param array $data * @param TDefault $default - * @return string|TDefault + * @return mixed|TDefault */ -function data_get_str(array $data, string $key, mixed $default = null): mixed +function data_get_value(array $data, string $key, mixed $default = null): mixed { - if (! array_key_exists($key, $data) || $data[$key] === null) { - return $default; - } + return array_key_exists($key, $data) && $data[$key] !== null + ? $data[$key] + : $default; +} + +/** + * @param array $data + */ +function data_get_str(array $data, string $key, ?string $default = null): ?string +{ + $value = data_get_value($data, $key, $default); - $value = $data[$key]; + return is_string($value) ? trim($value) : $default; +} +/** + * @param array $data + */ +function data_get_int(array $data, string $key, int $default = 0): int +{ + $value = data_get_value($data, $key, $default); + + return is_numeric($value) ? (int) $value : $default; +} + +/** + * @param array $data + */ +function data_get_bool(array $data, string $key, bool $default = false): bool +{ + $value = data_get_value($data, $key, $default); + + if (is_bool($value)) { + return $value; + } + + // Handle common truthy/falsy string representations if (is_string($value)) { - $value = trim($value); + return match (strtolower(trim($value))) { + 'true', '1', 'yes', 'on' => true, + 'false', '0', 'no', 'off' => false, + default => $default, + }; + } - return $value !== '' ? $value : $default; + if (is_int($value)) { + return match ($value) { + 1 => true, + 0 => false, + default => $default, + }; } - return $value; + return $default; } diff --git a/tests/Api/SendTemplateMessageTest.php b/tests/Api/SendTemplateMessageTest.php new file mode 100644 index 0000000..96941a1 --- /dev/null +++ b/tests/Api/SendTemplateMessageTest.php @@ -0,0 +1,60 @@ +getMethod())->toBe('POST') + ->and($request->getUri()->getPath())->toBe('/api/v1/sendTemplateMessage') + ->and($request->getUri()->getQuery())->toBe('whatsappNumber=1234567890') + ->and($request->getHeaderLine('Accept'))->toBe('application/json') + ->and($request->getHeaderLine('Content-Type'))->toBe('application/json') + ->and($request->whatsappNumber)->toBe('1234567890') + ->and($request->templateName)->toBe('order_update') + ->and($request->broadcastName)->toBe('order_update') + ->and($request->parameters)->toBe([]); +}); + +it('can create a send template message with parameters', function (): void { + $parameters = [ + ['name' => 'name', 'value' => 'John'], + ['name' => 'ordernumber', 'value' => '12345'], + ]; + + $request = new SendTemplateMessage( + whatsappNumber: '1234567890', + templateName: 'order_update', + broadcastName: 'order_update', + parameters: $parameters + ); + + expect($request->parameters)->toBe($parameters); + + $body = $request->getBody()->getContents(); + $decoded = json_decode($body, true); + + expect($decoded)->toBe([ + 'template_name' => 'order_update', + 'broadcast_name' => 'order_update', + 'parameters' => $parameters, + ]); +}); + +it('encodes special characters in whatsapp number', function (): void { + $request = new SendTemplateMessage( + whatsappNumber: '+1 234 567 890', + templateName: 'welcome', + broadcastName: 'welcome_campaign' + ); + + expect($request->getUri()->getQuery())->toBe('whatsappNumber=+1%20234%20567%20890'); +}); diff --git a/tests/helpersTest.php b/tests/helpersTest.php index 4ee96c6..83fc34b 100644 --- a/tests/helpersTest.php +++ b/tests/helpersTest.php @@ -2,63 +2,176 @@ declare(strict_types=1); -it('returns value when key exists', function (): void { - $data = ['name' => 'John', 'email' => 'john@example.com']; +describe('data_get_value', function (): void { + it('returns value when key exists and is not null', function (): void { + $data = ['name' => 'John', 'count' => 42]; - expect(data_get_str($data, 'name'))->toBe('John') - ->and(data_get_str($data, 'email'))->toBe('john@example.com'); -}); + expect(data_get_value($data, 'name'))->toBe('John') + ->and(data_get_value($data, 'count'))->toBe(42); + }); -it('returns default when key does not exist', function (): void { - $data = ['name' => 'John']; + it('returns default when key does not exist', function (): void { + $data = ['name' => 'John']; - expect(data_get_str($data, 'email'))->toBeNull() - ->and(data_get_str($data, 'email', 'default'))->toBe('default'); -}); + expect(data_get_value($data, 'email'))->toBeNull() + ->and(data_get_value($data, 'email', 'default'))->toBe('default'); + }); -it('returns default when value is null', function (): void { - $data = ['name' => null]; + it('returns default when value is null', function (): void { + $data = ['name' => null]; - expect(data_get_str($data, 'name'))->toBeNull() - ->and(data_get_str($data, 'name', 'default'))->toBe('default'); + expect(data_get_value($data, 'name'))->toBeNull() + ->and(data_get_value($data, 'name', 'default'))->toBe('default'); + }); }); -it('returns default when value is empty string', function (): void { - $data = ['name' => '']; +describe('data_get_str', function (): void { + it('returns trimmed string when value is string', function (): void { + $data = ['name' => ' John ']; - expect(data_get_str($data, 'name'))->toBeNull() - ->and(data_get_str($data, 'name', 'default'))->toBe('default'); -}); + expect(data_get_str($data, 'name'))->toBe('John'); + }); -it('trims string values', function (): void { - $data = ['name' => ' John ']; + it('returns default when key does not exist', function (): void { + $data = ['name' => 'John']; - expect(data_get_str($data, 'name'))->toBe('John'); -}); + expect(data_get_str($data, 'email'))->toBeNull() + ->and(data_get_str($data, 'email', 'default'))->toBe('default'); + }); -it('returns default when trimmed value is empty', function (): void { - $data = ['name' => ' ']; + it('returns default when value is null', function (): void { + $data = ['name' => null]; - expect(data_get_str($data, 'name'))->toBeNull() - ->and(data_get_str($data, 'name', 'default'))->toBe('default'); -}); + expect(data_get_str($data, 'name'))->toBeNull() + ->and(data_get_str($data, 'name', 'default'))->toBe('default'); + }); -it('returns non-string values as-is', function (): void { - $data = [ - 'count' => 42, - 'active' => true, - 'items' => ['a', 'b'], - 'price' => 19.99, - ]; - - expect(data_get_str($data, 'count'))->toBe(42) - ->and(data_get_str($data, 'active'))->toBeTrue() - ->and(data_get_str($data, 'items'))->toBe(['a', 'b']) - ->and(data_get_str($data, 'price'))->toBe(19.99); + it('returns default when value is not a string', function (): void { + $data = ['count' => 42, 'active' => true]; + + expect(data_get_str($data, 'count'))->toBeNull() + ->and(data_get_str($data, 'count', 'default'))->toBe('default') + ->and(data_get_str($data, 'active'))->toBeNull(); + }); + + it('returns default when trimmed value is empty', function (): void { + $data = ['name' => ' ']; + + expect(data_get_str($data, 'name'))->toBe('') + ->and(data_get_str($data, 'name', 'default'))->toBe(''); + }); }); -it('returns default for missing nested keys', function (): void { - $data = ['user' => ['name' => 'John']]; +describe('data_get_int', function (): void { + it('returns integer when value is numeric', function (): void { + $data = ['count' => 42, 'price' => '19.99']; + + expect(data_get_int($data, 'count'))->toBe(42) + ->and(data_get_int($data, 'price'))->toBe(19); + }); + + it('returns default when key does not exist', function (): void { + $data = ['name' => 'John']; + + expect(data_get_int($data, 'count'))->toBe(0) + ->and(data_get_int($data, 'count', 10))->toBe(10); + }); + + it('returns default when value is null', function (): void { + $data = ['count' => null]; + + expect(data_get_int($data, 'count'))->toBe(0) + ->and(data_get_int($data, 'count', 5))->toBe(5); + }); + + it('returns default when value is not numeric', function (): void { + $data = ['name' => 'John', 'active' => true]; + + expect(data_get_int($data, 'name'))->toBe(0) + ->and(data_get_int($data, 'active'))->toBe(0); + }); + + it('handles string numbers', function (): void { + $data = ['count' => '123']; + + expect(data_get_int($data, 'count'))->toBe(123); + }); +}); - expect(data_get_str($data, 'email', 'missing'))->toBe('missing'); +describe('data_get_bool', function (): void { + it('returns boolean when value is bool', function (): void { + $data = ['active' => true, 'disabled' => false]; + + expect(data_get_bool($data, 'active'))->toBeTrue() + ->and(data_get_bool($data, 'disabled'))->toBeFalse(); + }); + + it('returns default when key does not exist', function (): void { + $data = ['name' => 'John']; + + expect(data_get_bool($data, 'active'))->toBeFalse() + ->and(data_get_bool($data, 'active', true))->toBeTrue(); + }); + + it('returns default when value is null', function (): void { + $data = ['active' => null]; + + expect(data_get_bool($data, 'active'))->toBeFalse() + ->and(data_get_bool($data, 'active', true))->toBeTrue(); + }); + + it('handles truthy string representations', function (): void { + $data = [ + 'a' => 'true', + 'b' => 'TRUE', + 'c' => '1', + 'd' => 'yes', + 'e' => 'on', + ]; + + expect(data_get_bool($data, 'a'))->toBeTrue() + ->and(data_get_bool($data, 'b'))->toBeTrue() + ->and(data_get_bool($data, 'c'))->toBeTrue() + ->and(data_get_bool($data, 'd'))->toBeTrue() + ->and(data_get_bool($data, 'e'))->toBeTrue(); + }); + + it('handles falsy string representations', function (): void { + $data = [ + 'a' => 'false', + 'b' => 'FALSE', + 'c' => '0', + 'd' => 'no', + 'e' => 'off', + ]; + + expect(data_get_bool($data, 'a'))->toBeFalse() + ->and(data_get_bool($data, 'b'))->toBeFalse() + ->and(data_get_bool($data, 'c'))->toBeFalse() + ->and(data_get_bool($data, 'd'))->toBeFalse() + ->and(data_get_bool($data, 'e'))->toBeFalse(); + }); + + it('returns default for unrecognized string values', function (): void { + $data = ['status' => 'maybe']; + + expect(data_get_bool($data, 'status'))->toBeFalse() + ->and(data_get_bool($data, 'status', true))->toBeTrue(); + }); + + it('handles integer values', function (): void { + $data = ['a' => 1, 'b' => 0, 'c' => 2]; + + expect(data_get_bool($data, 'a'))->toBeTrue() + ->and(data_get_bool($data, 'b'))->toBeFalse() + ->and(data_get_bool($data, 'c'))->toBeFalse() + ->and(data_get_bool($data, 'c', true))->toBeTrue(); + }); + + it('returns default for non-bool, non-string, non-int values', function (): void { + $data = ['items' => ['a', 'b'], 'price' => 19.99]; + + expect(data_get_bool($data, 'items'))->toBeFalse() + ->and(data_get_bool($data, 'items', true))->toBeTrue(); + }); }); From 91eefacd8e08a44ed106a3832f41592e081606e0 Mon Sep 17 00:00:00 2001 From: Mohammed Elhaouari Date: Sun, 22 Feb 2026 23:39:03 +0100 Subject: [PATCH 2/2] Add more tests --- src/helpers.php | 10 ++- tests/Api/Dto/ContactTest.php | 110 ++++++++++++++++++++++++++ tests/Api/Dto/MessageTemplateTest.php | 100 +++++++++++++++++++++++ tests/helpersTest.php | 19 +++-- 4 files changed, 233 insertions(+), 6 deletions(-) create mode 100644 tests/Api/Dto/ContactTest.php create mode 100644 tests/Api/Dto/MessageTemplateTest.php diff --git a/src/helpers.php b/src/helpers.php index 642bd18..74ac19d 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -23,7 +23,15 @@ function data_get_str(array $data, string $key, ?string $default = null): ?strin { $value = data_get_value($data, $key, $default); - return is_string($value) ? trim($value) : $default; + if (is_string($value)) { + return trim($value); + } + + if (is_scalar($value)) { + return (string) $value; + } + + return $default; } /** diff --git a/tests/Api/Dto/ContactTest.php b/tests/Api/Dto/ContactTest.php new file mode 100644 index 0000000..93ee4ed --- /dev/null +++ b/tests/Api/Dto/ContactTest.php @@ -0,0 +1,110 @@ + '123', + 'phone' => '+1234567890', + 'fullName' => 'John Doe', + 'wAid' => 'wa123', + 'firstName' => 'John', + 'email' => 'john@example.com', + 'contactStatus' => 'active', + 'created' => '2024-01-01', + 'lastUpdated' => '2024-01-02', + ]; + + $contact = Contact::fromArray($data); + + expect($contact->id)->toBe('123') + ->and($contact->phone)->toBe('+1234567890') + ->and($contact->fullName)->toBe('John Doe') + ->and($contact->wAid)->toBe('wa123') + ->and($contact->firstName)->toBe('John') + ->and($contact->email)->toBe('john@example.com') + ->and($contact->contactStatus)->toBe('active') + ->and($contact->created)->toBe('2024-01-01') + ->and($contact->lastUpdated)->toBe('2024-01-02'); + }); + + it('can be created from array with required fields only', function (): void { + $data = [ + 'id' => '123', + 'phone' => '+1234567890', + 'fullName' => 'John Doe', + ]; + + $contact = Contact::fromArray($data); + + expect($contact->id)->toBe('123') + ->and($contact->phone)->toBe('+1234567890') + ->and($contact->fullName)->toBe('John Doe') + ->and($contact->wAid)->toBeNull() + ->and($contact->firstName)->toBeNull() + ->and($contact->email)->toBeNull() + ->and($contact->contactStatus)->toBeNull() + ->and($contact->created)->toBeNull() + ->and($contact->lastUpdated)->toBeNull(); + }); + + it('handles empty array with defaults', function (): void { + $contact = Contact::fromArray([]); + + expect($contact->id)->toBe('') + ->and($contact->phone)->toBe('') + ->and($contact->fullName)->toBe(''); + }); + + it('trims string values', function (): void { + $data = [ + 'id' => ' 123 ', + 'phone' => ' +1234567890 ', + 'fullName' => ' John Doe ', + 'email' => ' john@example.com ', + ]; + + $contact = Contact::fromArray($data); + + expect($contact->id)->toBe('123') + ->and($contact->phone)->toBe('+1234567890') + ->and($contact->fullName)->toBe('John Doe') + ->and($contact->email)->toBe('john@example.com'); + }); + + it('handles null values in optional fields', function (): void { + $data = [ + 'id' => '123', + 'phone' => '+1234567890', + 'fullName' => 'John Doe', + 'wAid' => null, + 'firstName' => null, + 'email' => null, + ]; + + $contact = Contact::fromArray($data); + + expect($contact->wAid)->toBeNull() + ->and($contact->firstName)->toBeNull() + ->and($contact->email)->toBeNull(); + }); + + it('converts scalar values to strings', function (): void { + $data = [ + 'id' => 123, + 'phone' => 1234567890, + 'fullName' => ['John', 'Doe'], + ]; + + $contact = Contact::fromArray($data); + + expect($contact->id)->toBe('123') + ->and($contact->phone)->toBe('1234567890') + ->and($contact->fullName)->toBe(''); + }); +}); diff --git a/tests/Api/Dto/MessageTemplateTest.php b/tests/Api/Dto/MessageTemplateTest.php new file mode 100644 index 0000000..559e4ee --- /dev/null +++ b/tests/Api/Dto/MessageTemplateTest.php @@ -0,0 +1,100 @@ + 'template_123', + 'elementName' => 'welcome_message', + 'category' => 'MARKETING', + 'status' => 'APPROVED', + 'language' => 'en', + 'body' => 'Hello {{name}}!', + ]; + + $template = MessageTemplate::fromArray($data); + + expect($template->id)->toBe('template_123') + ->and($template->elementName)->toBe('welcome_message') + ->and($template->category)->toBe('MARKETING') + ->and($template->status)->toBe('APPROVED') + ->and($template->language)->toBe('en') + ->and($template->body)->toBe('Hello {{name}}!'); + }); + + it('can be created from array with required fields only', function (): void { + $data = [ + 'id' => 'template_123', + 'elementName' => 'welcome_message', + ]; + + $template = MessageTemplate::fromArray($data); + + expect($template->id)->toBe('template_123') + ->and($template->elementName)->toBe('welcome_message') + ->and($template->category)->toBeNull() + ->and($template->status)->toBeNull() + ->and($template->language)->toBeNull() + ->and($template->body)->toBeNull(); + }); + + it('handles empty array with defaults', function (): void { + $template = MessageTemplate::fromArray([]); + + expect($template->id)->toBe('') + ->and($template->elementName)->toBe(''); + }); + + it('trims string values', function (): void { + $data = [ + 'id' => ' template_123 ', + 'elementName' => ' welcome_message ', + 'category' => ' MARKETING ', + 'body' => ' Hello {{name}}! ', + ]; + + $template = MessageTemplate::fromArray($data); + + expect($template->id)->toBe('template_123') + ->and($template->elementName)->toBe('welcome_message') + ->and($template->category)->toBe('MARKETING') + ->and($template->body)->toBe('Hello {{name}}!'); + }); + + it('handles null values in optional fields', function (): void { + $data = [ + 'id' => 'template_123', + 'elementName' => 'welcome_message', + 'category' => null, + 'status' => null, + 'language' => null, + 'body' => null, + ]; + + $template = MessageTemplate::fromArray($data); + + expect($template->category)->toBeNull() + ->and($template->status)->toBeNull() + ->and($template->language)->toBeNull() + ->and($template->body)->toBeNull(); + }); + + it('converts scalar values to strings', function (): void { + $data = [ + 'id' => 123, + 'elementName' => ['welcome', 'message'], + 'category' => true, + ]; + + $template = MessageTemplate::fromArray($data); + + expect($template->id)->toBe('123') + ->and($template->elementName)->toBe('') + ->and($template->category)->toBe('1'); + }); +}); diff --git a/tests/helpersTest.php b/tests/helpersTest.php index 83fc34b..e9a1f5d 100644 --- a/tests/helpersTest.php +++ b/tests/helpersTest.php @@ -46,12 +46,21 @@ ->and(data_get_str($data, 'name', 'default'))->toBe('default'); }); - it('returns default when value is not a string', function (): void { - $data = ['count' => 42, 'active' => true]; + it('converts scalar values to string', function (): void { + $data = ['count' => 42, 'active' => true, 'price' => 19.99, 'flag' => false]; - expect(data_get_str($data, 'count'))->toBeNull() - ->and(data_get_str($data, 'count', 'default'))->toBe('default') - ->and(data_get_str($data, 'active'))->toBeNull(); + expect(data_get_str($data, 'count'))->toBe('42') + ->and(data_get_str($data, 'active'))->toBe('1') + ->and(data_get_str($data, 'price'))->toBe('19.99') + ->and(data_get_str($data, 'flag'))->toBe(''); + }); + + it('returns default for non-scalar values', function (): void { + $data = ['items' => ['a', 'b'], 'obj' => new stdClass]; + + expect(data_get_str($data, 'items'))->toBeNull() + ->and(data_get_str($data, 'items', 'default'))->toBe('default') + ->and(data_get_str($data, 'obj'))->toBeNull(); }); it('returns default when trimmed value is empty', function (): void {