diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 439dbf0..ef196f5 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -27,7 +27,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ['8.1', '8.2', '8.3'] + php-versions: ['8.1', '8.2', '8.3', '8.4'] steps: - name: Checkout diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 7165e73..e5a2748 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -32,7 +32,7 @@ jobs: if: (! contains(github.event.head_commit.message, '[ci skip]')) strategy: matrix: - php-versions: ['8.1', '8.2', '8.3'] + php-versions: ['8.1', '8.2', '8.3', '8.4'] db-platforms: ['MySQLi', 'SQLite3'] mysql-versions: ['5.7'] dependencies: ['highest'] @@ -55,8 +55,8 @@ jobs: # SQLSRV - php-versions: '8.1' db-platforms: SQLSRV - mysql-versions: '5.7' - dependencies: 'highest' + mysql-versions: '8.0' + dependencies: 'lowest' # OCI8 - php-versions: '8.1' db-platforms: OCI8 @@ -84,15 +84,18 @@ jobs: options: --health-cmd=pg_isready --health-interval=10s --health-timeout=5s --health-retries=3 mssql: - image: mcr.microsoft.com/mssql/server:2019-CU28-ubuntu-20.04 + image: mcr.microsoft.com/mssql/server:2022-latest env: - SA_PASSWORD: 1Secure*Password1 + MSSQL_SA_PASSWORD: 1Secure*Password1 ACCEPT_EULA: Y MSSQL_PID: Developer - MSSQL_ENCRYPT: optional ports: - 1433:1433 - options: --health-cmd="/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U sa -P 1Secure*Password1 -Q 'SELECT @@VERSION' -N -C" --health-interval=10s --health-timeout=5s --health-retries=3 + options: >- + --health-cmd="/opt/mssql-tools18/bin/sqlcmd -C -S 127.0.0.1 -U sa -P 1Secure*Password1 -Q 'SELECT @@VERSION'" + --health-interval=10s + --health-timeout=5s + --health-retries=3 oracle: image: gvenzl/oracle-xe:18 @@ -109,6 +112,22 @@ jobs: --health-retries 10 steps: + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@main + with: + # this might remove tools that are actually needed, + # if set to "true" but frees about 6 GB + tool-cache: false + + # all of these default to true, but feel free to set to + # "false" if necessary for your workflow + android: true + dotnet: true + haskell: true + large-packages: false + docker-images: true + swap-storage: true + - name: Create database for MSSQL Server if: matrix.db-platforms == 'SQLSRV' run: sqlcmd -S 127.0.0.1 -U sa -P 1Secure*Password1 -Q "CREATE DATABASE test" @@ -147,7 +166,7 @@ jobs: COMPOSER_UPDATE_FLAGS: ${{ matrix.dependencies == 'lowest' && '--prefer-lowest' || '' }} - name: Test with PHPUnit - run: vendor/bin/phpunit --debug --coverage-text --testsuite main + run: vendor/bin/phpunit --coverage-text --testsuite main env: DB: ${{ matrix.db-platforms }} TERM: xterm-256color diff --git a/.github/workflows/rector.yml b/.github/workflows/rector.yml index 7c2a7d5..bdd37dc 100644 --- a/.github/workflows/rector.yml +++ b/.github/workflows/rector.yml @@ -27,7 +27,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ['8.1', '8.2', '8.3'] + php-versions: ['8.1', '8.2', '8.3', '8.4'] steps: - name: Checkout diff --git a/composer.json b/composer.json index 4b97be5..1c9c311 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "codeigniter4/framework": "^4.2.7", "mikey179/vfsstream": "^1.6.7", "mockery/mockery": "^1.0", - "rector/rector": "1.2.8" + "rector/rector": "^2.0" }, "minimum-stability": "dev", "prefer-stable": true, diff --git a/php-cs-fixer.dist.php b/php-cs-fixer.dist.php index 28ed0ee..8f66124 100644 --- a/php-cs-fixer.dist.php +++ b/php-cs-fixer.dist.php @@ -45,5 +45,5 @@ return Factory::create(new CodeIgniter4(), $overrides, $options)->forLibrary( 'CodeIgniter SMSRocket', 'Pooya Parsa Dadashi', - 'admin@codeigniter4.ir' + 'admin@codeigniter4.ir', ); diff --git a/phpstan-baseline.php b/phpstan-baseline.php index cf60819..5b2e1b4 100644 --- a/phpstan-baseline.php +++ b/phpstan-baseline.php @@ -2,26 +2,10 @@ $ignoreErrors = []; -$ignoreErrors[] = [ - 'message' => '#^Access to an undefined property hasProperty\\(Status\\)\\:\\:\\$Data\\.$#', - 'count' => 3, - 'path' => __DIR__ . '/src/Drivers/AmootsmsDriver.php', -]; - -$ignoreErrors[] = [ - 'message' => '#^Access to an undefined property hasProperty\\(status\\)\\:\\:\\$data\\.$#', - 'count' => 3, - 'path' => __DIR__ . '/src/Drivers/IdehpardazanDriver.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Access to an undefined property hasProperty\\(status\\)\\:\\:\\$data\\.$#', - 'count' => 2, - 'path' => __DIR__ . '/src/Drivers/FarazsmsDriver.php', -]; -$ignoreErrors[] = [ - 'message' => '#Access to an undefined property hasProperty\(sid\)::\$status.#', - 'count' => 1, - 'path' => __DIR__ . '/src/Drivers/TwilioDriver.php', -]; +// $ignoreErrors[] = [ +// 'message' => '#^Access to an undefined property hasProperty\\(Status\\)\\:\\:\\$Data\\.$#', +// 'count' => 3, +// 'path' => __DIR__ . '/src/Drivers/AmootsmsDriver.php', +// ]; return ['parameters' => ['ignoreErrors' => $ignoreErrors]]; diff --git a/psalm.xml b/psalm.xml index ee76813..e02e076 100644 --- a/psalm.xml +++ b/psalm.xml @@ -11,6 +11,7 @@ errorBaseline="psalm-baseline.xml" findUnusedBaselineEntry="false" findUnusedCode="false" + ensureOverrideAttribute="false" > diff --git a/rector.php b/rector.php index 5a41e84..61db3b5 100644 --- a/rector.php +++ b/rector.php @@ -92,7 +92,7 @@ TypedPropertyFromAssignsRector::class => [ __DIR__ . '/src/Models/SMSLogModel.php', - + __DIR__ . '/tests/_support/DatabaseTestCase.php', __DIR__ . '/tests/_support/Config/Registrar.php', ], ]); diff --git a/src/Enums/Amootsms/DeliveryStatus.php b/src/Enums/Amootsms/DeliveryStatus.php index 827d598..49971c3 100644 --- a/src/Enums/Amootsms/DeliveryStatus.php +++ b/src/Enums/Amootsms/DeliveryStatus.php @@ -18,6 +18,26 @@ */ enum DeliveryStatus: int { + case SendToTci = 0; + case RecievedPhone = 1; + case NotRecievedPhone = 2; + case TciError = 3; + case UnknownError = 5; + case TciReceived = 8; + case NotTciReceived = 16; + case BlackList = 35; + case Unknown = 100; + case Sent = 200; + case Filtered = 300; + case SendingList = 400; + case NoReceipt = 500; + case SendWithAvanak = 501; + case SendWithBackupVtel = 502; + case SendingQueue = 900; + case WrongNumber = 950; + case EmptyMessage = 951; + case ShortCodeInvalid = 952; + /** * Get the delivery status title directly from the code. */ @@ -68,23 +88,4 @@ public static function fromCode(int|string $code): DeliveryStatus default => self::Unknown, // Return Unknown as default if code is invalid }; } - case SendToTci = 0; - case RecievedPhone = 1; - case NotRecievedPhone = 2; - case TciError = 3; - case UnknownError = 5; - case TciReceived = 8; - case NotTciReceived = 16; - case BlackList = 35; - case Unknown = 100; - case Sent = 200; - case Filtered = 300; - case SendingList = 400; - case NoReceipt = 500; - case SendWithAvanak = 501; - case SendWithBackupVtel = 502; - case SendingQueue = 900; - case WrongNumber = 950; - case EmptyMessage = 951; - case ShortCodeInvalid = 952; } diff --git a/src/Enums/Farazsms/DeliveryStatus.php b/src/Enums/Farazsms/DeliveryStatus.php index 98b4df4..5bf7f1f 100644 --- a/src/Enums/Farazsms/DeliveryStatus.php +++ b/src/Enums/Farazsms/DeliveryStatus.php @@ -18,6 +18,13 @@ */ enum DeliveryStatus: int { + case Delivered = 2; + case Discarded = 4; + case Pending = 1; + case Failed = 3; + case Send = 0; + case Unknown = 99; // Default status for unknown codes + /** * Get the delivery status title directly from the code. */ @@ -54,11 +61,4 @@ public static function fromCode(int|string $code): DeliveryStatus default => self::Unknown, // Return Unknown as default if code is invalid }; } - - case Delivered = 2; - case Discarded = 4; - case Pending = 1; - case Failed = 3; - case Send = 0; - case Unknown = 99; // Default status for unknown codes } diff --git a/src/Enums/Idehpardazan/DeliveryStatus.php b/src/Enums/Idehpardazan/DeliveryStatus.php index 61d30e8..e3c7666 100644 --- a/src/Enums/Idehpardazan/DeliveryStatus.php +++ b/src/Enums/Idehpardazan/DeliveryStatus.php @@ -18,6 +18,15 @@ */ enum DeliveryStatus: int { + case Recieved = 1; + case NotRecievedPhone = 2; + case RecievedToTci = 3; + case NotRecievedToTci = 4; + case RecievedToOperator = 5; + case Failed = 6; + case BlackList = 7; + case Unknown = 8; + /** * Get the delivery status title directly from the code. */ @@ -57,13 +66,4 @@ public static function fromCode(int|string $code): DeliveryStatus default => self::Unknown, // Return Unknown as default if code is invalid }; } - - case Recieved = 1; - case NotRecievedPhone = 2; - case RecievedToTci = 3; - case NotRecievedToTci = 4; - case RecievedToOperator = 5; - case Failed = 6; - case BlackList = 7; - case Unknown = 8; } diff --git a/src/Enums/Twilio/DeliveryStatus.php b/src/Enums/Twilio/DeliveryStatus.php index e484b2f..2d6b76b 100644 --- a/src/Enums/Twilio/DeliveryStatus.php +++ b/src/Enums/Twilio/DeliveryStatus.php @@ -18,6 +18,21 @@ */ enum DeliveryStatus: string { + case Queued = 'queued'; + case Sending = 'sending'; + case Sent = 'sent'; + case Failed = 'failed'; + case Delivered = 'delivered'; + case Undelivered = 'undelivered'; + case Receiving = 'receiving'; + case Received = 'received'; + case Accepted = 'accepted'; + case Scheduled = 'scheduled'; + case Read = 'read'; + case PartiallyDelivered = 'partially_delivered'; + case Canceled = 'canceled'; + case Unknown = 'unknown'; + /** * Map status string to a numeric code for storage in database. */ @@ -113,18 +128,4 @@ public static function fromCode(string $code): DeliveryStatus default => self::Unknown, // Return Unknown as default if code is invalid }; } - case Queued = 'queued'; - case Sending = 'sending'; - case Sent = 'sent'; - case Failed = 'failed'; - case Delivered = 'delivered'; - case Undelivered = 'undelivered'; - case Receiving = 'receiving'; - case Received = 'received'; - case Accepted = 'accepted'; - case Scheduled = 'scheduled'; - case Read = 'read'; - case PartiallyDelivered = 'partially_delivered'; - case Canceled = 'canceled'; - case Unknown = 'unknown'; } diff --git a/src/Responses/SMSResponse.php b/src/Responses/SMSResponse.php index cd5aa1b..c012dae 100644 --- a/src/Responses/SMSResponse.php +++ b/src/Responses/SMSResponse.php @@ -40,7 +40,7 @@ public function __construct( /** * @var string|null The message ID of the SMS operation, or null if not available. */ - protected ?string $messageId = null + protected ?string $messageId = null, ) { } diff --git a/src/Traits/ObfuscatesSensitiveDataTrait.php b/src/Traits/ObfuscatesSensitiveDataTrait.php index dbf67b7..2cf721a 100644 --- a/src/Traits/ObfuscatesSensitiveDataTrait.php +++ b/src/Traits/ObfuscatesSensitiveDataTrait.php @@ -38,7 +38,7 @@ public function hideSensitive(string $message, ?array $customPatterns = null): s // Iterate through each pattern and replace sensitive data with a masked version foreach ($patterns as $pattern => $replacement) { - $message = preg_replace($pattern, $replacement, (string) $message); + $message = preg_replace($pattern, (string) $replacement, (string) $message); } return $message; diff --git a/tests/Drivers/AmootsmsDriverTest.php b/tests/Drivers/AmootsmsDriverTest.php index 8f35e01..09bf6ba 100644 --- a/tests/Drivers/AmootsmsDriverTest.php +++ b/tests/Drivers/AmootsmsDriverTest.php @@ -28,20 +28,19 @@ final class AmootsmsDriverTest extends TestCase { private AmootsmsDriver $driver; - private MockObject $mockModel; private MockObject $mockClient; protected function setUp(): void { parent::setUp(); - $this->mockModel = $this->createMock(SMSLogModel::class); + $mockModel = $this->createMock(SMSLogModel::class); $this->mockClient = $this->createMock(CURLRequest::class); $config = [ 'token' => 'test-token', ]; - $this->driver = new AmootsmsDriver($config, $this->mockModel, $this->mockClient); + $this->driver = new AmootsmsDriver($config, $mockModel, $this->mockClient); } public function testSendSuccess(): void diff --git a/tests/Drivers/FarazsmsDriverTest.php b/tests/Drivers/FarazsmsDriverTest.php index 9a1d849..3e28505 100644 --- a/tests/Drivers/FarazsmsDriverTest.php +++ b/tests/Drivers/FarazsmsDriverTest.php @@ -28,15 +28,14 @@ final class FarazsmsDriverTest extends TestCase { private FarazsmsDriver $driver; private MockObject $client; - private MockObject $model; protected function setUp(): void { $this->client = $this->createMock(CURLRequest::class); - $this->model = $this->createMock(SMSLogModel::class); + $model = $this->createMock(SMSLogModel::class); $config = ['api_key' => 'test_api_key']; - $this->driver = new FarazsmsDriver($config, $this->model, $this->client); + $this->driver = new FarazsmsDriver($config, $model, $this->client); } public function testSendSuccess(): void diff --git a/tests/Drivers/IdehpardazanDriverTest.php b/tests/Drivers/IdehpardazanDriverTest.php index d7b5022..5381998 100644 --- a/tests/Drivers/IdehpardazanDriverTest.php +++ b/tests/Drivers/IdehpardazanDriverTest.php @@ -28,7 +28,6 @@ final class IdehpardazanDriverTest extends CIUnitTestCase { private IdehpardazanDriver $driver; private MockObject $client; - private MockObject $model; protected function setUp(): void { @@ -36,10 +35,10 @@ protected function setUp(): void // Mocking the CURLRequest and SMSLogModel $this->client = $this->createMock(CURLRequest::class); - $this->model = $this->createMock(SMSLogModel::class); + $model = $this->createMock(SMSLogModel::class); // Initialize IdehpardazanDriver with mocked dependencies - $this->driver = new IdehpardazanDriver(['api_key' => 'test-api-key'], $this->model, $this->client); + $this->driver = new IdehpardazanDriver(['api_key' => 'test-api-key'], $model, $this->client); } public function testSend(): void diff --git a/tests/Drivers/TwilioDriverTest.php b/tests/Drivers/TwilioDriverTest.php index 21256f0..e476588 100644 --- a/tests/Drivers/TwilioDriverTest.php +++ b/tests/Drivers/TwilioDriverTest.php @@ -74,7 +74,7 @@ public function testSendSuccess(): void DeliveryStatus::fromCode('sent')->toNumericCode(), 'Test message', null, - 'TestSender' + 'TestSender', ); $messageId = $this->driver->send('+1234567890', 'Test message', 'TestSender'); diff --git a/tests/Responses/SMSMultiResponseTest.php b/tests/Responses/SMSMultiResponseTest.php index f59342f..d0e2224 100644 --- a/tests/Responses/SMSMultiResponseTest.php +++ b/tests/Responses/SMSMultiResponseTest.php @@ -46,7 +46,7 @@ public function testGetResponseNotFound(): void { $multiResponse = new SMSMultiResponse(); - $this->assertNull($multiResponse->getResponse('non_existent_recipient')); + $this->assertNotInstanceOf(SMSResponse::class, $multiResponse->getResponse('non_existent_recipient')); } /** diff --git a/tests/SMSRocketServiceTest.php b/tests/SMSRocketServiceTest.php index c4fbbc3..85cbc8b 100644 --- a/tests/SMSRocketServiceTest.php +++ b/tests/SMSRocketServiceTest.php @@ -36,22 +36,18 @@ final class SMSRocketServiceTest extends TestCase { private SMSRocketService $service; private SMSDriverInterface $driver; - private CacheInterface $cache; private MockObject $logger; - private CURLRequest $client; - private SMSRocketConfig $config; - private SMSLogModel $model; protected function setUp(): void { - $this->cache = $this->createMock(CacheInterface::class); - $this->config = new SMSRocketConfig(); - $this->model = $this->createMock(SMSLogModel::class); + $cache = $this->createMock(CacheInterface::class); + $config = new SMSRocketConfig(); + $model = $this->createMock(SMSLogModel::class); $this->logger = $this->createMock(Logger::class); - $this->client = $this->createMock(CURLRequest::class); + $client = $this->createMock(CURLRequest::class); - $this->config->defaultDriver = 'testDriver'; - $this->config->drivers = [ + $config->defaultDriver = 'testDriver'; + $config->drivers = [ 'testDriver' => [ 'class' => $this->createMock(SMSDriverInterface::class)::class, 'config' => [ @@ -59,10 +55,10 @@ protected function setUp(): void ], ], ]; - $this->config->retryAttempts = 3; - $this->config->retryDelay = 1; + $config->retryAttempts = 3; + $config->retryDelay = 1; - $this->service = new SMSRocketService($this->cache, $this->config, $this->model, $this->logger, $this->client); + $this->service = new SMSRocketService($cache, $config, $model, $this->logger, $client); } /**