From f9d32222b93ce24077959710201db2af4a359ba3 Mon Sep 17 00:00:00 2001 From: omakei Date: Mon, 3 Jan 2022 18:06:18 +0300 Subject: [PATCH] WIP --- .github/FUNDING.yml | 2 +- .github/ISSUE_TEMPLATE/config.yml | 8 +- .github/SECURITY.md | 2 +- CHANGELOG.md | 2 +- LICENSE.md | 2 +- README.md | 241 +++++++++++-- art/nextsms-logo.png | Bin 0 -> 92417 bytes composer.json | 25 +- config/nextsms.php | 25 ++ config/skeleton.php | 5 - configure.php | 229 ------------ database/factories/ModelFactory.php | 2 +- ...php.stub => create_nextsms_table.php.stub} | 2 +- phpunit.xml.dist | 2 +- ...SkeletonCommand.php => NextSMSCommand.php} | 6 +- src/Exceptions/InvalidPayload.php | 36 ++ src/Facades/NextSMS.php | 16 + src/Facades/Skeleton.php | 16 - src/NextSMS.php | 241 +++++++++++++ ...rovider.php => NextSMSServiceProvider.php} | 12 +- src/Skeleton.php | 7 - tests/ExampleTest.php | 5 - tests/NextSMSTest.php | 341 ++++++++++++++++++ tests/Pest.php | 2 +- tests/TestCase.php | 10 +- .../stubs/responses/all_delivery_reports.json | 57 +++ tests/stubs/responses/all_sent_sms_logs.json | 62 ++++ ...ent_sms_logs_with_optional_parameters.json | 28 ++ .../stubs/responses/create_sub_customer.json | 13 + .../stubs/responses/deduct_sub_customer.json | 11 + ...ivery_report_with_specific_date_range.json | 26 ++ .../delivery_reports_with_message_id.json | 26 ++ tests/stubs/responses/get_sms_balance.json | 3 + .../stubs/responses/multiple_destination.json | 26 ++ .../multiple_sms_to_multiple_destination.json | 26 ++ .../responses/recharge_sub_customer.json | 10 + tests/stubs/responses/schedule_sms.json | 15 + tests/stubs/responses/single_destination.json | 15 + 38 files changed, 1219 insertions(+), 338 deletions(-) create mode 100644 art/nextsms-logo.png create mode 100644 config/nextsms.php delete mode 100644 config/skeleton.php delete mode 100644 configure.php rename database/migrations/{create_skeleton_table.php.stub => create_nextsms_table.php.stub} (80%) rename src/Commands/{SkeletonCommand.php => NextSMSCommand.php} (63%) create mode 100644 src/Exceptions/InvalidPayload.php create mode 100644 src/Facades/NextSMS.php delete mode 100644 src/Facades/Skeleton.php create mode 100755 src/NextSMS.php rename src/{SkeletonServiceProvider.php => NextSMSServiceProvider.php} (59%) delete mode 100755 src/Skeleton.php delete mode 100644 tests/ExampleTest.php create mode 100644 tests/NextSMSTest.php create mode 100644 tests/stubs/responses/all_delivery_reports.json create mode 100644 tests/stubs/responses/all_sent_sms_logs.json create mode 100644 tests/stubs/responses/all_sent_sms_logs_with_optional_parameters.json create mode 100644 tests/stubs/responses/create_sub_customer.json create mode 100644 tests/stubs/responses/deduct_sub_customer.json create mode 100644 tests/stubs/responses/delivery_report_with_specific_date_range.json create mode 100644 tests/stubs/responses/delivery_reports_with_message_id.json create mode 100644 tests/stubs/responses/get_sms_balance.json create mode 100644 tests/stubs/responses/multiple_destination.json create mode 100644 tests/stubs/responses/multiple_sms_to_multiple_destination.json create mode 100644 tests/stubs/responses/recharge_sub_customer.json create mode 100644 tests/stubs/responses/schedule_sms.json create mode 100644 tests/stubs/responses/single_destination.json diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index c68765b..9132b11 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -github: :vendor_name +github: omakei diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 80a788c..b2b96bd 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,14 +1,14 @@ blank_issues_enabled: false contact_links: - name: Ask a question - url: https://github.com/:vendor_name/:package_name/discussions/new?category=q-a + url: https://github.com/omakei/laravel-nextsms/discussions/new?category=q-a about: Ask the community for help - name: Request a feature - url: https://github.com/:vendor_name/:package_name/discussions/new?category=ideas + url: https://github.com/omakei/laravel-nextsms/discussions/new?category=ideas about: Share ideas for new features - name: Report a security issue - url: https://github.com/:vendor_name/:package_name/security/policy + url: https://github.com/omakei/laravel-nextsms/security/policy about: Learn how to notify us for sensitive bugs - name: Report a bug - url: https://github.com/:vendor_name/:package_name/issues/new + url: https://github.com/omakei/laravel-nextsms/issues/new about: Report a reproducable bug diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 12ab7c2..0ceccab 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -1,3 +1,3 @@ # Security Policy -If you discover any security related issues, please email author@domain.com instead of using the issue tracker. +If you discover any security related issues, please email omakei96@gmail.com instead of using the issue tracker. diff --git a/CHANGELOG.md b/CHANGELOG.md index 767365d..ab2a7b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -All notable changes to `:package_name` will be documented in this file. +All notable changes to `laravel-nextsms` will be documented in this file. ## 1.0.0 - 202X-XX-XX diff --git a/LICENSE.md b/LICENSE.md index 58c9ad4..7898534 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) :vendor_name +Copyright (c) omakei Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index b7d5a48..b8567e3 100644 --- a/README.md +++ b/README.md @@ -1,71 +1,236 @@ -# :package_description -[![Latest Version on Packagist](https://img.shields.io/packagist/v/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug) -[![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/:vendor_slug/:package_slug/run-tests?label=tests)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3Arun-tests+branch%3Amain) -[![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/:vendor_slug/:package_slug/Check%20&%20fix%20styling?label=code%20style)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain) -[![Total Downloads](https://img.shields.io/packagist/dt/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug) - ---- -This repo can be used to scaffold a Laravel package. Follow these steps to get started: +

+ NextSMS Logo +

+# Laravel NextSMS -1. Press the "Use template" button at the top of this repo to create a new repo with the contents of this skeleton -2. Run "php ./configure.php" to run a script that will replace all placeholders throughout all the files -3. Remove this block of text. -4. Have fun creating your package. -5. If you need help creating a package, consider picking up our Laravel Package Training video course. ---- - -This is where your description should go. Limit it to a paragraph or two. Consider adding a small example. +[![Latest Version on Packagist](https://img.shields.io/packagist/v/omakei/laravel-nextsms.svg?style=flat-square)](https://packagist.org/packages/omakei/laravel-nextsms) +[![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/omakei/laravel-nextsms/run-tests?label=tests)](https://github.com/omakei/laravel-nextsms/actions?query=workflow%3Arun-tests+branch%3Amain) +[![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/omakei/laravel-nextsms/Check%20&%20fix%20styling?label=code%20style)](https://github.com/omakei/laravel-nextsms/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain) +[![Total Downloads](https://img.shields.io/packagist/dt/omakei/laravel-nextsms.svg?style=flat-square)](https://packagist.org/packages/omakei/laravel-nextsms) -## Support us - -[](https://spatie.be/github-ad-click/:package_name) - -We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us). - -We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards). +Laravel package to send SMS using NextSMS API. ## Installation You can install the package via composer: ```bash -composer require :vendor_slug/:package_slug -``` - -You can publish and run the migrations with: - -```bash -php artisan vendor:publish --tag=":package_slug-migrations" -php artisan migrate +composer require omakei/laravel-nextsms ``` You can publish the config file with: ```bash -php artisan vendor:publish --tag=":package_slug-config" +php artisan vendor:publish --tag="laravel-nextsms-config" ``` -Optionally, you can publish the views using +The following keys must be available in your `.env` file: ```bash -php artisan vendor:publish --tag=":package_slug-views" +NEXTSMS_USERNAME= +NEXTSMS_PASSWORD= +NEXTSMS_SENDER_ID= ``` -This is the contents of the published config file: +This is the contents of the published `config` file: ```php return [ + 'username' => env('NEXTSMS_USERNAME', 'NEXTSMS'), + 'password' => env('NEXTSMS_PASSWORD', 'NEXTSMS'), + 'api_key' => base64_encode(env('NEXTSMS_USERNAME', 'NEXTSMS').':'.env('NEXTSMS_PASSWORD', 'NEXTSMS')), + 'sender_id' => env('NEXTSMS_SENDER_ID', 'NEXTSMS'), + 'url' => [ + 'sms' => [ + 'single' => NextSMS::NEXTSMS_BASE_URL.'/api/sms/v1/text/single', + 'multiple' => NextSMS::NEXTSMS_BASE_URL.'/api/sms/v1/text/multi', + 'reports' => NextSMS::NEXTSMS_BASE_URL.'/api/sms/v1/reports', + 'logs' => NextSMS::NEXTSMS_BASE_URL.'/api/sms/v1/logs', + 'balance' => NextSMS::NEXTSMS_BASE_URL.'/api/sms/v1/balance', + ], + 'sub_customer' => [ + 'create' => NextSMS::NEXTSMS_BASE_URL.'/api/reseller/v1/sub_customer/create', + 'recharge' => NextSMS::NEXTSMS_BASE_URL.'/api/reseller/v1/sub_customer/recharge', + 'deduct' => NextSMS::NEXTSMS_BASE_URL.'/api/reseller/v1/sub_customer/deduct', + ] + ], ]; ``` ## Usage +### Send SMS + +Sending single sms to single destination: + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::sendSingleSMS(['to' => '255625933171', 'text' => 'Dj Omakei is texting.']); + +``` + +Sending single sms to multiple destinations: + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::sendSingleSMSToMultipleDestination([ + 'to' => ['255625933171','255656699895'], + 'text' => 'Dj Omakei is texting.']); + +``` + +Sending multiple sms to multiple destinations (Example 1): + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::sendMultipleSMSToMultipleDestinations(['messages' => [ + ['to' => '255625933171', 'text' => 'Dj Omakei is texting.'], + ['to' => '255656699895', 'text' => 'Dj Omakei is texting.'] + ]]); + +``` + +Sending multiple sms to multiple destinations (Example 2): + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::sendMultipleSMSToMultipleDestinations(['messages' => [ + ['to' => ['255625933171','255656699895'], 'text' => 'Dj Omakei is texting.'], + ['to' => '255625933171', 'text' => 'Dj Omakei is texting.'] + ]]); + +``` + +Schedule sms: + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::scheduleSMS([ + 'to' => '255625933171', + 'text' => 'Dj Omakei is texting.', + 'date' => '2022-01-25' , + 'time' => '12:00']); + +``` + +### SMS Delivery Reports + +Get all delivery reports: + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::getAllDeliveryReports(); + +``` + +Get delivery reports with messageId: + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::getDeliveryReportWithMessageId(243452542526627); + +``` + +Get delivery reports with messageId: + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::getDeliveryReportWithSpecificDateRange('2022-01-25', '2022-01-29'); + +``` + +### Sent Sms Logs + +Get all sent SMS logs: + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::getAllSentSMSLogs(10, 5); + +``` + +Get all sent SMS logs with the optional parameter: + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::getAllSentSMSLogsWithOptionalParameter('255625933171','2022-01-25', '2022-01-29',10, 5); + +``` + +### Sub Customer + +Register Sub Customer: + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::subCustomerCreate( + 'Michael', + 'Omakei', + 'omakei', + 'omakei96@gmail.com', + '06259313171', + 'Sub Customer (Reseller)', + 100); + +``` + +Recharge customer: + ```php -$skeleton = new VendorName\Skeleton(); -echo $skeleton->echoPhrase('Hello, VendorName!'); + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::subCustomerRecharge('omakei96@gmail.com', 100); + ``` +Deduct a customer: + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::subCustomerDeduct('omakei96@gmail.com', 100); + +``` + +Get sms balance: + +```php + +use Omakei\NextSMS\NextSMS; + +$response = NextSMS::getSMSBalance(); + +``` + +## NextSMS API Documentation + +Please see [NextSMS Developer API](https://documenter.getpostman.com/view/4680389/SW7dX7JL#2936eed4-6027-45e7-92c9-fe1cd7df140b) for more details. + ## Testing ```bash @@ -86,7 +251,7 @@ Please review [our security policy](../../security/policy) on how to report secu ## Credits -- [:author_name](https://github.com/:author_username) +- [omakei](https://github.com/omakei) - [All Contributors](../../contributors) ## License diff --git a/art/nextsms-logo.png b/art/nextsms-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5a6c9ee690e149de30b16e17966f745cfd4b7266 GIT binary patch literal 92417 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

?nyg$1*&*$Wd`ma}wpU^)6S7no^bfm(No}*b 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 CDYqK{ literal 0 HcmV?d00001 diff --git a/composer.json b/composer.json index 1ffdef8..866935a 100644 --- a/composer.json +++ b/composer.json @@ -1,17 +1,17 @@ { - "name": ":vendor_slug/:package_slug", - "description": ":package_description", + "name": "omakei/laravel-nextsms", + "description": "A Laravel package to send SMS using NextSMS API ", "keywords": [ - ":vendor_name", + "omakei", "laravel", - ":package_slug" + "laravel-nextsms" ], - "homepage": "https://github.com/:vendor_slug/:package_slug", + "homepage": "https://github.com/omakei/laravel-nextsms", "license": "MIT", "authors": [ { - "name": ":author_name", - "email": "author@domain.com", + "name": "omakei", + "email": "omakei96@gmail.com", "role": "Developer" } ], @@ -26,6 +26,7 @@ "orchestra/testbench": "^6.22", "pestphp/pest": "^1.21", "pestphp/pest-plugin-laravel": "^1.1", + "pestphp/pest-plugin-mock": "^1.0", "phpstan/extension-installer": "^1.1", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-phpunit": "^1.0", @@ -34,13 +35,13 @@ }, "autoload": { "psr-4": { - "VendorName\\Skeleton\\": "src", - "VendorName\\Skeleton\\Database\\Factories\\": "database/factories" + "Omakei\\NextSMS\\": "src", + "Omakei\\NextSMS\\Database\\Factories\\": "database/factories" } }, "autoload-dev": { "psr-4": { - "VendorName\\Skeleton\\Tests\\": "tests" + "Omakei\\NextSMS\\Tests\\": "tests" } }, "scripts": { @@ -54,10 +55,10 @@ "extra": { "laravel": { "providers": [ - "VendorName\\Skeleton\\SkeletonServiceProvider" + "Omakei\\NextSMS\\NextSMSServiceProvider" ], "aliases": { - "Skeleton": "VendorName\\Skeleton\\Facades\\Skeleton" + "NextSMS": "Omakei\\NextSMS\\Facades\\NextSMS" } } }, diff --git a/config/nextsms.php b/config/nextsms.php new file mode 100644 index 0000000..f0af9a4 --- /dev/null +++ b/config/nextsms.php @@ -0,0 +1,25 @@ + env('NEXTSMS_USERNAME', 'NEXTSMS'), + 'password' => env('NEXTSMS_PASSWORD', 'NEXTSMS'), + 'api_key' => base64_encode(env('NEXTSMS_USERNAME', 'NEXTSMS').':'.env('NEXTSMS_PASSWORD', 'NEXTSMS')), + 'sender_id' => env('NEXTSMS_SENDER_ID', 'NEXTSMS'), + 'url' => [ + 'sms' => [ + 'single' => NextSMS::NEXTSMS_BASE_URL.'/api/sms/v1/text/single', + 'multiple' => NextSMS::NEXTSMS_BASE_URL.'/api/sms/v1/text/multi', + 'reports' => NextSMS::NEXTSMS_BASE_URL.'/api/sms/v1/reports', + 'logs' => NextSMS::NEXTSMS_BASE_URL.'/api/sms/v1/logs', + 'balance' => NextSMS::NEXTSMS_BASE_URL.'/api/sms/v1/balance', + ], + 'sub_customer' => [ + 'create' => NextSMS::NEXTSMS_BASE_URL.'/api/reseller/v1/sub_customer/create', + 'recharge' => NextSMS::NEXTSMS_BASE_URL.'/api/reseller/v1/sub_customer/recharge', + 'deduct' => NextSMS::NEXTSMS_BASE_URL.'/api/reseller/v1/sub_customer/deduct', + ] + ], +]; diff --git a/config/skeleton.php b/config/skeleton.php deleted file mode 100644 index fbb0e4c..0000000 --- a/config/skeleton.php +++ /dev/null @@ -1,5 +0,0 @@ - $version) { - if (in_array($name, $names, true)) { - unset($data['require-dev'][$name]); - } - } - - file_put_contents(__DIR__.'/composer.json', json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); -} - -function remove_composer_script($scriptName) { - $data = json_decode(file_get_contents(__DIR__.'/composer.json'), true); - - foreach($data['scripts'] as $name => $script) { - if ($scriptName === $name) { - unset($data['scripts'][$name]); - break; - } - } - - file_put_contents(__DIR__.'/composer.json', json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); -} - -function remove_readme_paragraphs(string $file): void { - $contents = file_get_contents($file); - - file_put_contents( - $file, - preg_replace('/.*/s', '', $contents) ?: $contents - ); -} - -function safeUnlink(string $filename) { - if (file_exists($filename) && is_file($filename)) { - unlink($filename); - } -} - -function determineSeparator(string $path): string { - return str_replace('/', DIRECTORY_SEPARATOR, $path); -} - -function replaceForWindows(): array { - return preg_split('/\\r\\n|\\r|\\n/', run('dir /S /B * | findstr /v /i .git\ | findstr /v /i vendor | findstr /v /i '.basename(__FILE__).' | findstr /r /i /M /F:/ ":author :vendor :package VendorName skeleton vendor_name vendor_slug author@domain.com"')); -} - -function replaceForAllOtherOSes(): array { - return explode(PHP_EOL, run('grep -E -r -l -i ":author|:vendor|:package|VendorName|skeleton|vendor_name|vendor_slug|author@domain.com" --exclude-dir=vendor ./* ./.github/* | grep -v ' . basename(__FILE__))); -} - -$gitName = run('git config user.name'); -$authorName = ask('Author name', $gitName); - -$gitEmail = run('git config user.email'); -$authorEmail = ask('Author email', $gitEmail); - -$usernameGuess = explode(':', run('git config remote.origin.url'))[1]; -$usernameGuess = dirname($usernameGuess); -$usernameGuess = basename($usernameGuess); -$authorUsername = ask('Author username', $usernameGuess); - -$vendorName = ask('Vendor name', $authorUsername); -$vendorSlug = slugify($vendorName); -$vendorNamespace = ucwords($vendorName); -$vendorNamespace = ask('Vendor namespace', $vendorNamespace); - -$currentDirectory = getcwd(); -$folderName = basename($currentDirectory); - -$packageName = ask('Package name', $folderName); -$packageSlug = slugify($packageName); -$packageSlugWithoutPrefix = remove_prefix('laravel-', $packageSlug); - -$className = title_case($packageName); -$className = ask('Class name', $className); -$description = ask('Package description', "This is my package {$packageSlug}"); - -$usePhpStan = confirm('Enable PhpStan?', true); -$usePhpCsFixer = confirm('Enable PhpCsFixer?', true); -$useUpdateChangelogWorkflow = confirm('Use automatic changelog updater workflow?', true); - -writeln('------'); -writeln("Author : {$authorName} ({$authorUsername}, {$authorEmail})"); -writeln("Vendor : {$vendorName} ({$vendorSlug})"); -writeln("Package : {$packageSlug} <{$description}>"); -writeln("Namespace : {$vendorNamespace}\\{$className}"); -writeln("Class name : {$className}"); -writeln("---"); -writeln("Packages & Utilities"); -writeln("Use PhpCsFixer : " . ($usePhpCsFixer ? 'yes' : 'no')); -writeln("Use Larastan/PhpStan : " . ($usePhpStan ? 'yes' : 'no')); -writeln("Use Auto-Changelog : " . ($useUpdateChangelogWorkflow ? 'yes' : 'no')); -writeln('------'); - -writeln('This script will replace the above values in all relevant files in the project directory.'); - -if (! confirm('Modify files?', true)) { - exit(1); -} - -$files = (str_starts_with(strtoupper(PHP_OS), 'WIN') ? replaceForWindows() : replaceForAllOtherOSes()); - -foreach ($files as $file) { - replace_in_file($file, [ - ':author_name' => $authorName, - ':author_username' => $authorUsername, - 'author@domain.com' => $authorEmail, - ':vendor_name' => $vendorName, - ':vendor_slug' => $vendorSlug, - 'VendorName' => $vendorNamespace, - ':package_name' => $packageName, - ':package_slug' => $packageSlug, - ':package_slug_without_prefix' => $packageSlugWithoutPrefix, - 'Skeleton' => $className, - 'skeleton' => $packageSlug, - ':package_description' => $description, - ]); - - match (true) { - str_contains($file, determineSeparator('src/Skeleton.php')) => rename($file, determineSeparator('./src/' . $className . '.php')), - str_contains($file, determineSeparator('src/SkeletonServiceProvider.php')) => rename($file, determineSeparator('./src/' . $className . 'ServiceProvider.php')), - str_contains($file, determineSeparator('src/Facades/Skeleton.php')) => rename($file, determineSeparator('./src/Facades/' . $className . '.php')), - str_contains($file, determineSeparator('src/Commands/SkeletonCommand.php')) => rename($file, determineSeparator('./src/Commands/' . $className . 'Command.php')), - str_contains($file, determineSeparator('database/migrations/create_skeleton_table.php.stub')) => rename($file, determineSeparator('./database/migrations/create_' . $packageSlugWithoutPrefix . '_table.php.stub')), - str_contains($file, determineSeparator('config/skeleton.php')) => rename($file, determineSeparator('./config/' . $packageSlugWithoutPrefix . '.php')), - str_contains($file, 'README.md') => remove_readme_paragraphs($file), - default => [], - }; -} - -if (! $usePhpCsFixer) { - safeUnlink(__DIR__ . '/.php_cs.dist.php'); - safeUnlink(__DIR__ . '/.github/workflows/php-cs-fixer.yml'); -} - -if (! $usePhpStan) { - safeUnlink(__DIR__ . '/phpstan.neon.dist'); - safeUnlink(__DIR__ . '/phpstan-baseline.neon'); - safeUnlink(__DIR__ . '/.github/workflows/phpstan.yml'); - - remove_composer_deps([ - 'phpstan/extension-installer', - 'phpstan/phpstan-deprecation-rules', - 'phpstan/phpstan-phpunit', - 'nunomaduro/larastan', - ]); - - remove_composer_script('phpstan'); -} - -if (! $useUpdateChangelogWorkflow) { - safeUnlink(__DIR__ . '/.github/workflows/update-changelog.yml'); -} - -confirm('Execute `composer install` and run tests?') && run('composer install && composer test'); - -confirm('Let this script delete itself?', true) && unlink(__FILE__); diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index c51604f..51f128f 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -1,6 +1,6 @@ id(); // add fields diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 3bbe22a..513924a 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -19,7 +19,7 @@ verbose="true" > - + tests diff --git a/src/Commands/SkeletonCommand.php b/src/Commands/NextSMSCommand.php similarity index 63% rename from src/Commands/SkeletonCommand.php rename to src/Commands/NextSMSCommand.php index 3e5f628..761f87e 100644 --- a/src/Commands/SkeletonCommand.php +++ b/src/Commands/NextSMSCommand.php @@ -1,12 +1,12 @@ $messageId]); + } + + public static function getDeliveryReportWithSpecificDateRange(string $sentSince, string $sentUntil): Response + { + throw_if(count(explode('-', $sentSince))!=3 || count(explode('-', $sentUntil))!=3 + , InvalidPayload::invalidPayloadArrayKeyType('"date" key of format "YYYY-MM-DD"')); + + $dateSince = explode('-', $sentSince); + + $dateUnit = explode('-', $sentUntil); + + throw_if(checkdate($dateSince[1], $dateSince[2],$dateSince[0]) || + checkdate($dateUnit[1], $dateUnit[2],$dateUnit[0]) + , InvalidPayload::invalidPayloadArrayKeyType('"date" key of format "YYYY-MM-DD"')); + + return self::makeGetRequest(config('nextsms.url.sms.reports'), + ['sentSince' => $sentSince, 'sentUntil' => $sentUntil]); + } + + public static function getAllSentSMSLogs(int $limit, int $offset): Response + { + return self::makeGetRequest(config('nextsms.url.sms.reports'), [ + 'from' => config('nextsms.sender_id'), + 'limit' => $limit, + 'offset' => $offset + ]); + } + + public static function getAllSentSMSLogsWithOptionalParameter( + string $to, string $sentSince, string $sentUntil, int $limit, int $offset): Response + { + + throw_if(count(explode('-', $sentSince))!=3 || count(explode('-', $sentUntil))!=3 + , InvalidPayload::invalidPayloadArrayKeyType('"date" key of format "YYYY-MM-DD"')); + + $dateSince = explode('-', $sentSince); + + $dateUnit = explode('-', $sentUntil); + + throw_if(checkdate($dateSince[1], $dateSince[2],$dateSince[0]) || + checkdate($dateUnit[1], $dateUnit[2],$dateUnit[0]) + , InvalidPayload::invalidSingleSMSPayload()); + + + return self::makeGetRequest(config('nextsms.url.sms.reports'), [ + 'from' => config('nextsms.sender_id'), + 'to' => $to, + 'sentSince' => $sentSince, + 'sentUntil' => $sentUntil, + 'limit' => $limit, + 'offset' => $offset + ]); + } + + public static function getSMSBalance(): Response + { + return self::makeGetRequest(config('nextsms.url.sms.balance'), []); + } + + public static function subCustomerCreate( + string $first_name, + string $last_name, + string $username, + string $email, + string $phone_number, + string $account_type, + int $sms_price): Response + { + + throw_if($account_type !='Sub Customer' || + $account_type !='Sub Customer (Reseller)' + , InvalidPayload::invalidAccountType()); + + return self::makePostRequest(config('nextsms.url.sub_customer.create'), [ + 'first_name'=> $first_name, + 'last_name'=> $last_name, + 'username'=> $username, + 'email'=> $email, + 'phone_number'=> $phone_number, + 'account_type'=> $account_type, + 'sms_price'=> $sms_price + ]); + } + + public static function subCustomerRecharge(string $email, int $smscount): Response + { + return self::makePostRequest(config('nextsms.url.sub_customer.recharge'), [ + 'email'=> $email, + 'smscount'=> $smscount + ]); + } + + + public static function subCustomerDeduct(string $email, int $smscount): Response + { + return self::makePostRequest(config('nextsms.url.sub_customer.deduct'), [ + 'email'=> $email, + 'smscount'=> $smscount + ]); + } + + protected static function makePostRequest(string $url, mixed $payload): Response + { + return Http::withHeaders(self::getHeaders())->post($url, $payload); + } + + protected static function makeGetRequest(string $url, mixed $payload): Response + { + return Http::withHeaders(self::getHeaders())->get($url, $payload); + + } + + protected static function getHeaders(): array + { + return [ + 'Authorization' => 'Basic ' . config('nextsms.api_key'), + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + ]; + } + + protected static function getSingleSMSPayload(array $payload): array + { + throw_if(count(array_diff(['to','text'], array_keys($payload))) != 0, + InvalidPayload::invalidSingleSMSPayload()); + + return array_merge(['from' => config('textsms.sender_id'), $payload]); + + } + + protected static function getSingleSMSToMultipleDestinationPayload(array $payload): array + { + throw_if(count(array_diff(['to','text'], array_keys($payload))) != 0, + InvalidPayload::invalidSingleSMSPayload()); + + throw_if(!is_array($payload['to']), InvalidPayload::invalidMultipleSMSPayload()); + + return array_merge(['from' => config('textsms.sender_id'), $payload]); + + } + + protected static function getMultipleSMSToMultipleDestinationPayload(array $payload): array + { + throw_if(count(array_diff(['messages'], array_keys($payload))) != 0, + InvalidPayload::invalidPayloadArrayKeys('"messages"')); + + throw_if(!is_array($payload['messages']), + InvalidPayload::invalidPayloadArrayKeyType('"messages" key of type array')); + + + $payloads = []; + $index = 0; + + foreach ($payload['messages'] as $object) + { + throw_if(count(array_diff(['to','text'], array_keys($object))) != 0, + InvalidPayload::invalidSingleSMSPayload()); + + throw_if(!is_array(array_column($object, 'to')) || + !is_string(array_column($object, 'to')), + InvalidPayload::invalidPayloadArrayKeyType('"to" key of type array or "to" key of type string')); + + + $payloads['messages'][$index] = array_merge(['from' => config('textsms.sender_id'), $object]); + + $index++; + } + + return $payloads; + + } + + protected static function getScheduleSMSPayload(array $payload): array + { + throw_if(count(array_diff(['to','text', 'date', 'time'], array_keys($payload))) != 0, + InvalidPayload::invalidPayloadArrayKeys('"to", "text", "date" and "time"')); + + throw_if(count(explode('-', $payload['date']))!=3, + InvalidPayload::invalidPayloadArrayKeyType('"date" key of format "YYYY-MM-DD"')); + + throw_if(count(explode(':', $payload['time']))!=2, + InvalidPayload::invalidPayloadArrayKeyType('"time" key of format "HH:MM"')); + + $date = explode('-', $payload['date']); + + throw_if(!checkdate($date[1], $date[2],$date[0]), + InvalidPayload::invalidPayloadArrayKeyType('"date" key of format "YYYY-MM-DD"')); + + throw_if(!preg_match("/(2[0-3]|[0][0-9]|1[0-9]):([0-5][0-9])/", $payload['time']), + InvalidPayload::invalidPayloadArrayKeyType('"time" key of format "HH:MM"')); + + return array_merge(['from' => config('textsms.sender_id'), $payload]); + + } + +} diff --git a/src/SkeletonServiceProvider.php b/src/NextSMSServiceProvider.php similarity index 59% rename from src/SkeletonServiceProvider.php rename to src/NextSMSServiceProvider.php index 618b267..9b71a4a 100644 --- a/src/SkeletonServiceProvider.php +++ b/src/NextSMSServiceProvider.php @@ -1,12 +1,12 @@ name('skeleton') + ->name('laravel-nextsms') ->hasConfigFile() ->hasViews() - ->hasMigration('create_skeleton_table') - ->hasCommand(SkeletonCommand::class); + ->hasMigration('create_laravel-nextsms_table') + ->hasCommand(NextSMSCommand::class); } } diff --git a/src/Skeleton.php b/src/Skeleton.php deleted file mode 100755 index 66fab60..0000000 --- a/src/Skeleton.php +++ /dev/null @@ -1,7 +0,0 @@ -toBeTrue(); -}); diff --git a/tests/NextSMSTest.php b/tests/NextSMSTest.php new file mode 100644 index 0000000..67d9892 --- /dev/null +++ b/tests/NextSMSTest.php @@ -0,0 +1,341 @@ + + Http::response( $stub, 200)]); + + $response = NextSMS::sendSingleSMS(['to' => '25576328997', 'text' => 'Dj Omakei is texting.']); + + $this->assertEquals($response, $stub); + } + + /** @test */ + public function it_can_throw_exception_when_payload_of_single_destination_is_invalid() { + + $this->expectException(InvalidPayload::class); + + $this->expectExceptionMessage('The payload provided must contain "to" and "text" keys.'); + + $response = NextSMS::sendSingleSMS(['to' => '25576328997']); + + } + + /** @test */ + public function it_can_send_single_sms_to_multiple_destination() { + + $stub = json_decode( + file_get_contents(__DIR__ . '/stubs/responses/multiple_destination.json'), + true); + + Http::fake([config('nextsms.url.sms.single') => + Http::response( $stub, 200)]); + + $response = NextSMS::sendSingleSMSToMultipleDestination([ + 'to' => ['25576328997'], + 'text' => 'Dj Omakei is texting.']); + + $this->assertEquals($response, $stub); + } + + /** @test */ + public function it_can_throw_exception_when_payload_of_multiple_destination_is_invalid() { + + $this->expectException(InvalidPayload::class); + + $this->expectExceptionMessage('The payload provided must contain "to" key of type array.'); + + $response = NextSMS::sendSingleSMSToMultipleDestination([ + 'to' => '25576328997', + 'text' => 'Dj Omakei is texting.']); + + } + + /** @test */ + public function it_can_send_multiple_sms_to_multiple_destination() { + + $stub = json_decode( + file_get_contents(__DIR__ . '/stubs/responses/multiple_sms_to_multiple_destination.json'), + true); + + Http::fake([config('nextsms.url.sms.multiple') => + Http::response( $stub , 200)]); + + $response = NextSMS::sendMultipleSMSToMultipleDestinations(['messages' => [[ + 'to' => '25576328997', + 'text' => 'Dj Omakei is texting.']]]); + + $this->assertEquals($response, $stub); + } + + /** @test */ + public function it_can_throw_exception_when_payload_of_multiple_sms_to_multiple_destination_is_invalid() { + + $this->expectException(InvalidPayload::class); + + $this->expectExceptionMessage('The payload provided must contain "to" and "text" keys.'); + + $response = NextSMS::sendMultipleSMSToMultipleDestinations(['messages' =>[ + ['to' => '25576328997']]]); + + } + + /** @test */ + public function it_can_schedule_sms() { + + $stub = json_decode( + file_get_contents(__DIR__ . '/stubs/responses/schedule_sms.json'), + true); + + Http::fake([config('nextsms.url.sms.single') => + Http::response( $stub , 200)]); + + $response = NextSMS::scheduleSMS([ + 'to' => '25576328997', + 'text' => 'Dj Omakei is texting.', + 'date' => '2022-01-25' , + 'time' => '12:00' + ]); + + $this->assertEquals($response, $stub); + } + + /** @test */ + public function it_can_throw_exception_when_date_payload_of_schedule_sms_is_invalid() { + + $this->expectException(InvalidPayload::class); + + $this->expectExceptionMessage('The payload provided must contain "date" key of format "YYYY-MM-DD".'); + + $response = NextSMS::scheduleSMS([ + 'to' => '25576328997', + 'text' => 'Dj Omakei is texting.', + 'date' => '2022/01/25' , + 'time' => '12:00' + ]); + + } + + /** @test */ + public function it_can_throw_exception_when_time_payload_of_schedule_sms_is_invalid() { + + $this->expectException(InvalidPayload::class); + + $this->expectExceptionMessage('The payload provided must contain "time" key of format "HH:MM".'); + + $response1 = NextSMS::scheduleSMS([ + 'to' => '25576328997', + 'text' => 'Dj Omakei is texting.', + 'date' => '2022-01-25' , + 'time' => '12:90' + ]); + + + } + + /** @test */ + public function it_can_get_all_delivery_reports() { + + $stub = json_decode( + file_get_contents(__DIR__ . '/stubs/responses/recharge_sub_customer.json'), + true); + + Http::fake([config('nextsms.url.sms.reports') => + Http::response( $stub , 200)]); + + $response = NextSMS::getAllDeliveryReports(); + + $this->assertEquals($response, $stub); + } + + /** @test */ + public function it_can_delivery_report_with_message_id() { + + $stub = json_decode( + file_get_contents(__DIR__ . '/stubs/responses/delivery_reports_with_message_id.json'), + true); + + Http::fake([config('nextsms.url.sms.reports') => + Http::response( $stub , 200)]); + + $response = NextSMS::getDeliveryReportWithMessageId(2346673573733); + + $this->assertEquals($response, $stub); + } + + /** @test */ + public function it_can_get_delivery_report_with_specific_date_range() { + + $stub = json_decode( + file_get_contents(__DIR__ . '/stubs/responses/delivery_report_with_specific_date_range.json'), + true); + + Http::fake([config('nextsms.url.sms.reports') => + Http::response( $stub , 200)]); + + $response = NextSMS::getDeliveryReportWithSpecificDateRange('2022-01-25', '2022-01-29'); + + $this->assertEquals($response, $stub); + } + + /** @test */ + public function it_can_throw_exception_when_arguments_of_get_delivery_report_with_specific_date_range_is_invalid() { + + $this->expectException(InvalidPayload::class); + + $this->expectExceptionMessage('The payload provided must contain "date" key of format "YYYY-MM-DD".'); + + $response = NextSMS::getDeliveryReportWithSpecificDateRange('2022/01/25', '2022/01/29'); + + } + + /** @test */ + public function it_can_get_all_sent_sms_logs() { + + $stub = json_decode( + file_get_contents(__DIR__ . '/stubs/responses/all_sent_sms_logs.json'), + true); + + Http::fake([config('nextsms.url.sms.reports') => + Http::response( $stub, 200)]); + + $response = NextSMS::getAllSentSMSLogs(20,5); + + $this->assertEquals($response, $stub); + } + + /** @test */ + public function it_can_get_all_sent_sms_logs_with_optional_parameter() { + + $stub = json_decode( + file_get_contents(__DIR__ . '/stubs/responses/all_sent_sms_logs.json'), + true); + + Http::fake([config('nextsms.url.sms.reports') => + Http::response( $stub , 200)]); + + $response = NextSMS::getAllSentSMSLogsWithOptionalParameter( + '255625933171','2022-01-25', '2022-01-29',10, 5); + + $this->assertEquals($response, $stub); + } + + /** @test */ + public function it_can_throw_exception_when_arguments_of_get_all_sent_sms_logs_with_optional_parameter_is_invalid() { + + $this->expectException(InvalidPayload::class); + + $this->expectExceptionMessage('The payload provided must contain "date" key of format "YYYY-MM-DD".'); + + $response = NextSMS::getAllSentSMSLogsWithOptionalParameter( + '255625933171','2022/01/25', '2022/01/29',10, 5); + + + } + + /** @test */ + public function it_can_get_sms_balance() { + + $stub = json_decode( + file_get_contents(__DIR__ . '/stubs/responses/get_sms_balance.json'), + true); + + Http::fake([config('nextsms.url.sms.balance') => + Http::response( $stub , 200)]); + + $response = NextSMS::getSMSBalance(); + + $this->assertEquals($response, $stub); + } + + + /** @test */ + public function it_can_register_sub_customer() { + + $stub = json_decode( + file_get_contents(__DIR__ . '/stubs/responses/create_sub_customer.json'), + true); + + Http::fake([config('nextsms.url.sub_customer.create') => + Http::response( $stub , 200)]); + + $response = NextSMS::subCustomerCreate( 'Michael', + 'Omakei', + 'omakei', + 'omakei96@gmail.com', + '06259313171', + 'Sub Customer (Reseller)', + 100); + + $this->assertEquals($response, $stub); + } + + /** @test */ + public function it_can_throw_exception_when_arguments_of_register_sub_customer_is_invalid() { + + $this->expectException(InvalidPayload::class); + + $this->expectExceptionMessage('The account type must be Sub Customer or Sub Customer (Reseller).'); + + $response = NextSMS::subCustomerCreate( 'Michael', + 'Omakei', + 'omakei', + 'omakei96@gmail.com', + '06259313171', + 'Sub Customer (Omakei)', + 100); + + } + + /** @test */ + public function it_can_recharge_sub_customer() { + + $stub = json_decode( + file_get_contents(__DIR__ . '/stubs/responses/recharge_sub_customer.json'), + true); + + Http::fake([config('nextsms.url.sub_customer.recharge') => + Http::response( $stub , 200)]); + + $response = NextSMS::subCustomerRecharge('omakei96@gmail.com', 100); + + $this->assertEquals($response, $stub); + } + + /** @test */ + public function it_can_deduct_sub_customer() { + + $stub = json_decode( + file_get_contents(__DIR__ . '/stubs/responses/deduct_sub_customer.json'), + true); + + Http::fake([config('nextsms.url.sub_customer.deduct') => + Http::response( $stub, 200)]); + + $response = NextSMS::subCustomerDeduct('omakei96@gmail.com', 100); + + $this->assertEquals($response, $stub); + } +} + diff --git a/tests/Pest.php b/tests/Pest.php index 7fe1500..c6d6c3d 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -1,5 +1,5 @@ in(__DIR__); diff --git a/tests/TestCase.php b/tests/TestCase.php index d04fb0c..72febbc 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,10 +1,10 @@ 'VendorName\\Skeleton\\Database\\Factories\\'.class_basename($modelName).'Factory' + fn (string $modelName) => 'Omakei\\NextSMS\\Database\\Factories\\'.class_basename($modelName).'Factory' ); } protected function getPackageProviders($app) { return [ - SkeletonServiceProvider::class, + NextSMSServiceProvider::class, ]; } @@ -29,7 +29,7 @@ public function getEnvironmentSetUp($app) config()->set('database.default', 'testing'); /* - $migration = include __DIR__.'/../database/migrations/create_skeleton_table.php.stub'; + $migration = include __DIR__.'/../database/migrations/create_laravel-nextsms_table.php.stub'; $migration->up(); */ } diff --git a/tests/stubs/responses/all_delivery_reports.json b/tests/stubs/responses/all_delivery_reports.json new file mode 100644 index 0000000..4bd03b3 --- /dev/null +++ b/tests/stubs/responses/all_delivery_reports.json @@ -0,0 +1,57 @@ +{ + "results": [ + { + "messageId": "2808579298410163167", + "sentAt": "2020-02-08 12:28:51", + "doneAt": "2020-04-21 18:23:07", + "to": "255716718040", + "smsCount": 1, + "status": { + "groupId": 3, + "groupName": "DELIVERED", + "id": 5, + "name": "DELIVERED_TO_HANDSET", + "description": "Message delivered to handset" + }, + "error": { + "groupId": 0, + "groupName": "OK", + "id": 0, + "name": "NO_ERROR", + "description": "No Error", + "permanent": false + } + }, + { + "messageId": "28227686813403535606", + "sentAt": "2020-02-21 12:21:00", + "doneAt": "2020-04-18 18:23:07", + "to": "255716718040", + "smsCount": 1, + "status": null, + "error": null + }, + { + "messageId": "28089492984101631440", + "sentAt": "2020-02-05 12:28:51", + "doneAt": "2020-04-18 18:23:07", + "to": "255716718040", + "smsCount": 1, + "status": { + "groupId": 3, + "groupName": "DELIVERED", + "id": 5, + "name": "DELIVERED_TO_HANDSET", + "description": "Message delivered to handset" + }, + "error": { + "groupId": 0, + "groupName": "OK", + "id": 0, + "name": "NO_ERROR", + "description": "No Error", + "permanent": false + } + } + ] +} diff --git a/tests/stubs/responses/all_sent_sms_logs.json b/tests/stubs/responses/all_sent_sms_logs.json new file mode 100644 index 0000000..b4a489b --- /dev/null +++ b/tests/stubs/responses/all_sent_sms_logs.json @@ -0,0 +1,62 @@ +{ + "results": [ + { + "messageId": "28695733526003536021", + "sentAt": "2020-04-15 16:09:00", + "doneAt": "2020-04-18 18:23:07", + "to": "255716718040", + "from": "NEXTSMS", + "text": "test", + "smsCount": 1, + "status": { + "groupId": 1, + "groupName": "PENDING", + "id": 7, + "name": "PENDING_ENROUTE", + "description": "Message sent to next instance" + }, + "error": null + }, + { + "messageId": "28255409354101630625", + "sentAt": "2020-02-24 17:21:00", + "doneAt": "2020-04-18 18:23:07", + "to": "255716718040", + "from": "NEXTSMS", + "text": "test", + "smsCount": 1, + "status": { + "groupId": 5, + "groupName": "REJECTED", + "id": 12, + "name": "REJECTED_NOT_ENOUGH_CREDITS", + "description": "Not enough credits" + }, + "error": null + }, + { + "messageId": "28089492984101631440", + "sentAt": "2020-02-05 12:28:51", + "doneAt": "2020-04-18 18:23:07", + "to": "255716718040", + "from": "NEXTSMS", + "text": "Your message", + "smsCount": 1, + "status": { + "groupId": 3, + "groupName": "DELIVERED", + "id": 5, + "name": "DELIVERED_TO_HANDSET", + "description": "Message delivered to handset" + }, + "error": { + "groupId": 0, + "groupName": "OK", + "id": 0, + "name": "NO_ERROR", + "description": "No Error", + "permanent": false + } + } + ] +} diff --git a/tests/stubs/responses/all_sent_sms_logs_with_optional_parameters.json b/tests/stubs/responses/all_sent_sms_logs_with_optional_parameters.json new file mode 100644 index 0000000..8b04d55 --- /dev/null +++ b/tests/stubs/responses/all_sent_sms_logs_with_optional_parameters.json @@ -0,0 +1,28 @@ +{ + "results": [ + { + "messageId": "28089492984101631440", + "sentAt": "2020-02-05 12:28:51", + "doneAt": "2020-04-18 18:23:07", + "to": "255716718040", + "from": "NEXTSMS", + "text": "Your message", + "smsCount": 1, + "status": { + "groupId": 3, + "groupName": "DELIVERED", + "id": 5, + "name": "DELIVERED_TO_HANDSET", + "description": "Message delivered to handset" + }, + "error": { + "groupId": 0, + "groupName": "OK", + "id": 0, + "name": "NO_ERROR", + "description": "No Error", + "permanent": false + } + } + ] +} diff --git a/tests/stubs/responses/create_sub_customer.json b/tests/stubs/responses/create_sub_customer.json new file mode 100644 index 0000000..35c8b7d --- /dev/null +++ b/tests/stubs/responses/create_sub_customer.json @@ -0,0 +1,13 @@ +{ + "success": true, + "status": 200, + "message": "Customer created successfully. Email is sent to your customer email address for confirmation.", + "result": { + "name": "Api Customer", + "username": "apicust", + "phone_number": "+255738234339", + "email": "apicust@customer.com", + "account_type": "Sub Customer (Reseller)", + "sms_price": "20.00 TSH" + } +} diff --git a/tests/stubs/responses/deduct_sub_customer.json b/tests/stubs/responses/deduct_sub_customer.json new file mode 100644 index 0000000..0dec123 --- /dev/null +++ b/tests/stubs/responses/deduct_sub_customer.json @@ -0,0 +1,11 @@ +{ + "success": true, + "status": 200, + "message": "Transaction completed successfully", + "result": { + "Customer": "example@email.com", + "Sms deducted": 2000, + "Your sms balance": 470000, + "Customer sms balance": 3000 + } +} diff --git a/tests/stubs/responses/delivery_report_with_specific_date_range.json b/tests/stubs/responses/delivery_report_with_specific_date_range.json new file mode 100644 index 0000000..0641732 --- /dev/null +++ b/tests/stubs/responses/delivery_report_with_specific_date_range.json @@ -0,0 +1,26 @@ +{ + "results": [ + { + "messageId": "28089492984101631440", + "sentAt": "2020-02-05 12:28:51", + "doneAt": "2020-04-18 18:23:07", + "to": "255716718040", + "smsCount": 1, + "status": { + "groupId": 3, + "groupName": "DELIVERED", + "id": 5, + "name": "DELIVERED_TO_HANDSET", + "description": "Message delivered to handset" + }, + "error": { + "groupId": 0, + "groupName": "OK", + "id": 0, + "name": "NO_ERROR", + "description": "No Error", + "permanent": false + } + } + ] +} diff --git a/tests/stubs/responses/delivery_reports_with_message_id.json b/tests/stubs/responses/delivery_reports_with_message_id.json new file mode 100644 index 0000000..0641732 --- /dev/null +++ b/tests/stubs/responses/delivery_reports_with_message_id.json @@ -0,0 +1,26 @@ +{ + "results": [ + { + "messageId": "28089492984101631440", + "sentAt": "2020-02-05 12:28:51", + "doneAt": "2020-04-18 18:23:07", + "to": "255716718040", + "smsCount": 1, + "status": { + "groupId": 3, + "groupName": "DELIVERED", + "id": 5, + "name": "DELIVERED_TO_HANDSET", + "description": "Message delivered to handset" + }, + "error": { + "groupId": 0, + "groupName": "OK", + "id": 0, + "name": "NO_ERROR", + "description": "No Error", + "permanent": false + } + } + ] +} diff --git a/tests/stubs/responses/get_sms_balance.json b/tests/stubs/responses/get_sms_balance.json new file mode 100644 index 0000000..d835987 --- /dev/null +++ b/tests/stubs/responses/get_sms_balance.json @@ -0,0 +1,3 @@ +{ + "sms_balance": 5 +} diff --git a/tests/stubs/responses/multiple_destination.json b/tests/stubs/responses/multiple_destination.json new file mode 100644 index 0000000..df174c3 --- /dev/null +++ b/tests/stubs/responses/multiple_destination.json @@ -0,0 +1,26 @@ +{ + "messages": [ + { + "to": "255655912841", + "status": { + "groupId": 1, + "groupName": "PENDING", + "id": 7, + "name": "PENDING_ENROUTE", + "description": "Message sent to next instance" + }, + "smsCount": 1 + }, + { + "to": "255716718040", + "status": { + "groupId": 1, + "groupName": "PENDING", + "id": 7, + "name": "PENDING_ENROUTE", + "description": "Message sent to next instance" + }, + "smsCount": 1 + } + ] +} diff --git a/tests/stubs/responses/multiple_sms_to_multiple_destination.json b/tests/stubs/responses/multiple_sms_to_multiple_destination.json new file mode 100644 index 0000000..2b28b4b --- /dev/null +++ b/tests/stubs/responses/multiple_sms_to_multiple_destination.json @@ -0,0 +1,26 @@ +{ + "messages": [ + { + "to": "255716718040", + "status": { + "groupId": 1, + "groupName": "PENDING", + "id": 7, + "name": "PENDING_ENROUTE", + "description": "Message sent to next instance" + }, + "smsCount": 1 + }, + { + "to": "255655912841", + "status": { + "groupId": 1, + "groupName": "PENDING", + "id": 7, + "name": "PENDING_ENROUTE", + "description": "Message sent to next instance" + }, + "smsCount": 1 + } + ] +} diff --git a/tests/stubs/responses/recharge_sub_customer.json b/tests/stubs/responses/recharge_sub_customer.json new file mode 100644 index 0000000..c65b19d --- /dev/null +++ b/tests/stubs/responses/recharge_sub_customer.json @@ -0,0 +1,10 @@ +{ + "success": true, + "status": 200, + "message": "Transaction completed successfully", + "result": { + "Customer": "example@email.com", + "Sms transferred": 5000, + "Your sms balance": 450000 + } +} diff --git a/tests/stubs/responses/schedule_sms.json b/tests/stubs/responses/schedule_sms.json new file mode 100644 index 0000000..b38de9d --- /dev/null +++ b/tests/stubs/responses/schedule_sms.json @@ -0,0 +1,15 @@ +{ + "messages": [ + { + "to": "255716718040", + "status": { + "groupId": 1, + "groupName": "PENDING", + "id": 26, + "name": "PENDING_ACCEPTED", + "description": "Pending accepted , will be sent on scheduled time." + }, + "smsCount": 1 + } + ] +} diff --git a/tests/stubs/responses/single_destination.json b/tests/stubs/responses/single_destination.json new file mode 100644 index 0000000..671447d --- /dev/null +++ b/tests/stubs/responses/single_destination.json @@ -0,0 +1,15 @@ +{ + "messages": [ + { + "to": "255716718040", + "status": { + "groupId": 1, + "groupName": "PENDING", + "id": 7, + "name": "PENDING_ENROUTE", + "description": "Message sent to next instance" + }, + "smsCount": 1 + } + ] +}