From bb7abddc237addef931d9496ea1ad0b625bdef67 Mon Sep 17 00:00:00 2001 From: Dmitriy Ignatenko Date: Wed, 24 Jun 2026 14:08:08 +0400 Subject: [PATCH] Add messageservice methods --- .php-cs-fixer.php | 1 + CHANGELOG.md | 8 + Makefile | 12 ++ phpstan.neon.dist | 1 + phpunit.xml.dist | 9 + rector.php | 2 + .../Result/MessageStatusUpdateResult.php | 29 ++++ .../Message/Status/Service/MessageStatus.php | 63 +++++++ .../MessageserviceServiceBuilder.php | 48 ++++++ .../Sender/Result/SenderAddResult.php | 29 ++++ .../Sender/Result/SenderDeleteResult.php | 29 ++++ .../Sender/Result/SenderUpdateResult.php | 29 ++++ .../Sender/Result/SendersListResult.php | 33 ++++ .../Messageservice/Sender/Service/Sender.php | 154 +++++++++++++++++ src/Services/ServiceBuilder.php | 16 +- .../Status/Service/MessageStatusTest.php | 81 +++++++++ .../Sender/Service/SenderTest.php | 123 +++++++++++++ .../Status/Service/MessageStatusTest.php | 63 +++++++ .../Sender/Service/SenderTest.php | 162 ++++++++++++++++++ 19 files changed, 891 insertions(+), 1 deletion(-) create mode 100644 src/Services/Messageservice/Message/Status/Result/MessageStatusUpdateResult.php create mode 100644 src/Services/Messageservice/Message/Status/Service/MessageStatus.php create mode 100644 src/Services/Messageservice/MessageserviceServiceBuilder.php create mode 100644 src/Services/Messageservice/Sender/Result/SenderAddResult.php create mode 100644 src/Services/Messageservice/Sender/Result/SenderDeleteResult.php create mode 100644 src/Services/Messageservice/Sender/Result/SenderUpdateResult.php create mode 100644 src/Services/Messageservice/Sender/Result/SendersListResult.php create mode 100644 src/Services/Messageservice/Sender/Service/Sender.php create mode 100644 tests/Integration/Services/Messageservice/Message/Status/Service/MessageStatusTest.php create mode 100644 tests/Integration/Services/Messageservice/Sender/Service/SenderTest.php create mode 100644 tests/Unit/Services/Messageservice/Message/Status/Service/MessageStatusTest.php create mode 100644 tests/Unit/Services/Messageservice/Sender/Service/SenderTest.php diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index fbbe56ae..fd0ceef7 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -28,6 +28,7 @@ ->in(__DIR__ . '/src/Services/Calendar/') ->in(__DIR__ . '/src/Services/SonetGroup/') ->in(__DIR__ . '/src/Services/IMOpenLines/') + ->in(__DIR__ . '/src/Services/Messageservice/') ->name('*.php') ->exclude(['vendor', 'storage', 'docker', 'docs']) // Exclude directories ->ignoreDotFiles(true) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f141291..3b6bf1f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ ### Added +- Added service `Services\Messageservice\Sender` and `Services\Messageservice\Message\Status` with support for `messageservice.*` methods, + see [messageservice.* methods](https://apidocs.bitrix24.com/api-reference/messageservice/index.html) ([#498](https://github.com/bitrix24/b24phpsdk/issues/498)): + - `sender.add` — register a new SMS message service provider + - `sender.update` — update a registered message service provider + - `sender.list` — get list of sender codes registered by the current application + - `sender.delete` — delete a registered message service provider + - `message.status.update` — update delivery status of a message sent via a provider + - Added support for events: - `onCrmDocumentGeneratorDocumentAdd` — fires when a document is created, see [event documentation](https://apidocs.bitrix24.com/api-reference/crm/document-generator/documents/events/on-crm-document-generator-document-add.html) diff --git a/Makefile b/Makefile index d3555c4f..51e482ad 100644 --- a/Makefile +++ b/Makefile @@ -445,6 +445,18 @@ integration_tests_crm_documentgenerator_document: integration_tests_crm_documentgenerator_template: docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_crm_documentgenerator_template +.PHONY: test-integration-scope-messageservice +test-integration-scope-messageservice: + docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_scope_messageservice + +.PHONY: test-integration-messageservice-sender +test-integration-messageservice-sender: + docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_messageservice_sender + +.PHONY: test-integration-messageservice-message-status +test-integration-messageservice-message-status: + docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_messageservice_message_status + # work dev environment .PHONY: php-dev-server-up php-dev-server-up: diff --git a/phpstan.neon.dist b/phpstan.neon.dist index bb074ed2..b3581bb2 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -36,6 +36,7 @@ parameters: - tests/Integration/Services/CRM/Documentgenerator/Numerator - tests/Integration/Services/CRM/Documentgenerator/Document - tests/Integration/Services/CRM/Documentgenerator/Template + - tests/Integration/Services/Messageservice excludePaths: - tests/Integration/Services/CRM/Requisites/Service/RequisiteUserfieldUseCaseTest.php - tests/Integration/Services/CRM/Status diff --git a/phpunit.xml.dist b/phpunit.xml.dist index e9c12ee3..a4292328 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -232,6 +232,15 @@ ./tests/Integration/Services/SonetGroup/ + + ./tests/Integration/Services/Messageservice/ + + + ./tests/Integration/Services/Messageservice/Sender/ + + + ./tests/Integration/Services/Messageservice/Message/Status/ + diff --git a/rector.php b/rector.php index c35b39eb..d9180f4d 100644 --- a/rector.php +++ b/rector.php @@ -76,6 +76,8 @@ __DIR__ . '/tests/Integration/Services/CRM/Documentgenerator/Document', __DIR__ . '/src/Services/CRM/Documentgenerator/Template', __DIR__ . '/tests/Integration/Services/CRM/Documentgenerator/Template', + __DIR__ . '/src/Services/Messageservice', + __DIR__ . '/tests/Integration/Services/Messageservice', __DIR__ . '/tests/Unit/', ]) ->withCache(cacheDirectory: __DIR__ . '/var/.cache/rector') diff --git a/src/Services/Messageservice/Message/Status/Result/MessageStatusUpdateResult.php b/src/Services/Messageservice/Message/Status/Result/MessageStatusUpdateResult.php new file mode 100644 index 00000000..35a5a5c4 --- /dev/null +++ b/src/Services/Messageservice/Message/Status/Result/MessageStatusUpdateResult.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Messageservice\Message\Status\Result; + +use Bitrix24\SDK\Core\Result\AbstractResult; + +class MessageStatusUpdateResult extends AbstractResult +{ + /** + * Check if message status was updated successfully. + * + * @throws \Bitrix24\SDK\Core\Exceptions\BaseException + */ + public function isSuccess(): bool + { + return (bool)$this->getCoreResponse()->getResponseData()->getResult(); + } +} diff --git a/src/Services/Messageservice/Message/Status/Service/MessageStatus.php b/src/Services/Messageservice/Message/Status/Service/MessageStatus.php new file mode 100644 index 00000000..2a035d0e --- /dev/null +++ b/src/Services/Messageservice/Message/Status/Service/MessageStatus.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Messageservice\Message\Status\Service; + +use Bitrix24\SDK\Attributes\ApiEndpointMetadata; +use Bitrix24\SDK\Attributes\ApiServiceMetadata; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Services\AbstractService; +use Bitrix24\SDK\Services\Messageservice\Message\Status\Result\MessageStatusUpdateResult; + +#[ApiServiceMetadata(new Scope(['messageservice']))] +class MessageStatus extends AbstractService +{ + /** + * Update delivery status of a message sent via a message service provider. + * + * Supported status values: + * - queued — message is queued for sending + * - sent — message was sent by the provider + * - delivered — message was successfully delivered to the recipient + * - undelivered — message was not delivered to the recipient + * - failed — provider encountered a sending or processing error + * + * @param string $code Sender code. Can be retrieved via messageservice.sender.list + * @param string $messageId External message identifier received by the handler on message send + * @param string $status New message status + * + * @throws BaseException + * @throws TransportException + * @link https://apidocs.bitrix24.com/api-reference/messageservice/messageservice-message-status-update.html + */ + #[ApiEndpointMetadata( + 'messageservice.message.status.update', + 'https://apidocs.bitrix24.com/api-reference/messageservice/messageservice-message-status-update.html', + 'Update delivery status of a message sent via a message service provider' + )] + public function update( + string $code, + string $messageId, + string $status + ): MessageStatusUpdateResult { + return new MessageStatusUpdateResult( + $this->core->call('messageservice.message.status.update', [ + 'CODE' => $code, + 'MESSAGE_ID' => $messageId, + 'STATUS' => $status, + ]) + ); + } +} diff --git a/src/Services/Messageservice/MessageserviceServiceBuilder.php b/src/Services/Messageservice/MessageserviceServiceBuilder.php new file mode 100644 index 00000000..241aa512 --- /dev/null +++ b/src/Services/Messageservice/MessageserviceServiceBuilder.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Messageservice; + +use Bitrix24\SDK\Attributes\ApiServiceBuilderMetadata; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Services\AbstractServiceBuilder; +use Bitrix24\SDK\Services\Messageservice\Message\Status\Service\MessageStatus; +use Bitrix24\SDK\Services\Messageservice\Sender\Service\Sender; + +#[ApiServiceBuilderMetadata(new Scope(['messageservice']))] +class MessageserviceServiceBuilder extends AbstractServiceBuilder +{ + public function sender(): Sender + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new Sender( + $this->core, + $this->log + ); + } + + return $this->serviceCache[__METHOD__]; + } + + public function messageStatus(): MessageStatus + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new MessageStatus( + $this->core, + $this->log + ); + } + + return $this->serviceCache[__METHOD__]; + } +} diff --git a/src/Services/Messageservice/Sender/Result/SenderAddResult.php b/src/Services/Messageservice/Sender/Result/SenderAddResult.php new file mode 100644 index 00000000..4aa1c1cb --- /dev/null +++ b/src/Services/Messageservice/Sender/Result/SenderAddResult.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Messageservice\Sender\Result; + +use Bitrix24\SDK\Core\Result\AbstractResult; + +class SenderAddResult extends AbstractResult +{ + /** + * Check if sender was registered successfully. + * + * @throws \Bitrix24\SDK\Core\Exceptions\BaseException + */ + public function isSuccess(): bool + { + return (bool)$this->getCoreResponse()->getResponseData()->getResult(); + } +} diff --git a/src/Services/Messageservice/Sender/Result/SenderDeleteResult.php b/src/Services/Messageservice/Sender/Result/SenderDeleteResult.php new file mode 100644 index 00000000..d36d98de --- /dev/null +++ b/src/Services/Messageservice/Sender/Result/SenderDeleteResult.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Messageservice\Sender\Result; + +use Bitrix24\SDK\Core\Result\AbstractResult; + +class SenderDeleteResult extends AbstractResult +{ + /** + * Check if sender was deleted successfully. + * + * @throws \Bitrix24\SDK\Core\Exceptions\BaseException + */ + public function isSuccess(): bool + { + return (bool)$this->getCoreResponse()->getResponseData()->getResult(); + } +} diff --git a/src/Services/Messageservice/Sender/Result/SenderUpdateResult.php b/src/Services/Messageservice/Sender/Result/SenderUpdateResult.php new file mode 100644 index 00000000..2d591961 --- /dev/null +++ b/src/Services/Messageservice/Sender/Result/SenderUpdateResult.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Messageservice\Sender\Result; + +use Bitrix24\SDK\Core\Result\AbstractResult; + +class SenderUpdateResult extends AbstractResult +{ + /** + * Check if sender was updated successfully. + * + * @throws \Bitrix24\SDK\Core\Exceptions\BaseException + */ + public function isSuccess(): bool + { + return (bool)$this->getCoreResponse()->getResponseData()->getResult(); + } +} diff --git a/src/Services/Messageservice/Sender/Result/SendersListResult.php b/src/Services/Messageservice/Sender/Result/SendersListResult.php new file mode 100644 index 00000000..c32788b8 --- /dev/null +++ b/src/Services/Messageservice/Sender/Result/SendersListResult.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Messageservice\Sender\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Result\AbstractResult; + +class SendersListResult extends AbstractResult +{ + /** + * Get list of registered sender codes. + * + * @return string[] + * @throws BaseException + */ + public function getSenderCodes(): array + { + $result = $this->getCoreResponse()->getResponseData()->getResult(); + + return is_array($result) ? array_values(array_map('strval', $result)) : []; + } +} diff --git a/src/Services/Messageservice/Sender/Service/Sender.php b/src/Services/Messageservice/Sender/Service/Sender.php new file mode 100644 index 00000000..a549c556 --- /dev/null +++ b/src/Services/Messageservice/Sender/Service/Sender.php @@ -0,0 +1,154 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Messageservice\Sender\Service; + +use Bitrix24\SDK\Attributes\ApiEndpointMetadata; +use Bitrix24\SDK\Attributes\ApiServiceMetadata; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Services\AbstractService; +use Bitrix24\SDK\Services\Messageservice\Sender\Result\SenderAddResult; +use Bitrix24\SDK\Services\Messageservice\Sender\Result\SenderDeleteResult; +use Bitrix24\SDK\Services\Messageservice\Sender\Result\SenderUpdateResult; +use Bitrix24\SDK\Services\Messageservice\Sender\Result\SendersListResult; + +#[ApiServiceMetadata(new Scope(['messageservice']))] +class Sender extends AbstractService +{ + /** + * Register a new message service provider (sender). + * + * @param string $code Sender code. Allowed characters: a-z, A-Z, 0-9, ., -, _ + * @param string $type Provider type. Supported value: SMS + * @param string $handler Application handler URL called on message send + * @param string|array $name Provider name. Can be a string or an associative array of localized strings + * @param string|array|null $description Provider description. Can be a string or localized array + * + * @throws BaseException + * @throws TransportException + * @link https://apidocs.bitrix24.com/api-reference/messageservice/messageservice-sender-add.html + */ + #[ApiEndpointMetadata( + 'messageservice.sender.add', + 'https://apidocs.bitrix24.com/api-reference/messageservice/messageservice-sender-add.html', + 'Register a new message service provider (sender)' + )] + public function add( + string $code, + string $type, + string $handler, + string|array $name, + string|array|null $description = null + ): SenderAddResult { + $params = [ + 'CODE' => $code, + 'TYPE' => $type, + 'HANDLER' => $handler, + 'NAME' => $name, + ]; + + if ($description !== null) { + $params['DESCRIPTION'] = $description; + } + + return new SenderAddResult( + $this->core->call('messageservice.sender.add', $params) + ); + } + + /** + * Update a registered message service provider (sender). + * + * @param string $code Sender code to update. Can be retrieved via messageservice.sender.list + * @param string|null $handler New application handler URL + * @param string|array|null $name New provider name. Can be a string or localized array + * @param string|array|null $description New provider description. Can be a string or localized array + * + * @throws BaseException + * @throws TransportException + * @link https://apidocs.bitrix24.com/api-reference/messageservice/messageservice-sender-update.html + */ + #[ApiEndpointMetadata( + 'messageservice.sender.update', + 'https://apidocs.bitrix24.com/api-reference/messageservice/messageservice-sender-update.html', + 'Update a registered message service provider (sender)' + )] + public function update( + string $code, + string|null $handler = null, + string|array|null $name = null, + string|array|null $description = null + ): SenderUpdateResult { + $params = [ + 'CODE' => $code, + ]; + + if ($handler !== null) { + $params['HANDLER'] = $handler; + } + + if ($name !== null) { + $params['NAME'] = $name; + } + + if ($description !== null) { + $params['DESCRIPTION'] = $description; + } + + return new SenderUpdateResult( + $this->core->call('messageservice.sender.update', $params) + ); + } + + /** + * Get list of sender codes registered by the current application. + * + * @throws BaseException + * @throws TransportException + * @link https://apidocs.bitrix24.com/api-reference/messageservice/messageservice-sender-list.html + */ + #[ApiEndpointMetadata( + 'messageservice.sender.list', + 'https://apidocs.bitrix24.com/api-reference/messageservice/messageservice-sender-list.html', + 'Get list of sender codes registered by the current application' + )] + public function list(): SendersListResult + { + return new SendersListResult( + $this->core->call('messageservice.sender.list', []) + ); + } + + /** + * Delete a registered message service provider (sender). + * + * @param string $code Sender code to delete. Can be retrieved via messageservice.sender.list + * + * @throws BaseException + * @throws TransportException + * @link https://apidocs.bitrix24.com/api-reference/messageservice/messageservice-sender-delete.html + */ + #[ApiEndpointMetadata( + 'messageservice.sender.delete', + 'https://apidocs.bitrix24.com/api-reference/messageservice/messageservice-sender-delete.html', + 'Delete a registered message service provider (sender)' + )] + public function delete(string $code): SenderDeleteResult + { + return new SenderDeleteResult( + $this->core->call('messageservice.sender.delete', ['CODE' => $code]) + ); + } +} diff --git a/src/Services/ServiceBuilder.php b/src/Services/ServiceBuilder.php index e76b5e06..450024d2 100644 --- a/src/Services/ServiceBuilder.php +++ b/src/Services/ServiceBuilder.php @@ -36,6 +36,7 @@ use Bitrix24\SDK\Services\Calendar\CalendarServiceBuilder; use Bitrix24\SDK\Services\Paysystem\PaysystemServiceBuilder; use Bitrix24\SDK\Services\SonetGroup\SonetGroupServiceBuilder; +use Bitrix24\SDK\Services\Messageservice\MessageserviceServiceBuilder; use Psr\Log\LoggerInterface; class ServiceBuilder extends AbstractServiceBuilder @@ -334,5 +335,18 @@ public function getSonetGroupScope(): SonetGroupServiceBuilder return $this->serviceCache[__METHOD__]; } - + + public function getMessageserviceScope(): MessageserviceServiceBuilder + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new MessageserviceServiceBuilder( + $this->core, + $this->batch, + $this->bulkItemsReader, + $this->log + ); + } + + return $this->serviceCache[__METHOD__]; + } } diff --git a/tests/Integration/Services/Messageservice/Message/Status/Service/MessageStatusTest.php b/tests/Integration/Services/Messageservice/Message/Status/Service/MessageStatusTest.php new file mode 100644 index 00000000..869a5971 --- /dev/null +++ b/tests/Integration/Services/Messageservice/Message/Status/Service/MessageStatusTest.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Tests\Integration\Services\Messageservice\Message\Status\Service; + +use Bitrix24\SDK\Services\Messageservice\Message\Status\Service\MessageStatus; +use Bitrix24\SDK\Services\Messageservice\Sender\Service\Sender; +use Bitrix24\SDK\Tests\Integration\Fabric; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\Attributes\TestDox; +use PHPUnit\Framework\TestCase; + +#[CoversClass(MessageStatus::class)] +class MessageStatusTest extends TestCase +{ + private MessageStatus $messageStatus; + + private Sender $sender; + + private string $testSenderCode = 'test_sdk_msg_status_1'; + + #[\Override] + protected function setUp(): void + { + $messageserviceServiceBuilder = Fabric::getServiceBuilder(true)->getMessageserviceScope(); + $this->messageStatus = $messageserviceServiceBuilder->messageStatus(); + $this->sender = $messageserviceServiceBuilder->sender(); + + // Ensure cleanup before test + try { + $this->sender->delete($this->testSenderCode); + } catch (\Throwable) { + // Ignore if sender does not exist + } + + // Register a sender to use in tests + $this->sender->add( + code: $this->testSenderCode, + type: 'SMS', + handler: 'https://provider.example/api/handler', + name: 'Test SDK Message Status Sender' + ); + } + + #[\Override] + protected function tearDown(): void + { + try { + $this->sender->delete($this->testSenderCode); + } catch (\Throwable) { + // Ignore + } + } + + #[Test] + #[TestDox('messageservice.message.status.update returns error for unknown message id (expected API error)')] + public function testUpdateReturnsExpectedErrorForUnknownMessage(): void + { + // The messageservice.message.status.update requires a real MESSAGE_ID from an actual sent message. + // Since integration tests cannot send real SMS, we verify that the API correctly rejects + // an unknown message ID with the expected error code. + $this->expectException(\Bitrix24\SDK\Core\Exceptions\BaseException::class); + + $this->messageStatus->update( + code: $this->testSenderCode, + messageId: 'nonexistent_message_id_for_testing', + status: 'delivered' + ); + } +} diff --git a/tests/Integration/Services/Messageservice/Sender/Service/SenderTest.php b/tests/Integration/Services/Messageservice/Sender/Service/SenderTest.php new file mode 100644 index 00000000..ef1f3d94 --- /dev/null +++ b/tests/Integration/Services/Messageservice/Sender/Service/SenderTest.php @@ -0,0 +1,123 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Tests\Integration\Services\Messageservice\Sender\Service; + +use Bitrix24\SDK\Services\Messageservice\Sender\Service\Sender; +use Bitrix24\SDK\Tests\Integration\Fabric; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\Attributes\TestDox; +use PHPUnit\Framework\TestCase; + +#[CoversClass(Sender::class)] +class SenderTest extends TestCase +{ + private Sender $sender; + + private string $testSenderCode = 'test_sdk_sender_1'; + + #[\Override] + protected function setUp(): void + { + $this->sender = Fabric::getServiceBuilder(true)->getMessageserviceScope()->sender(); + // Ensure cleanup before each test + try { + $this->sender->delete($this->testSenderCode); + } catch (\Throwable) { + // Ignore if sender does not exist + } + } + + #[\Override] + protected function tearDown(): void + { + // Cleanup after each test + try { + $this->sender->delete($this->testSenderCode); + } catch (\Throwable) { + // Ignore if sender was already deleted + } + } + + #[Test] + #[TestDox('messageservice.sender.add registers a new sender successfully')] + public function testAdd(): void + { + $senderAddResult = $this->sender->add( + code: $this->testSenderCode, + type: 'SMS', + handler: 'https://provider.example/api/handler', + name: 'Test SDK Sender' + ); + + $this->assertTrue($senderAddResult->isSuccess()); + } + + #[Test] + #[TestDox('messageservice.sender.list returns array of sender codes')] + public function testList(): void + { + // Register a sender first + $this->sender->add( + code: $this->testSenderCode, + type: 'SMS', + handler: 'https://provider.example/api/handler', + name: 'Test SDK Sender' + ); + + $sendersListResult = $this->sender->list(); + $codes = $sendersListResult->getSenderCodes(); + + $this->assertIsArray($codes); + $this->assertContains($this->testSenderCode, $codes); + } + + #[Test] + #[TestDox('messageservice.sender.update updates an existing sender successfully')] + public function testUpdate(): void + { + // Register a sender first + $this->sender->add( + code: $this->testSenderCode, + type: 'SMS', + handler: 'https://provider.example/api/handler', + name: 'Test SDK Sender' + ); + + $senderUpdateResult = $this->sender->update( + code: $this->testSenderCode, + handler: 'https://provider.example/api/new-handler', + name: 'Test SDK Sender Updated' + ); + + $this->assertTrue($senderUpdateResult->isSuccess()); + } + + #[Test] + #[TestDox('messageservice.sender.delete removes an existing sender successfully')] + public function testDelete(): void + { + // Register a sender first + $this->sender->add( + code: $this->testSenderCode, + type: 'SMS', + handler: 'https://provider.example/api/handler', + name: 'Test SDK Sender' + ); + + $senderDeleteResult = $this->sender->delete($this->testSenderCode); + + $this->assertTrue($senderDeleteResult->isSuccess()); + } +} diff --git a/tests/Unit/Services/Messageservice/Message/Status/Service/MessageStatusTest.php b/tests/Unit/Services/Messageservice/Message/Status/Service/MessageStatusTest.php new file mode 100644 index 00000000..f2ac7840 --- /dev/null +++ b/tests/Unit/Services/Messageservice/Message/Status/Service/MessageStatusTest.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Tests\Unit\Services\Messageservice\Message\Status\Service; + +use Bitrix24\SDK\Core\Contracts\CoreInterface; +use Bitrix24\SDK\Core\Response\Response; +use Bitrix24\SDK\Services\Messageservice\Message\Status\Result\MessageStatusUpdateResult; +use Bitrix24\SDK\Services\Messageservice\Message\Status\Service\MessageStatus; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\TestDox; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; + +#[CoversClass(MessageStatus::class)] +class MessageStatusTest extends TestCase +{ + #[TestDox('Test MessageStatus service can be instantiated')] + public function testCanBeInstantiated(): void + { + $core = $this->createStub(CoreInterface::class); + $messageStatus = new MessageStatus($core, new NullLogger()); + $this->assertInstanceOf(MessageStatus::class, $messageStatus); + } + + #[TestDox('Test MessageStatus::update builds correct parameters')] + public function testUpdateBuildsCorrectParameters(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $core->expects($this->once()) + ->method('call') + ->with( + 'messageservice.message.status.update', + [ + 'CODE' => 'provider1', + 'MESSAGE_ID' => '65575980fa531ac284c2ee68f81ebebd', + 'STATUS' => 'delivered', + ] + ) + ->willReturn($response); + + $messageStatus = new MessageStatus($core, new NullLogger()); + $messageStatusUpdateResult = $messageStatus->update( + code: 'provider1', + messageId: '65575980fa531ac284c2ee68f81ebebd', + status: 'delivered' + ); + + $this->assertInstanceOf(MessageStatusUpdateResult::class, $messageStatusUpdateResult); + } +} diff --git a/tests/Unit/Services/Messageservice/Sender/Service/SenderTest.php b/tests/Unit/Services/Messageservice/Sender/Service/SenderTest.php new file mode 100644 index 00000000..12c5f94f --- /dev/null +++ b/tests/Unit/Services/Messageservice/Sender/Service/SenderTest.php @@ -0,0 +1,162 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Tests\Unit\Services\Messageservice\Sender\Service; + +use Bitrix24\SDK\Core\Contracts\CoreInterface; +use Bitrix24\SDK\Core\Response\Response; +use Bitrix24\SDK\Services\Messageservice\Sender\Result\SenderAddResult; +use Bitrix24\SDK\Services\Messageservice\Sender\Result\SenderDeleteResult; +use Bitrix24\SDK\Services\Messageservice\Sender\Result\SenderUpdateResult; +use Bitrix24\SDK\Services\Messageservice\Sender\Result\SendersListResult; +use Bitrix24\SDK\Services\Messageservice\Sender\Service\Sender; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\TestDox; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; + +#[CoversClass(Sender::class)] +class SenderTest extends TestCase +{ + #[TestDox('Test Sender service can be instantiated')] + public function testCanBeInstantiated(): void + { + $core = $this->createStub(CoreInterface::class); + $sender = new Sender($core, new NullLogger()); + $this->assertInstanceOf(Sender::class, $sender); + } + + #[TestDox('Test Sender::add builds correct parameters')] + public function testAddBuildsCorrectParameters(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $core->expects($this->once()) + ->method('call') + ->with( + 'messageservice.sender.add', + [ + 'CODE' => 'provider1', + 'TYPE' => 'SMS', + 'HANDLER' => 'https://provider.example/api/handler', + 'NAME' => 'Provider 1', + 'DESCRIPTION' => 'Main SMS provider', + ] + ) + ->willReturn($response); + + $sender = new Sender($core, new NullLogger()); + $senderAddResult = $sender->add( + code: 'provider1', + type: 'SMS', + handler: 'https://provider.example/api/handler', + name: 'Provider 1', + description: 'Main SMS provider' + ); + + $this->assertInstanceOf(SenderAddResult::class, $senderAddResult); + } + + #[TestDox('Test Sender::add without optional description')] + public function testAddWithoutDescription(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $core->expects($this->once()) + ->method('call') + ->with( + 'messageservice.sender.add', + [ + 'CODE' => 'provider1', + 'TYPE' => 'SMS', + 'HANDLER' => 'https://provider.example/api/handler', + 'NAME' => 'Provider 1', + ] + ) + ->willReturn($response); + + $sender = new Sender($core, new NullLogger()); + $senderAddResult = $sender->add( + code: 'provider1', + type: 'SMS', + handler: 'https://provider.example/api/handler', + name: 'Provider 1' + ); + + $this->assertInstanceOf(SenderAddResult::class, $senderAddResult); + } + + #[TestDox('Test Sender::update builds correct parameters')] + public function testUpdateBuildsCorrectParameters(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $core->expects($this->once()) + ->method('call') + ->with( + 'messageservice.sender.update', + [ + 'CODE' => 'provider1', + 'HANDLER' => 'https://provider.example/api/new-handler', + 'NAME' => 'Provider 1 Updated', + ] + ) + ->willReturn($response); + + $sender = new Sender($core, new NullLogger()); + $senderUpdateResult = $sender->update( + code: 'provider1', + handler: 'https://provider.example/api/new-handler', + name: 'Provider 1 Updated' + ); + + $this->assertInstanceOf(SenderUpdateResult::class, $senderUpdateResult); + } + + #[TestDox('Test Sender::list calls correct API method')] + public function testListCallsCorrectMethod(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $core->expects($this->once()) + ->method('call') + ->with('messageservice.sender.list', []) + ->willReturn($response); + + $sender = new Sender($core, new NullLogger()); + $sendersListResult = $sender->list(); + + $this->assertInstanceOf(SendersListResult::class, $sendersListResult); + } + + #[TestDox('Test Sender::delete builds correct parameters')] + public function testDeleteBuildsCorrectParameters(): void + { + $core = $this->createMock(CoreInterface::class); + $response = $this->createStub(Response::class); + + $core->expects($this->once()) + ->method('call') + ->with('messageservice.sender.delete', ['CODE' => 'provider1']) + ->willReturn($response); + + $sender = new Sender($core, new NullLogger()); + $senderDeleteResult = $sender->delete('provider1'); + + $this->assertInstanceOf(SenderDeleteResult::class, $senderDeleteResult); + } +}