diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1754c28
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,8 @@
+/.github export-ignore
+/build export-ignore
+/tests export-ignore
+/tests-resources export-ignore
+/.gitattributes export-ignore
+/.gitignore export-ignore
+
+*.php diff=php
\ No newline at end of file
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 0000000..9385edd
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,56 @@
+name: Tests
+
+on:
+ push:
+ branches:
+ - main
+ - master
+ pull_request:
+ branches:
+ - main
+ - master
+
+jobs:
+ tests:
+ name: PHP ${{ matrix.php }}
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ php:
+ - 7.0
+ - 7.1
+ - 7.2
+ - 7.3
+ - 7.4
+ - 8.0
+ - 8.1
+ - 8.2
+ - 8.3
+ - 8.4
+ - 8.5
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+
+ - id: composer-cache
+ run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('composer.json') }}
+
+ - name: Install dependencies
+ run: composer update --prefer-dist --no-interaction
+
+ - name: Audit dependencies
+ run: composer audit || true
+
+ - name: Running unit tests
+ run: php vendor/bin/phpunit --configuration tests-resources/phpunit.dist.xml --testsuite unit
diff --git a/.gitignore b/.gitignore
index 2a0d621..130e21e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
/tests-resources/config/config.yml
+/tests-resources/phpunit.xml
/vendor
/composer.lock
-/phpunit.xml
-/composer.phar
+.phpunit.result.cache
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 6da4a7b..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-language: php
-php:
-- '7.0'
-- '7.1'
-- '7.2'
-- '7.3'
-- '7.4'
-- '8.0'
-before_script:
-- composer self-update
-- composer install
-script: ./vendor/bin/phpunit --configuration phpunit.dist.xml --testsuite unit
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c67ebb6..190eb08 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,63 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
-## [Unreleased]
+## [3.0.13] - 2026-01-12
+### Added
+- PHP-8.5 support
+
+## [3.0.12] - 2025-07-03
+### Added
+- PHP-8.4 support
+
+## [3.0.11] - 2024-03-27
+### Added
+- service url scheme and host validation
+- service url with port support
+
+### Changed
+- PSR-18 HTTP client related exceptions namespace moved
+
+## [3.0.10] - 2024-01-16
+### Added
+- PHP-8.3 support
+- `SendSmsBag::$timeRestriction` optional parameter
+- `SendSmssBag::$timeRestriction` optional parameter
+- `SendSmsToGroupBag::$timeRestriction` optional parameter
+- `ScheduleSmsBag::$timeRestriction` optional parameter
+- `ScheduleSmssBag::$timeRestriction` optional parameter
+- `ScheduleSmsToGroupBag::$timeRestriction` optional parameter
+### Fixed
+- sending/scheduling smses in large amount
+
+## [3.0.9] - 2024-01-09
+### Fixed
+- expired MFA code verification
+
+## [3.0.8] - 2023-10-18
+### Added
+- `psr/http-message` v2 support
+
+## [3.0.7] - 2022-11-21
+### Fixed
+- dynamic property deprecations
+
+## [3.0.6] - 2022-03-28
+### Fixed
+- HTTP headers parsing, PSR-7 compliant
+
+## [3.0.5] - 2022-03-23
+### Fixed
+- HTTP headers parsing, `HttpClient` issue
+
+## [3.0.4] - 2022-01-17
+### Added
+- `psr/log` v2, v3 support
+
+## [3.0.3] - 2021-07-21
+### Fixed
+- Guzzle PSR7 incompatible URI paths, `The path of a URI with an authority must start with a slash "/" or be empty`
+
+## [3.0.2] - 2021-01-29
### Added
- PHP-8 support
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 199e534..0000000
--- a/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-.PHONY: help
-
-help:
- @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
-
-.DEFAULT_GOAL := help
-
-prepare: ## load dependencies
- docker-compose run -T php /usr/bin/composer update
-
-test: prepare ## run test
- docker-compose run -T php php vendor/bin/phpunit --configuration phpunit.xml
-
-test-suite: prepare ## run test against suite, ex: make test-suite SUITE="unit"
- docker-compose run -T php php vendor/bin/phpunit --configuration phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/README.md b/README.md
index 4f144c0..95ef8f3 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# SMSAPI PHP Client
-[](https://travis-ci.org/smsapi/smsapi-php-client)
+[](https://github.com/smsapi/smsapi-php-client/actions/workflows/tests.yml)
[](https://packagist.org/packages/smsapi/php-client)
[](https://packagist.org/packages/smsapi/php-client)
[](https://packagist.org/packages/smsapi/php-client)
@@ -118,7 +118,7 @@ $apiToken = '0000000000000000000000000000000000000000';
$service = $client->smsapiPlService($apiToken);
```
-## How to use a service with custom URI?
+### How to use *SMSAPI.SE* or *SMSAPI.BG* services?
```php
smsapiComServiceWithUri($apiToken, $uri);
```
@@ -185,50 +185,59 @@ $service->smsFeature()
->sendSms($sms);
```
-### How to send a SMS with optional from field?
+### How to use request parameters?
+
+Request parameters are represented in a form of data transfer object.
+DTOs can be found by searching for 'bag' postfixed classes.
+Each bag may contain required and optional parameters.
+
+#### Required parameters
+
+Required parameters are that class public properties, usually accessible via some form of a setter or named constructor.
+Each parameter can be also set directly by setting bag property, as in example:
+
+##### How to change SMS encoding?
```php
from = 'Test';
+$sms->encoding = 'utf-8';
-$service->smsFeature()
- ->sendSms($sms);
```
-For more usage examples take a look at client test suite.
+#### Optional parameters
-### How to use optional request parameters?
+Some of request's optional parameters have been described by docblock's '@property' annotation.
+You can always add any not documented here optional parameter by setting dynamic property to 'bag'.
+Camel case property names are being converted to snake case on the fly.
-Request parameters are represented in a form of data transfer object.
-DTOs can be found by searching for 'bag' postfixed classes.
-Each bag may contain required and optional parameters.
-Required parameters are that class public properties, usually accessible via some form of a setter or named constructor.
-Optional parameters are described by docblock's '@property' annotation.
-
-Each parameter can be also set directly by setting bag property, as in example:
+##### How to send a SMS with optional from field?
```php
encoding = 'utf-8';
+$sms->from = 'Test';
+$service->smsFeature()
+ ->sendSms($sms);
```
+For more usage examples take a look at client test suite.
+
## How to use additional features?
### How to use proxy server?
@@ -268,14 +277,51 @@ $logger = new class() implements LoggerInterface
$client->setLogger($logger);
```
-## Test package
-1. Download package: `composer create-project smsapi/php-client`
-2. Execute tests: `./vendor/bin/phpunit --configuration phpunit.dist.xml`
+## How to test package
+
+Copy `phpunit.dist.xml` to `phpunit.xml`. You may adjust it to your needs then.
+
+Copy `tests-resources/config/config.dist.yml` to `tests-resources/config/config.yml`. Fill in SMSAPI service connection data.
+
+### How to run unit tests
+
+Unit tests are included into package build process and run against its current version on every commit (see workflow Tests).
+You can run those tests locally with ease using provided Docker configuration, simply run:
+
+```shell
+make test-suite SUITE="unit"
+```
+
+### How to run integration tests
+
+Note that integration test works within an account you have configured in `tests-resources/config/config.yml`.
+Although those test have been written to self-cleanup on exit, in case of failure some trash data may stay.
+Use it with caution.
+
+```shell
+make test-suite SUITE="integration"
+```
+
+### How to run feature tests
+
+Feature test groups are defined in `phpunit.dist.xml`. To run tests execute:
+
+```shell
+make test-suite SUITE="feature-contacts"
+```
+
+### How to run tests against PHP8
+
+To run any of mentioned above against PHP8 use make targets with `php8` suffix. See `Makefile.php8`.
## Docs & Infos
* [SMSAPI.COM API documentation](https://www.smsapi.com/docs)
* [SMSAPI.PL API documentation](https://www.smsapi.pl/docs)
-* [Repository on GitHub](https://github.com/smsapi/smsapi-php-client)
-* [Package on Packagist](https://packagist.org/packages/smsapi/php-client)
+* [SMSAPI.SE API documentation](https://www.smsapi.se/docs)
+* [SMSAPI.BG API documentation](https://www.smsapi.bg/docs)
* [SMSAPI.COM web page](https://smsapi.com)
* [SMSAPI.PL web page](https://smsapi.pl)
+* [SMSAPI.SE web page](https://smsapi.se)
+* [SMSAPI.BG web page](https://smsapi.bg)
+* [Repository on GitHub](https://github.com/smsapi/smsapi-php-client)
+* [Package on Packagist](https://packagist.org/packages/smsapi/php-client)
diff --git a/build/Makefile b/build/Makefile
new file mode 100644
index 0000000..5d807b1
--- /dev/null
+++ b/build/Makefile
@@ -0,0 +1,46 @@
+.PHONY: help build test
+
+include $(CURDIR)/php-7.0/Makefile
+include $(CURDIR)/php-7.1/Makefile
+include $(CURDIR)/php-7.2/Makefile
+include $(CURDIR)/php-7.3/Makefile
+include $(CURDIR)/php-7.4/Makefile
+include $(CURDIR)/php-8.0/Makefile
+include $(CURDIR)/php-8.1/Makefile
+include $(CURDIR)/php-8.2/Makefile
+include $(CURDIR)/php-8.3/Makefile
+include $(CURDIR)/php-8.4/Makefile
+
+help:
+ @grep -hE '^[a-zA-Z0-9_.-]+:.*?## .*$$' $(MAKEFILE_LIST) \
+ | sort \
+ | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+
+build: ## build php images
+ docker compose build
+
+test: ## test all against all php images
+ $(MAKE) test-php-7.0
+ $(MAKE) test-php-7.1
+ $(MAKE) test-php-7.2
+ $(MAKE) test-php-7.3
+ $(MAKE) test-php-7.4
+ $(MAKE) test-php-8.0
+ $(MAKE) test-php-8.1
+ $(MAKE) test-php-8.2
+ $(MAKE) test-php-8.3
+ $(MAKE) test-php-8.4
+
+test-unit: ## test unit suite against all php images
+ $(MAKE) test-suite-php-7.0 SUITE=unit
+ $(MAKE) test-suite-php-7.1 SUITE=unit
+ $(MAKE) test-suite-php-7.2 SUITE=unit
+ $(MAKE) test-suite-php-7.3 SUITE=unit
+ $(MAKE) test-suite-php-7.4 SUITE=unit
+ $(MAKE) test-suite-php-8.0 SUITE=unit
+ $(MAKE) test-suite-php-8.1 SUITE=unit
+ $(MAKE) test-suite-php-8.2 SUITE=unit
+ $(MAKE) test-suite-php-8.3 SUITE=unit
+ $(MAKE) test-suite-php-8.4 SUITE=unit
+
+.DEFAULT_GOAL := help
diff --git a/build/docker-compose.yml b/build/docker-compose.yml
new file mode 100644
index 0000000..dcbfba0
--- /dev/null
+++ b/build/docker-compose.yml
@@ -0,0 +1,80 @@
+version: '3.5'
+
+services:
+
+ php-7.0:
+ build:
+ context: php-7.0
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-7.1:
+ build:
+ context: php-7.1
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-7.2:
+ build:
+ context: php-7.2
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-7.3:
+ build:
+ context: php-7.3
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-7.4:
+ build:
+ context: php-7.4
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-8.0:
+ build:
+ context: php-8.0
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-8.1:
+ build:
+ context: php-8.1
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-8.2:
+ build:
+ context: php-8.2
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-8.3:
+ build:
+ context: php-8.3
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-8.4:
+ build:
+ context: php-8.4
+ volumes:
+ - ..:/app
+ network_mode: host
+
+ php-8.5:
+ build:
+ context: php-8.5
+ volumes:
+ - ..:/app
+ network_mode: host
\ No newline at end of file
diff --git a/Dockerfile b/build/php-7.0/Dockerfile
similarity index 62%
rename from Dockerfile
rename to build/php-7.0/Dockerfile
index f1bf11c..ed516f7 100644
--- a/Dockerfile
+++ b/build/php-7.0/Dockerfile
@@ -1,4 +1,4 @@
-FROM composer:latest as composer
+FROM composer:2.2 as composer
FROM php:7.0-cli-alpine
RUN apk update && \
@@ -8,10 +8,6 @@ RUN apk update && \
g++ \
make
-RUN pecl install xdebug-2.7.2 && \
- pecl clear-cache && \
- docker-php-ext-enable xdebug
-
COPY --from=composer /usr/bin/composer /usr/bin/composer
WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-7.0/Makefile b/build/php-7.0/Makefile
new file mode 100644
index 0000000..62c467c
--- /dev/null
+++ b/build/php-7.0/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-7.0 test-php-7.0 test-suite-php-7.0
+
+prepare-php-7.0: ## load dependencies with php 7.0
+ docker compose run -T php-7.0 /usr/bin/composer update
+
+test-php-7.0: prepare-php-7.0 ## run tests against php 7.0
+ docker compose run -T php-7.0 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-7.0: prepare-php-7.0 ## run suite tests against php 7.0, ex: make test-suite-php-7.0 SUITE="unit"
+ docker compose run -T php-7.0 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-7.1/Dockerfile b/build/php-7.1/Dockerfile
new file mode 100644
index 0000000..2a0487e
--- /dev/null
+++ b/build/php-7.1/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:2.2 as composer
+FROM php:7.1-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-7.1/Makefile b/build/php-7.1/Makefile
new file mode 100644
index 0000000..26cbfad
--- /dev/null
+++ b/build/php-7.1/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-7.1 test-php-7.1 test-suite-php-7.1
+
+prepare-php-7.1: ## load dependencies with php 7.1
+ docker compose run -T php-7.1 /usr/bin/composer update
+
+test-php-7.1: prepare-php-7.1 ## run tests against php 7.1
+ docker compose run -T php-7.1 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-7.1: prepare-php-7.1 ## run suite tests against php 7.1, ex: make test-suite-php-7.1 SUITE="unit"
+ docker compose run -T php-7.1 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-7.2/Dockerfile b/build/php-7.2/Dockerfile
new file mode 100644
index 0000000..bd7b230
--- /dev/null
+++ b/build/php-7.2/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:2.2 as composer
+FROM php:7.2-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-7.2/Makefile b/build/php-7.2/Makefile
new file mode 100644
index 0000000..6cb0833
--- /dev/null
+++ b/build/php-7.2/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-7.2 test-php-7.2 test-suite-php-7.2
+
+prepare-php-7.2: ## load dependencies with php 7.2
+ docker compose run -T php-7.2 /usr/bin/composer update
+
+test-php-7.2: prepare-php-7.2 ## run tests against php 7.2
+ docker compose run -T php-7.2 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-7.2: prepare-php-7.2 ## run suite tests against php 7.2, ex: make test-suite-php-7.2 SUITE="unit"
+ docker compose run -T php-7.2 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-7.3/Dockerfile b/build/php-7.3/Dockerfile
new file mode 100644
index 0000000..28ef4fc
--- /dev/null
+++ b/build/php-7.3/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:2.2 as composer
+FROM php:7.3-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-7.3/Makefile b/build/php-7.3/Makefile
new file mode 100644
index 0000000..99e7817
--- /dev/null
+++ b/build/php-7.3/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-7.3 test-php-7.3 test-suite-php-7.3
+
+prepare-php-7.3: ## load dependencies with php 7.3
+ docker compose run -T php-7.3 /usr/bin/composer update
+
+test-php-7.3: prepare-php-7.3 ## run tests against php 7.3
+ docker compose run -T php-7.3 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-7.3: prepare-php-7.3 ## run suite tests against php 7.3, ex: make test-suite-php-7.3 SUITE="unit"
+ docker compose run -T php-7.3 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-7.4/Dockerfile b/build/php-7.4/Dockerfile
new file mode 100644
index 0000000..d810922
--- /dev/null
+++ b/build/php-7.4/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:2.2 as composer
+FROM php:7.4-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-7.4/Makefile b/build/php-7.4/Makefile
new file mode 100644
index 0000000..d68c343
--- /dev/null
+++ b/build/php-7.4/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-7.4 test-php-7.4 test-suite-php-7.4
+
+prepare-php-7.4: ## load dependencies with php 7.4
+ docker compose run -T php-7.4 /usr/bin/composer update
+
+test-php-7.4: prepare-php-7.4 ## run tests against php 7.4
+ docker compose run -T php-7.4 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-7.4: prepare-php-7.4 ## run suite tests against php 7.4, ex: make test-suite-php-7.4 SUITE="unit"
+ docker compose run -T php-7.4 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/Dockerfile.php8 b/build/php-8.0/Dockerfile
similarity index 50%
rename from Dockerfile.php8
rename to build/php-8.0/Dockerfile
index c2916f9..04a6435 100644
--- a/Dockerfile.php8
+++ b/build/php-8.0/Dockerfile
@@ -3,14 +3,7 @@ FROM php:8.0-cli-alpine
RUN apk update && \
apk upgrade && \
- apk add --no-cache \
- autoconf \
- g++ \
- make
-
-RUN pecl install xdebug-3.0.2 && \
- pecl clear-cache && \
- docker-php-ext-enable xdebug
+ apk add --no-cache make
COPY --from=composer /usr/bin/composer /usr/bin/composer
diff --git a/build/php-8.0/Makefile b/build/php-8.0/Makefile
new file mode 100644
index 0000000..b8b7eaf
--- /dev/null
+++ b/build/php-8.0/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-8.0 test-php-8.0 test-suite-php-8.0
+
+prepare-php-8.0: ## load dependencies with php 8.0
+ docker compose run -T php-8.0 /usr/bin/composer update
+
+test-php-8.0: prepare-php-8.0 ## run tests against php 8.0
+ docker compose run -T php-8.0 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-8.0: prepare-php-8.0 ## run suite tests against php 8.0, ex: make test-suite-php-8.0 SUITE="unit"
+ docker compose run -T php-8.0 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-8.1/Dockerfile b/build/php-8.1/Dockerfile
new file mode 100644
index 0000000..70aea88
--- /dev/null
+++ b/build/php-8.1/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:latest as composer
+FROM php:8.1-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-8.1/Makefile b/build/php-8.1/Makefile
new file mode 100644
index 0000000..607d37b
--- /dev/null
+++ b/build/php-8.1/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-8.1 test-php-8.1 test-suite-php-8.1
+
+prepare-php-8.1: ## load dependencies with php 8.1
+ docker compose run -T php-8.1 /usr/bin/composer update
+
+test-php-8.1: prepare-php-8.1 ## run tests against php 8.1
+ docker compose run -T php-8.1 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-8.1: prepare-php-8.1 ## run suite tests against php 8.1, ex: make test-suite-php-8.1 SUITE="unit"
+ docker compose run -T php-8.1 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-8.2/Dockerfile b/build/php-8.2/Dockerfile
new file mode 100644
index 0000000..677d0ad
--- /dev/null
+++ b/build/php-8.2/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:latest as composer
+FROM php:8.2-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-8.2/Makefile b/build/php-8.2/Makefile
new file mode 100644
index 0000000..3867be5
--- /dev/null
+++ b/build/php-8.2/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-8.2 test-php-8.2 test-suite-php-8.2
+
+prepare-php-8.2: ## load dependencies with php 8.2
+ docker compose run -T php-8.2 /usr/bin/composer update
+
+test-php-8.2: prepare-php-8.2 ## run tests against php 8.2
+ docker compose run -T php-8.2 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-8.2: prepare-php-8.2 ## run suite tests against php 8.2, ex: make test-suite-php-8.2 SUITE="unit"
+ docker compose run -T php-8.2 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-8.3/Dockerfile b/build/php-8.3/Dockerfile
new file mode 100644
index 0000000..94ac096
--- /dev/null
+++ b/build/php-8.3/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:latest as composer
+FROM php:8.3-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-8.3/Makefile b/build/php-8.3/Makefile
new file mode 100644
index 0000000..886f5d4
--- /dev/null
+++ b/build/php-8.3/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-8.3 test-php-8.3 test-suite-php-8.3
+
+prepare-php-8.3: ## load dependencies with php 8.3
+ docker compose run -T php-8.3 /usr/bin/composer update
+
+test-php-8.3: prepare-php-8.3 ## run tests against php 8.3
+ docker compose run -T php-8.3 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-8.3: prepare-php-8.3 ## run suite tests against php 8.3, ex: make test-suite-php-8.3 SUITE="unit"
+ docker compose run -T php-8.3 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-8.4/Dockerfile b/build/php-8.4/Dockerfile
new file mode 100644
index 0000000..ba691e0
--- /dev/null
+++ b/build/php-8.4/Dockerfile
@@ -0,0 +1,10 @@
+FROM composer:latest AS composer
+FROM php:8.4-cli-alpine
+
+RUN apk update && \
+ apk upgrade && \
+ apk add --no-cache make
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-8.4/Makefile b/build/php-8.4/Makefile
new file mode 100644
index 0000000..bd4cfd0
--- /dev/null
+++ b/build/php-8.4/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-8.4 test-php-8.4 test-suite-php-8.4
+
+prepare-php-8.4: ## load dependencies with php 8.4
+ docker compose run -T php-8.4 /usr/bin/composer update
+
+test-php-8.4: prepare-php-8.4 ## run tests against php 8.4
+ docker compose run -T php-8.4 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-8.4: prepare-php-8.4 ## run suite tests against php 8.4, ex: make test-suite-php-8.4 SUITE="unit"
+ docker compose run -T php-8.4 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/build/php-8.5/Dockerfile b/build/php-8.5/Dockerfile
new file mode 100644
index 0000000..c93d62d
--- /dev/null
+++ b/build/php-8.5/Dockerfile
@@ -0,0 +1,6 @@
+FROM composer:latest AS composer
+FROM php:8.5-cli-alpine
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app/
\ No newline at end of file
diff --git a/build/php-8.5/Makefile b/build/php-8.5/Makefile
new file mode 100644
index 0000000..3a38702
--- /dev/null
+++ b/build/php-8.5/Makefile
@@ -0,0 +1,10 @@
+.PHONY: prepare-php-8.5 test-php-8.5 test-suite-php-8.5
+
+prepare-php-8.5: ## load dependencies with php 8.5
+ docker compose run -T php-8.5 /usr/bin/composer update
+
+test-php-8.5: prepare-php-8.5 ## run tests against php 8.5
+ docker compose run -T php-8.5 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml
+
+test-suite-php-8.5: prepare-php-8.5 ## run suite tests against php 8.5, ex: make test-suite-php-8.5 SUITE="unit"
+ docker compose run -T php-8.5 php vendor/bin/phpunit --configuration tests-resources/phpunit.xml --testsuite $(SUITE)
\ No newline at end of file
diff --git a/composer.json b/composer.json
index 330fa8f..8c5dad5 100644
--- a/composer.json
+++ b/composer.json
@@ -16,21 +16,22 @@
}
},
"require": {
- "php": "^7 || ^8.0",
+ "php": "^7 || ~8.0 || ~8.1 || ~8.2 || ~8.3 || ~8.4 || ~8.5",
"ext-json": "*",
- "psr/log": "^1",
- "psr/http-message": "^1",
+ "psr/log": "^1 || ^2 || ^3",
+ "psr/http-message": "~1.0 || ~1.1 || ~2.0",
"psr/http-client": "^1",
"psr/http-factory": "^1"
},
"require-dev": {
"ext-mbstring": "*",
- "phpunit/phpunit": "^6 || ^8",
+ "phpunit/phpunit": "^6 || ~8.5",
+ "phpspec/prophecy": "^1.7",
"symfony/yaml": "^3",
"doctrine/instantiator": "1.0.5 || ^1.4.0",
"phpdocumentor/reflection-docblock": "^4.3 || ^5.2.0",
"phpdocumentor/type-resolver": "^0.5 || ^1.3.0",
- "guzzlehttp/psr7": "^1",
+ "guzzlehttp/psr7": "^1 || ^2",
"ext-curl": "*"
},
"suggest": {
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index f669f77..0000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-version: '3.5'
-
-services:
- php:
- build: .
- volumes:
- - .:/app
- network_mode: host
-
diff --git a/phpcs.xml b/phpcs.xml
deleted file mode 100644
index 1a5512f..0000000
--- a/phpcs.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- SMSAPI Coding Standard
-
-
-
-
- */Standards/*/Tests/*\.(inc|css|js)
-
-
-
-
-
- **/tests/Unit/**
- **/tests/Integration/**
-
-
\ No newline at end of file
diff --git a/src/Curl/Exception/ClientException.php b/src/Curl/Exception/ClientException.php
index 4da31c7..0d2726a 100644
--- a/src/Curl/Exception/ClientException.php
+++ b/src/Curl/Exception/ClientException.php
@@ -4,27 +4,14 @@
namespace Smsapi\Client\Curl\Exception;
-use Exception;
-use Psr\Http\Client\ClientExceptionInterface;
-use Psr\Http\Message\RequestInterface;
+use Smsapi\Client\Infrastructure\HttpClient\ClientException as HttpClientException;
/**
* @api
+ * @deprecated
+ * @see HttpClientException
*/
-class ClientException extends Exception implements ClientExceptionInterface
+class ClientException extends HttpClientException
{
- private $request;
- public static function withRequest(string $message, RequestInterface $request): self
- {
- $exception = new self($message);
- $exception->request = $request;
-
- return $exception;
- }
-
- public function getRequest(): RequestInterface
- {
- return $this->request;
- }
}
\ No newline at end of file
diff --git a/src/Curl/Exception/NetworkException.php b/src/Curl/Exception/NetworkException.php
index a4b7421..9d1729a 100644
--- a/src/Curl/Exception/NetworkException.php
+++ b/src/Curl/Exception/NetworkException.php
@@ -4,12 +4,14 @@
namespace Smsapi\Client\Curl\Exception;
-use Psr\Http\Client\NetworkExceptionInterface;
+use Smsapi\Client\Infrastructure\HttpClient\NetworkException as HttpClientNetworkException;
/**
* @api
+ * @deprecated
+ * @see HttpClientNetworkException
*/
-class NetworkException extends ClientException implements NetworkExceptionInterface
+class NetworkException extends HttpClientNetworkException
{
}
\ No newline at end of file
diff --git a/src/Curl/Exception/RequestException.php b/src/Curl/Exception/RequestException.php
index 2ea1aa5..0b96f1e 100644
--- a/src/Curl/Exception/RequestException.php
+++ b/src/Curl/Exception/RequestException.php
@@ -4,12 +4,14 @@
namespace Smsapi\Client\Curl\Exception;
-use Psr\Http\Client\RequestExceptionInterface;
+use Smsapi\Client\Infrastructure\HttpClient\RequestException as HttpClientRequestException;
/**
* @api
+ * @deprecated
+ * @see HttpClientRequestException
*/
-class RequestException extends ClientException implements RequestExceptionInterface
+class RequestException extends HttpClientRequestException
{
}
\ No newline at end of file
diff --git a/src/Curl/HttpClient.php b/src/Curl/HttpClient.php
index d068cf5..7bfadcb 100644
--- a/src/Curl/HttpClient.php
+++ b/src/Curl/HttpClient.php
@@ -8,8 +8,8 @@
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
-use Smsapi\Client\Curl\Exception\NetworkException;
-use Smsapi\Client\Curl\Exception\RequestException;
+use Smsapi\Client\Infrastructure\HttpClient\NetworkException;
+use Smsapi\Client\Infrastructure\HttpClient\RequestException;
/**
* @internal
@@ -34,7 +34,13 @@ public function sendRequest(RequestInterface $request): ResponseInterface
private function prepareRequestHttpClient(RequestInterface $request)
{
- $url = sprintf("%s://%s%s", $request->getUri()->getScheme(), $request->getUri()->getHost(), $request->getRequestTarget());
+ $url = strtr("{scheme}://{host}{port}{path}", [
+ '{scheme}' => $request->getUri()->getScheme(),
+ '{host}' => $request->getUri()->getHost(),
+ '{port}' => $request->getUri()->getPort() ? ':' . $request->getUri()->getPort() : '',
+ '{path}' => $request->getRequestTarget()
+ ]);
+
$httpClient = curl_init($url);
if ($httpClient === false) {
@@ -88,7 +94,7 @@ private function execute(RequestInterface $request, $httpClient): ResponseInterf
$headerSize = curl_getinfo($httpClient, CURLINFO_HEADER_SIZE);
$headerString = substr($response, 0, $headerSize);
- $headers = array_filter(explode("\n", $headerString), 'trim');
+ $headers = HttpHeadersParser::parse($headerString);
$body = substr($response, $headerSize);
@@ -99,4 +105,4 @@ private function closeHttpClient($httpClient)
{
curl_close($httpClient);
}
-}
\ No newline at end of file
+}
diff --git a/src/Curl/HttpHeadersParser.php b/src/Curl/HttpHeadersParser.php
new file mode 100644
index 0000000..9ae2d69
--- /dev/null
+++ b/src/Curl/HttpHeadersParser.php
@@ -0,0 +1,23 @@
+httpClient->setLogger($logger);
- }
-
public function smsapiPlService(string $apiToken): SmsapiPlService
{
- return $this->httpClient->smsapiPlService($apiToken);
+ return $this->httpClient()->smsapiPlService($apiToken);
}
public function smsapiPlServiceWithUri(string $apiToken, string $uri): SmsapiPlService
{
- return $this->httpClient->smsapiPlServiceWithUri($apiToken, $uri);
+ return $this->httpClient()->smsapiPlServiceWithUri($apiToken, $uri);
}
public function smsapiComService(string $apiToken): SmsapiComService
{
- return $this->httpClient->smsapiComService($apiToken);
+ return $this->httpClient()->smsapiComService($apiToken);
}
public function smsapiComServiceWithUri(string $apiToken, string $uri): SmsapiComService
{
- return $this->httpClient->smsapiComServiceWithUri($apiToken, $uri);
+ return $this->httpClient()->smsapiComServiceWithUri($apiToken, $uri);
+ }
+
+ private function httpClient(): \Smsapi\Client\SmsapiHttpClient
+ {
+ if ($this->logger instanceof LoggerInterface) {
+ $this->httpClient->setLogger($this->logger);
+ }
+
+ return $this->httpClient;
}
-}
\ No newline at end of file
+}
diff --git a/src/Feature/Blacklist/Bag/CreateBlacklistedPhoneNumberBag.php b/src/Feature/Blacklist/Bag/CreateBlacklistedPhoneNumberBag.php
index f51be56..571ef95 100644
--- a/src/Feature/Blacklist/Bag/CreateBlacklistedPhoneNumberBag.php
+++ b/src/Feature/Blacklist/Bag/CreateBlacklistedPhoneNumberBag.php
@@ -10,6 +10,7 @@
* @api
* @property DateTimeInterface $expireAt
*/
+#[\AllowDynamicProperties]
class CreateBlacklistedPhoneNumberBag
{
/** @var string */
diff --git a/src/Feature/Blacklist/Bag/DeleteBlacklistedPhoneNumberBag.php b/src/Feature/Blacklist/Bag/DeleteBlacklistedPhoneNumberBag.php
index cdeb83b..e7ebf9e 100644
--- a/src/Feature/Blacklist/Bag/DeleteBlacklistedPhoneNumberBag.php
+++ b/src/Feature/Blacklist/Bag/DeleteBlacklistedPhoneNumberBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class DeleteBlacklistedPhoneNumberBag
{
/** @var string */
diff --git a/src/Feature/Blacklist/Bag/FindBlacklistedPhoneNumbersBag.php b/src/Feature/Blacklist/Bag/FindBlacklistedPhoneNumbersBag.php
index 635f79f..4e3fbee 100644
--- a/src/Feature/Blacklist/Bag/FindBlacklistedPhoneNumbersBag.php
+++ b/src/Feature/Blacklist/Bag/FindBlacklistedPhoneNumbersBag.php
@@ -10,6 +10,7 @@
* @api
* @property string $q
*/
+#[\AllowDynamicProperties]
class FindBlacklistedPhoneNumbersBag
{
use PaginationBag;
diff --git a/src/Feature/Contacts/Bag/CreateContactBag.php b/src/Feature/Contacts/Bag/CreateContactBag.php
index 1c67efb..54ffd65 100644
--- a/src/Feature/Contacts/Bag/CreateContactBag.php
+++ b/src/Feature/Contacts/Bag/CreateContactBag.php
@@ -16,6 +16,7 @@
* @property string $city
* @property string $source
*/
+#[\AllowDynamicProperties]
class CreateContactBag
{
/**
diff --git a/src/Feature/Contacts/Bag/DeleteContactBag.php b/src/Feature/Contacts/Bag/DeleteContactBag.php
index dacee6d..a3363c0 100644
--- a/src/Feature/Contacts/Bag/DeleteContactBag.php
+++ b/src/Feature/Contacts/Bag/DeleteContactBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class DeleteContactBag
{
diff --git a/src/Feature/Contacts/Bag/FindContactBag.php b/src/Feature/Contacts/Bag/FindContactBag.php
index 6198a1d..157a6bb 100644
--- a/src/Feature/Contacts/Bag/FindContactBag.php
+++ b/src/Feature/Contacts/Bag/FindContactBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindContactBag
{
diff --git a/src/Feature/Contacts/Bag/FindContactsBag.php b/src/Feature/Contacts/Bag/FindContactsBag.php
index ea83eb2..e75445b 100644
--- a/src/Feature/Contacts/Bag/FindContactsBag.php
+++ b/src/Feature/Contacts/Bag/FindContactsBag.php
@@ -18,6 +18,7 @@
* @property string $gender
* @property string $birthdayDate
*/
+#[\AllowDynamicProperties]
class FindContactsBag
{
use PaginationBag;
diff --git a/src/Feature/Contacts/Bag/UpdateContactBag.php b/src/Feature/Contacts/Bag/UpdateContactBag.php
index bfeed43..4458055 100644
--- a/src/Feature/Contacts/Bag/UpdateContactBag.php
+++ b/src/Feature/Contacts/Bag/UpdateContactBag.php
@@ -16,6 +16,7 @@
* @property string $city
* @property string $source
*/
+#[\AllowDynamicProperties]
class UpdateContactBag
{
diff --git a/src/Feature/Contacts/ContactsFeature.php b/src/Feature/Contacts/ContactsFeature.php
index a1f2bfd..df9de39 100644
--- a/src/Feature/Contacts/ContactsFeature.php
+++ b/src/Feature/Contacts/ContactsFeature.php
@@ -19,6 +19,7 @@ interface ContactsFeature
{
/**
* @return Contact[]
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
*/
public function findContacts(FindContactsBag $findContactsBag = null): array;
diff --git a/src/Feature/Contacts/ContactsHttpFeature.php b/src/Feature/Contacts/ContactsHttpFeature.php
index 7d2f38c..7c73a56 100644
--- a/src/Feature/Contacts/ContactsHttpFeature.php
+++ b/src/Feature/Contacts/ContactsHttpFeature.php
@@ -31,6 +31,9 @@ public function __construct(RestRequestExecutor $restRequestExecutor, DataFactor
$this->dataFactoryProvider = $dataFactoryProvider;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function findContacts(FindContactsBag $findContactsBag = null): array
{
$result = $this->restRequestExecutor->read('contacts', (array)$findContactsBag);
diff --git a/src/Feature/Contacts/Fields/Bag/CreateContactFieldBag.php b/src/Feature/Contacts/Fields/Bag/CreateContactFieldBag.php
index 1a45b1c..2269dcc 100644
--- a/src/Feature/Contacts/Fields/Bag/CreateContactFieldBag.php
+++ b/src/Feature/Contacts/Fields/Bag/CreateContactFieldBag.php
@@ -8,6 +8,7 @@
* @api
* @property string $type
*/
+#[\AllowDynamicProperties]
class CreateContactFieldBag
{
diff --git a/src/Feature/Contacts/Fields/Bag/DeleteContactFieldBag.php b/src/Feature/Contacts/Fields/Bag/DeleteContactFieldBag.php
index ecdaabb..cbbb706 100644
--- a/src/Feature/Contacts/Fields/Bag/DeleteContactFieldBag.php
+++ b/src/Feature/Contacts/Fields/Bag/DeleteContactFieldBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class DeleteContactFieldBag
{
diff --git a/src/Feature/Contacts/Fields/Bag/FindContactFieldOptionsBag.php b/src/Feature/Contacts/Fields/Bag/FindContactFieldOptionsBag.php
index e48acc9..adf4d6d 100644
--- a/src/Feature/Contacts/Fields/Bag/FindContactFieldOptionsBag.php
+++ b/src/Feature/Contacts/Fields/Bag/FindContactFieldOptionsBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindContactFieldOptionsBag
{
diff --git a/src/Feature/Contacts/Fields/Bag/UpdateContactFieldBag.php b/src/Feature/Contacts/Fields/Bag/UpdateContactFieldBag.php
index 1dd2024..0e5cdbd 100644
--- a/src/Feature/Contacts/Fields/Bag/UpdateContactFieldBag.php
+++ b/src/Feature/Contacts/Fields/Bag/UpdateContactFieldBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class UpdateContactFieldBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/AssignContactToGroupBag.php b/src/Feature/Contacts/Groups/Bag/AssignContactToGroupBag.php
index f4124ad..b51723e 100644
--- a/src/Feature/Contacts/Groups/Bag/AssignContactToGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/AssignContactToGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class AssignContactToGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/CreateGroupBag.php b/src/Feature/Contacts/Groups/Bag/CreateGroupBag.php
index 4770a7c..80e934a 100644
--- a/src/Feature/Contacts/Groups/Bag/CreateGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/CreateGroupBag.php
@@ -10,6 +10,7 @@
* @property string $idx
* @property integer $contactExpireAfter
*/
+#[\AllowDynamicProperties]
class CreateGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/DeleteGroupBag.php b/src/Feature/Contacts/Groups/Bag/DeleteGroupBag.php
index d6f1bdf..cf7da05 100644
--- a/src/Feature/Contacts/Groups/Bag/DeleteGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/DeleteGroupBag.php
@@ -8,6 +8,7 @@
* @api
* @property bool $deleteContacts
*/
+#[\AllowDynamicProperties]
class DeleteGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/FindContactGroupBag.php b/src/Feature/Contacts/Groups/Bag/FindContactGroupBag.php
index 3c4c8e6..2ecfb43 100644
--- a/src/Feature/Contacts/Groups/Bag/FindContactGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/FindContactGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindContactGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/FindContactGroupsBag.php b/src/Feature/Contacts/Groups/Bag/FindContactGroupsBag.php
index 9ff20f4..053a7bc 100644
--- a/src/Feature/Contacts/Groups/Bag/FindContactGroupsBag.php
+++ b/src/Feature/Contacts/Groups/Bag/FindContactGroupsBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindContactGroupsBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/FindGroupBag.php b/src/Feature/Contacts/Groups/Bag/FindGroupBag.php
index 3b17dd4..b169b8a 100644
--- a/src/Feature/Contacts/Groups/Bag/FindGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/FindGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/UnpinContactFromGroupBag.php b/src/Feature/Contacts/Groups/Bag/UnpinContactFromGroupBag.php
index 550b81d..3b9000d 100644
--- a/src/Feature/Contacts/Groups/Bag/UnpinContactFromGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/UnpinContactFromGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class UnpinContactFromGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Bag/UpdateGroupBag.php b/src/Feature/Contacts/Groups/Bag/UpdateGroupBag.php
index ca9a3e4..2eb918f 100644
--- a/src/Feature/Contacts/Groups/Bag/UpdateGroupBag.php
+++ b/src/Feature/Contacts/Groups/Bag/UpdateGroupBag.php
@@ -10,6 +10,7 @@
* @property string $idx
* @property integer $contactExpireAfter
*/
+#[\AllowDynamicProperties]
class UpdateGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Members/Bag/AddContactToGroupByQueryBag.php b/src/Feature/Contacts/Groups/Members/Bag/AddContactToGroupByQueryBag.php
index 5d63613..a8ee959 100644
--- a/src/Feature/Contacts/Groups/Members/Bag/AddContactToGroupByQueryBag.php
+++ b/src/Feature/Contacts/Groups/Members/Bag/AddContactToGroupByQueryBag.php
@@ -15,6 +15,7 @@
* @property string $gender
* @property string $birthdayDate
*/
+#[\AllowDynamicProperties]
class AddContactToGroupByQueryBag
{
diff --git a/src/Feature/Contacts/Groups/Members/Bag/FindContactInGroupBag.php b/src/Feature/Contacts/Groups/Members/Bag/FindContactInGroupBag.php
index ffa7b02..9238eaa 100644
--- a/src/Feature/Contacts/Groups/Members/Bag/FindContactInGroupBag.php
+++ b/src/Feature/Contacts/Groups/Members/Bag/FindContactInGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindContactInGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Members/Bag/MoveContactToGroupByQueryBag.php b/src/Feature/Contacts/Groups/Members/Bag/MoveContactToGroupByQueryBag.php
index c7591b5..2d88a19 100644
--- a/src/Feature/Contacts/Groups/Members/Bag/MoveContactToGroupByQueryBag.php
+++ b/src/Feature/Contacts/Groups/Members/Bag/MoveContactToGroupByQueryBag.php
@@ -15,6 +15,7 @@
* @property string $gender
* @property string $birthdayDate
*/
+#[\AllowDynamicProperties]
class MoveContactToGroupByQueryBag
{
diff --git a/src/Feature/Contacts/Groups/Members/Bag/PinContactToGroupBag.php b/src/Feature/Contacts/Groups/Members/Bag/PinContactToGroupBag.php
index be2f10a..9fe9cbb 100644
--- a/src/Feature/Contacts/Groups/Members/Bag/PinContactToGroupBag.php
+++ b/src/Feature/Contacts/Groups/Members/Bag/PinContactToGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class PinContactToGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupBag.php b/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupBag.php
index 992a168..50cde48 100644
--- a/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupBag.php
+++ b/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class UnpinContactFromGroupBag
{
diff --git a/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupByQueryBag.php b/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupByQueryBag.php
index a7a8cd3..e36d5c8 100644
--- a/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupByQueryBag.php
+++ b/src/Feature/Contacts/Groups/Members/Bag/UnpinContactFromGroupByQueryBag.php
@@ -15,6 +15,7 @@
* @property string $gender
* @property string $birthdayDate
*/
+#[\AllowDynamicProperties]
class UnpinContactFromGroupByQueryBag
{
diff --git a/src/Feature/Contacts/Groups/Permissions/Bag/CreateGroupPermissionBag.php b/src/Feature/Contacts/Groups/Permissions/Bag/CreateGroupPermissionBag.php
index 6305d3e..e48404a 100644
--- a/src/Feature/Contacts/Groups/Permissions/Bag/CreateGroupPermissionBag.php
+++ b/src/Feature/Contacts/Groups/Permissions/Bag/CreateGroupPermissionBag.php
@@ -10,6 +10,7 @@
* @property string $write
* @property string $send
*/
+#[\AllowDynamicProperties]
class CreateGroupPermissionBag
{
diff --git a/src/Feature/Contacts/Groups/Permissions/Bag/DeleteGroupPermissionBag.php b/src/Feature/Contacts/Groups/Permissions/Bag/DeleteGroupPermissionBag.php
index f6ba1f2..591cad1 100644
--- a/src/Feature/Contacts/Groups/Permissions/Bag/DeleteGroupPermissionBag.php
+++ b/src/Feature/Contacts/Groups/Permissions/Bag/DeleteGroupPermissionBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class DeleteGroupPermissionBag
{
diff --git a/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionBag.php b/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionBag.php
index 4c285e0..150efff 100644
--- a/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionBag.php
+++ b/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindGroupPermissionBag
{
diff --git a/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionsBag.php b/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionsBag.php
index e7d2327..384d47e 100644
--- a/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionsBag.php
+++ b/src/Feature/Contacts/Groups/Permissions/Bag/FindGroupPermissionsBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindGroupPermissionsBag
{
diff --git a/src/Feature/Contacts/Groups/Permissions/Bag/UpdateGroupPermissionBag.php b/src/Feature/Contacts/Groups/Permissions/Bag/UpdateGroupPermissionBag.php
index 4a807e4..54fd14e 100644
--- a/src/Feature/Contacts/Groups/Permissions/Bag/UpdateGroupPermissionBag.php
+++ b/src/Feature/Contacts/Groups/Permissions/Bag/UpdateGroupPermissionBag.php
@@ -10,6 +10,7 @@
* @property string $write
* @property string $send
*/
+#[\AllowDynamicProperties]
class UpdateGroupPermissionBag
{
diff --git a/src/Feature/Hlr/Bag/SendHlrBag.php b/src/Feature/Hlr/Bag/SendHlrBag.php
index fa7428a..991fc60 100644
--- a/src/Feature/Hlr/Bag/SendHlrBag.php
+++ b/src/Feature/Hlr/Bag/SendHlrBag.php
@@ -8,6 +8,7 @@
* @api
* @property string $idx
*/
+#[\AllowDynamicProperties]
class SendHlrBag
{
diff --git a/src/Feature/Mfa/Bag/CreateMfaBag.php b/src/Feature/Mfa/Bag/CreateMfaBag.php
index 05036be..bafdac6 100644
--- a/src/Feature/Mfa/Bag/CreateMfaBag.php
+++ b/src/Feature/Mfa/Bag/CreateMfaBag.php
@@ -10,6 +10,7 @@
* @property string $content
* @property bool $fast
*/
+#[\AllowDynamicProperties]
class CreateMfaBag
{
/**
diff --git a/src/Feature/Mfa/Bag/VerificationMfaBag.php b/src/Feature/Mfa/Bag/VerificationMfaBag.php
index f1c8a7c..ba371e4 100644
--- a/src/Feature/Mfa/Bag/VerificationMfaBag.php
+++ b/src/Feature/Mfa/Bag/VerificationMfaBag.php
@@ -7,6 +7,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class VerificationMfaBag
{
/**
diff --git a/src/Feature/Mms/Bag/SendMmsBag.php b/src/Feature/Mms/Bag/SendMmsBag.php
index e3ce33a..6db03e1 100644
--- a/src/Feature/Mms/Bag/SendMmsBag.php
+++ b/src/Feature/Mms/Bag/SendMmsBag.php
@@ -7,6 +7,7 @@
* @api
* @property bool $test
*/
+#[\AllowDynamicProperties]
class SendMmsBag
{
diff --git a/src/Feature/ShortUrl/Bag/CreateShortUrlLinkBag.php b/src/Feature/ShortUrl/Bag/CreateShortUrlLinkBag.php
index 7452f19..05b5e94 100644
--- a/src/Feature/ShortUrl/Bag/CreateShortUrlLinkBag.php
+++ b/src/Feature/ShortUrl/Bag/CreateShortUrlLinkBag.php
@@ -14,12 +14,13 @@
* @property DateTimeInterface $expire
* @property string $description
*/
+#[\AllowDynamicProperties]
class CreateShortUrlLinkBag
{
public static function withUrl(string $url): self
{
- $bag = new self();
+ $bag = new CreateShortUrlLinkBag();
$bag->url = $url;
return $bag;
}
diff --git a/src/Feature/Sms/Bag/DeleteScheduledSmssBag.php b/src/Feature/Sms/Bag/DeleteScheduledSmssBag.php
index 748a5e6..51f6a09 100644
--- a/src/Feature/Sms/Bag/DeleteScheduledSmssBag.php
+++ b/src/Feature/Sms/Bag/DeleteScheduledSmssBag.php
@@ -4,6 +4,10 @@
namespace Smsapi\Client\Feature\Sms\Bag;
+/**
+ * @api
+ */
+#[\AllowDynamicProperties]
class DeleteScheduledSmssBag
{
/** @var array */
diff --git a/src/Feature/Sms/Bag/ScheduleSmsBag.php b/src/Feature/Sms/Bag/ScheduleSmsBag.php
index dc328e9..2ce4b52 100644
--- a/src/Feature/Sms/Bag/ScheduleSmsBag.php
+++ b/src/Feature/Sms/Bag/ScheduleSmsBag.php
@@ -24,7 +24,9 @@
* @property string $param2
* @property string $param3
* @property string $param4
+ * @property string $timeRestriction
*/
+#[\AllowDynamicProperties]
class ScheduleSmsBag
{
/** @var string */
@@ -65,6 +67,9 @@ public function setParams(array $params): self
return $this;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function setExternalId(string $idx, bool $checkIdx = null): self
{
$this->idx = [$idx];
diff --git a/src/Feature/Sms/Bag/ScheduleSmsToGroupBag.php b/src/Feature/Sms/Bag/ScheduleSmsToGroupBag.php
index 0b39fa5..0981fd2 100644
--- a/src/Feature/Sms/Bag/ScheduleSmsToGroupBag.php
+++ b/src/Feature/Sms/Bag/ScheduleSmsToGroupBag.php
@@ -20,7 +20,9 @@
* @property bool $normalize
* @property string $notifyUrl
* @property bool $test
+ * @property string $timeRestriction
*/
+#[\AllowDynamicProperties]
class ScheduleSmsToGroupBag
{
@@ -53,6 +55,9 @@ public static function withTemplateName(DateTimeInterface $scheduleAt, string $g
return $bag;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function setExternalId(string $idx, bool $checkIdx = null): self
{
$this->idx = [$idx];
diff --git a/src/Feature/Sms/Bag/ScheduleSmssBag.php b/src/Feature/Sms/Bag/ScheduleSmssBag.php
index 3e5fd10..b214567 100644
--- a/src/Feature/Sms/Bag/ScheduleSmssBag.php
+++ b/src/Feature/Sms/Bag/ScheduleSmssBag.php
@@ -25,10 +25,12 @@
* @property array $param2
* @property array $param3
* @property array $param4
+ * @property string $timeRestriction
*/
+#[\AllowDynamicProperties]
class ScheduleSmssBag
{
- /** @var array */
+ /** @var array|string */
public $to;
/** @var DateTimeInterface */
@@ -66,6 +68,9 @@ public function setParams(array $params): self
return $this;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function setExternalId(array $idx, bool $checkIdx = null): self
{
$this->idx = $idx;
diff --git a/src/Feature/Sms/Bag/SendSmsBag.php b/src/Feature/Sms/Bag/SendSmsBag.php
index 181a00f..9ac48b5 100644
--- a/src/Feature/Sms/Bag/SendSmsBag.php
+++ b/src/Feature/Sms/Bag/SendSmsBag.php
@@ -24,7 +24,9 @@
* @property string $param2
* @property string $param3
* @property string $param4
+ * @property string $timeRestriction
*/
+#[\AllowDynamicProperties]
class SendSmsBag
{
/** @var string */
@@ -60,6 +62,9 @@ public function setParams(array $params): self
return $this;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function setExternalId(string $idx, bool $checkIdx = null): self
{
$this->idx = [$idx];
diff --git a/src/Feature/Sms/Bag/SendSmsToGroupBag.php b/src/Feature/Sms/Bag/SendSmsToGroupBag.php
index 52adfdf..a6da846 100644
--- a/src/Feature/Sms/Bag/SendSmsToGroupBag.php
+++ b/src/Feature/Sms/Bag/SendSmsToGroupBag.php
@@ -19,7 +19,9 @@
* @property bool $normalize
* @property string $notifyUrl
* @property bool $test
+ * @property string $timeRestriction
*/
+#[\AllowDynamicProperties]
class SendSmsToGroupBag
{
/** @var string */
@@ -46,6 +48,9 @@ public static function withTemplateName(string $group, string $templateName): se
return $bag;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function setExternalId(string $idx, bool $checkIdx = null): self
{
$this->idx = [$idx];
diff --git a/src/Feature/Sms/Bag/SendSmssBag.php b/src/Feature/Sms/Bag/SendSmssBag.php
index fddbf5b..279bc53 100644
--- a/src/Feature/Sms/Bag/SendSmssBag.php
+++ b/src/Feature/Sms/Bag/SendSmssBag.php
@@ -25,10 +25,12 @@
* @property array $param2
* @property array $param3
* @property array $param4
+ * @property string $timeRestriction
*/
+#[\AllowDynamicProperties]
class SendSmssBag
{
- /** @var array */
+ /** @var array|string */
public $to;
/** @var string */
@@ -61,6 +63,9 @@ public function setParams(array $params): self
return $this;
}
+ /**
+ * @todo method signature to be changed in next major release as implicitly marking parameter as nullable is deprecated since PHP 8.4
+ */
public function setExternalId(array $idx, bool $checkIdx = null): self
{
$this->idx = $idx;
diff --git a/src/Feature/Sms/Sendernames/Bag/CreateSendernameBag.php b/src/Feature/Sms/Sendernames/Bag/CreateSendernameBag.php
index 81d6f10..09d40c1 100644
--- a/src/Feature/Sms/Sendernames/Bag/CreateSendernameBag.php
+++ b/src/Feature/Sms/Sendernames/Bag/CreateSendernameBag.php
@@ -6,6 +6,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class CreateSendernameBag
{
public $sender;
diff --git a/src/Feature/Sms/Sendernames/Bag/DeleteSendernameBag.php b/src/Feature/Sms/Sendernames/Bag/DeleteSendernameBag.php
index 9f54dde..8e34293 100644
--- a/src/Feature/Sms/Sendernames/Bag/DeleteSendernameBag.php
+++ b/src/Feature/Sms/Sendernames/Bag/DeleteSendernameBag.php
@@ -6,6 +6,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class DeleteSendernameBag
{
public $sender;
diff --git a/src/Feature/Sms/Sendernames/Bag/FindSendernameBag.php b/src/Feature/Sms/Sendernames/Bag/FindSendernameBag.php
index cf4e58e..60abde0 100644
--- a/src/Feature/Sms/Sendernames/Bag/FindSendernameBag.php
+++ b/src/Feature/Sms/Sendernames/Bag/FindSendernameBag.php
@@ -6,6 +6,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class FindSendernameBag
{
public $sender;
diff --git a/src/Feature/Sms/Sendernames/Bag/MakeSendernameDefaultBag.php b/src/Feature/Sms/Sendernames/Bag/MakeSendernameDefaultBag.php
index 28539af..991e2d0 100644
--- a/src/Feature/Sms/Sendernames/Bag/MakeSendernameDefaultBag.php
+++ b/src/Feature/Sms/Sendernames/Bag/MakeSendernameDefaultBag.php
@@ -6,6 +6,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class MakeSendernameDefaultBag
{
public $sender;
diff --git a/src/Feature/Sms/SmsHttpFeature.php b/src/Feature/Sms/SmsHttpFeature.php
index 10dea8b..b2e2299 100644
--- a/src/Feature/Sms/SmsHttpFeature.php
+++ b/src/Feature/Sms/SmsHttpFeature.php
@@ -110,6 +110,8 @@ public function sendFlashSmsToGroup(SendSmsToGroupBag $sendSmsToGroupBag): array
public function sendSmss(SendSmssBag $sendSmssBag): array
{
+ $sendSmssBag->to = implode(',', $sendSmssBag->to);
+
return array_map(
[$this->dataFactoryProvider->provideSmsFactory(), 'createFromObject'],
$this->makeRequest($sendSmssBag)->list
@@ -118,6 +120,8 @@ public function sendSmss(SendSmssBag $sendSmssBag): array
public function sendFlashSmss(SendSmssBag $sendSmssBag): array
{
+ $sendSmssBag->to = implode(',', $sendSmssBag->to);
+
return array_map(
[$this->dataFactoryProvider->provideSmsFactory(), 'createFromObject'],
$this->makeRequest($sendSmssBag)->list
@@ -146,6 +150,7 @@ public function scheduleSms(ScheduleSmsBag $scheduleSmsBag): Sms
public function scheduleSmss(ScheduleSmssBag $scheduleSmssBag): array
{
+ $scheduleSmssBag->to = implode(',', $scheduleSmssBag->to);
$scheduleSmssBag->dateValidate = true;
return array_map(
diff --git a/src/Feature/Subusers/Bag/CreateSubuserBag.php b/src/Feature/Subusers/Bag/CreateSubuserBag.php
index 2ea4249..a45cb3c 100644
--- a/src/Feature/Subusers/Bag/CreateSubuserBag.php
+++ b/src/Feature/Subusers/Bag/CreateSubuserBag.php
@@ -8,6 +8,7 @@
* @property bool $active
* @property string $description
*/
+#[\AllowDynamicProperties]
class CreateSubuserBag
{
/** @var string */
diff --git a/src/Feature/Subusers/Bag/DeleteSubuserBag.php b/src/Feature/Subusers/Bag/DeleteSubuserBag.php
index 65edc86..b5c741c 100644
--- a/src/Feature/Subusers/Bag/DeleteSubuserBag.php
+++ b/src/Feature/Subusers/Bag/DeleteSubuserBag.php
@@ -6,6 +6,7 @@
/**
* @api
*/
+#[\AllowDynamicProperties]
class DeleteSubuserBag
{
public $id;
diff --git a/src/Feature/Subusers/Bag/UpdateSubuserBag.php b/src/Feature/Subusers/Bag/UpdateSubuserBag.php
index f7eea08..fff8f26 100644
--- a/src/Feature/Subusers/Bag/UpdateSubuserBag.php
+++ b/src/Feature/Subusers/Bag/UpdateSubuserBag.php
@@ -11,6 +11,7 @@
* @property bool $active
* @property string $description
*/
+#[\AllowDynamicProperties]
class UpdateSubuserBag
{
/** @var string */
diff --git a/src/Feature/Vms/Bag/SendVmsBag.php b/src/Feature/Vms/Bag/SendVmsBag.php
index a194a28..ef88cef 100644
--- a/src/Feature/Vms/Bag/SendVmsBag.php
+++ b/src/Feature/Vms/Bag/SendVmsBag.php
@@ -13,6 +13,7 @@
* @property bool $checkIdx
* @property bool $test
*/
+#[\AllowDynamicProperties]
class SendVmsBag
{
diff --git a/src/Infrastructure/HttpClient/ClientException.php b/src/Infrastructure/HttpClient/ClientException.php
new file mode 100644
index 0000000..a17f164
--- /dev/null
+++ b/src/Infrastructure/HttpClient/ClientException.php
@@ -0,0 +1,30 @@
+request = $request;
+
+ return $exception;
+ }
+
+ public function getRequest(): RequestInterface
+ {
+ return $this->request;
+ }
+}
\ No newline at end of file
diff --git a/src/Infrastructure/HttpClient/Decorator/BaseUriDecorator.php b/src/Infrastructure/HttpClient/Decorator/BaseUriDecorator.php
index 4747292..79cc2fc 100644
--- a/src/Infrastructure/HttpClient/Decorator/BaseUriDecorator.php
+++ b/src/Infrastructure/HttpClient/Decorator/BaseUriDecorator.php
@@ -7,6 +7,7 @@
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
+use Smsapi\Client\Infrastructure\HttpClient\RequestException;
/**
* @internal
@@ -33,15 +34,22 @@ private function prependBaseUri(RequestInterface $request): RequestInterface
{
$uri = $request->getUri();
+ if (!filter_var($this->baseUri, FILTER_VALIDATE_URL)) {
+ throw RequestException::withRequest("Invalid Base URI", $request);
+ }
+
$baseUriParts = parse_url($this->baseUri);
$scheme = $baseUriParts['scheme'] ?? '';
$host = $baseUriParts['host'] ?? '';
- $path = $baseUriParts['path'] ?? '';
+ $port = $baseUriParts['port'] ?? null;
+ $basePath = $baseUriParts['path'] ?? '';
+ $basePath = rtrim($basePath, '/');
- $uri = $uri->withScheme($scheme);
+ $uri = $uri->withPath($basePath . '/' . $uri->getPath());
+ $uri = $uri->withPort($port);
$uri = $uri->withHost($host);
- $uri = $uri->withPath($path . $uri->getPath());
+ $uri = $uri->withScheme($scheme);
return $request->withUri($uri);
}
diff --git a/src/Infrastructure/HttpClient/Decorator/LoggerDecorator.php b/src/Infrastructure/HttpClient/Decorator/LoggerDecorator.php
index 926ce3f..decd283 100644
--- a/src/Infrastructure/HttpClient/Decorator/LoggerDecorator.php
+++ b/src/Infrastructure/HttpClient/Decorator/LoggerDecorator.php
@@ -26,13 +26,20 @@ public function __construct(ClientInterface $client, LoggerInterface $logger)
public function sendRequest(RequestInterface $request): ResponseInterface
{
$this->logger->info('Request', [
+ 'request' => $request,
'method' => $request->getMethod(),
'uri' => $request->getUri(),
+ 'headers' => $request->getHeaders(),
+ 'body' => $request->getBody()->getContents(),
]);
$response = $this->client->sendRequest($request);
- $this->logger->info('Response', ['response' => $response]);
+ $this->logger->info('Response', [
+ 'response' => $response,
+ 'headers' => $response->getHeaders(),
+ 'body' => $response->getBody()->getContents(),
+ ]);
return $response;
}
diff --git a/src/Infrastructure/HttpClient/NetworkException.php b/src/Infrastructure/HttpClient/NetworkException.php
new file mode 100644
index 0000000..8464188
--- /dev/null
+++ b/src/Infrastructure/HttpClient/NetworkException.php
@@ -0,0 +1,15 @@
+ 'json'] + $builtInParameters, $userParameters);
return new Request($method, $path, $this->queryFormatter->format($parameters));
}
diff --git a/src/Infrastructure/ResponseHttpCode.php b/src/Infrastructure/ResponseHttpCode.php
index 2c201f5..4ef42b5 100644
--- a/src/Infrastructure/ResponseHttpCode.php
+++ b/src/Infrastructure/ResponseHttpCode.php
@@ -13,5 +13,6 @@ class ResponseHttpCode
const CREATED = 201;
const ACCEPTED = 202;
const NO_CONTENT = 204;
+ const REQUEST_TIMEOUT = 408;
const SERVICE_UNAVAILABLE = 503;
}
diff --git a/src/Infrastructure/ResponseMapper/RestResponseMapper.php b/src/Infrastructure/ResponseMapper/RestResponseMapper.php
index fff15e3..04106a3 100644
--- a/src/Infrastructure/ResponseMapper/RestResponseMapper.php
+++ b/src/Infrastructure/ResponseMapper/RestResponseMapper.php
@@ -40,6 +40,8 @@ public function map(ResponseInterface $response): stdClass
return new stdClass();
} elseif ($statusCode == ResponseHttpCode::SERVICE_UNAVAILABLE) {
throw ApiErrorException::withMessageAndStatusCode('Service unavailable', $statusCode);
+ } elseif ($statusCode == ResponseHttpCode::REQUEST_TIMEOUT) {
+ throw ApiErrorException::withMessageAndStatusCode('Request timed out', $statusCode);
} elseif ($contents) {
$object = $this->jsonDecode->decode($contents);
diff --git a/src/SmsapiClient.php b/src/SmsapiClient.php
index 564843f..1c2bc2b 100644
--- a/src/SmsapiClient.php
+++ b/src/SmsapiClient.php
@@ -12,7 +12,7 @@
*/
interface SmsapiClient extends LoggerAwareInterface
{
- const VERSION = 'Unreleased';
+ const VERSION = '3.0.13';
public function smsapiPlService(string $apiToken): SmsapiPlService;
diff --git a/tests-resources/config/config.dist.yml b/tests-resources/config/config.dist.yml
index c3da0b8..7f9437f 100644
--- a/tests-resources/config/config.dist.yml
+++ b/tests-resources/config/config.dist.yml
@@ -1,3 +1,3 @@
Service name: SMSAPI.PL
API URI: https://api.smsapi.pl
-logger: false
+API token: 0000000000000000000000000000000000000000
diff --git a/tests-resources/config/config.yml.example b/tests-resources/config/config.yml.example
index ffbe66d..f93b66c 100644
--- a/tests-resources/config/config.yml.example
+++ b/tests-resources/config/config.yml.example
@@ -1,4 +1,3 @@
Service name: "SMSAPI.PL" OR "SMSAPI.COM"
API token: 40-characters length string generated in SMSAPI Panel
API URI: "https://api.smsapi.pl", "https://api.smsapi.com", "https://api2.smsapi.pl" or "https://api2.smsapi.com"
-logger: true
diff --git a/phpunit.dist.xml b/tests-resources/phpunit.dist.xml
similarity index 53%
rename from phpunit.dist.xml
rename to tests-resources/phpunit.dist.xml
index 95cb746..4d4acd5 100644
--- a/phpunit.dist.xml
+++ b/tests-resources/phpunit.dist.xml
@@ -1,7 +1,7 @@
- tests
+ ../tests
- tests/Unit
+ ../tests/Unit
- tests/Integration
+ ../tests/Integration
- tests/Integration/Feature/Contacts
- tests/Unit/Feature/Contacts
+ ../tests/Integration/Feature/Contacts
+ ../tests/Unit/Feature/Contacts
- tests/Integration/Feature/Hlr
+ ../tests/Integration/Feature/Hlr
- tests/Integration/Feature/Mms
+ ../tests/Integration/Feature/Mms
- tests/Integration/Feature/Ping
+ ../tests/Integration/Feature/Ping
- tests/Integration/Feature/Profile
+ ../tests/Integration/Feature/Profile
- tests/Unit/Feature/Push
+ ../tests/Unit/Feature/Push
- tests/Integration/Feature/Sendernames
+ ../tests/Integration/Feature/Sendernames
- tests/Integration/Feature/ShortUrl
+ ../tests/Integration/Feature/ShortUrl
- tests/Integration/Feature/Sms
- tests/Unit/Feature/Sms
+ ../tests/Integration/Feature/Sms
+ ../tests/Unit/Feature/Sms
- tests/Integration/Feature/Mfa
+ ../tests/Integration/Feature/Mfa
- tests/Integration/Feature/Subusers
+ ../tests/Integration/Feature/Subusers
- tests/Integration/Feature/Vms
+ ../tests/Integration/Feature/Vms
- tests/Integration/Feature/Blacklist
+ ../tests/Integration/Feature/Blacklist
+
+
+
+
+
+
diff --git a/tests/Fixture/PhoneNumberFixture.php b/tests/Fixture/PhoneNumberFixture.php
index 2ab2941..9f06e1f 100644
--- a/tests/Fixture/PhoneNumberFixture.php
+++ b/tests/Fixture/PhoneNumberFixture.php
@@ -20,4 +20,9 @@ public static function anyValidMobile(): string
{
return (string)((int)self::$validMobile + self::$i++);
}
+
+ public static function xValidMobile(int $x): array
+ {
+ return array_map(function () {return self::anyValidMobile();}, range(1, $x));
+ }
}
diff --git a/tests/Helper/HttpClient/HttpClientRequestSpy.php b/tests/Helper/HttpClient/HttpClientRequestSpy.php
new file mode 100644
index 0000000..375e984
--- /dev/null
+++ b/tests/Helper/HttpClient/HttpClientRequestSpy.php
@@ -0,0 +1,27 @@
+lastSentRequest = $request;
+
+ return new Response();
+ }
+
+ public function getLastSentRequest(): RequestInterface
+ {
+ return $this->lastSentRequest;
+ }
+}
\ No newline at end of file
diff --git a/tests/Integration/Feature/Mfa/MfaFeatureTest.php b/tests/Integration/Feature/Mfa/MfaFeatureTest.php
index 7fdbc3c..1a01cfb 100644
--- a/tests/Integration/Feature/Mfa/MfaFeatureTest.php
+++ b/tests/Integration/Feature/Mfa/MfaFeatureTest.php
@@ -32,7 +32,7 @@ public function it_should_create_mfa()
/**
* @test
*/
- public function it_should_not_create_mfa_for_an_ivalid_mobile_phone_number()
+ public function it_should_not_create_mfa_for_an_invalid_mobile_phone_number()
{
//given
$mfaFeature = self::$smsapiService->mfaFeature();
@@ -97,7 +97,7 @@ public function it_should_not_verify_invalid_code()
{
//given
$mfaFeature = self::$smsapiService->mfaFeature();
- $verificationMfaBag = new VerificationMfaBag('123 456', PhoneNumberFixture::anyValidMobile());
+ $verificationMfaBag = new VerificationMfaBag('invalid', PhoneNumberFixture::anyValidMobile());
//expect
$this->expectException(SmsapiClientException::class);
$this->expectExceptionMessage('MFA code has invalid format');
diff --git a/tests/Integration/Feature/Sms/SmsFeatureTest.php b/tests/Integration/Feature/Sms/SmsFeatureTest.php
index e78a420..c5051f8 100644
--- a/tests/Integration/Feature/Sms/SmsFeatureTest.php
+++ b/tests/Integration/Feature/Sms/SmsFeatureTest.php
@@ -82,12 +82,12 @@ public function it_should_send_flash_sms()
public function it_should_send_smss()
{
$smsFeature = self::$smsapiService->smsFeature();
- $sendSmssBag = $this->givenSmssToSend();
+ $sendSmssBag = $this->givenSmssToSend(2);
$sendSmssBag->test = true;
$results = $smsFeature->sendSmss($sendSmssBag);
- $this->assertCount(count($sendSmssBag->to), $results);
+ $this->assertCount(2, $results);
}
/**
@@ -96,12 +96,12 @@ public function it_should_send_smss()
public function it_should_send_flash_smss()
{
$smsFeature = self::$smsapiService->smsFeature();
- $sendSmssBag = $this->givenSmssToSend();
+ $sendSmssBag = $this->givenSmssToSend(2);
$sendSmssBag->test = true;
$results = $smsFeature->sendFlashSmss($sendSmssBag);
- $this->assertCount(count($sendSmssBag->to), $results);
+ $this->assertCount(2, $results);
}
/**
@@ -110,7 +110,7 @@ public function it_should_send_flash_smss()
public function it_should_not_receive_content_details_for_smss()
{
$smsFeature = self::$smsapiService->smsFeature();
- $sendSmsesBag = $this->givenSmssToSend();
+ $sendSmsesBag = $this->givenSmssToSend(2);
$sendSmsesBag->test = true;
/** @var Sms[] $results */
@@ -142,12 +142,12 @@ public function it_should_schedule_sms()
public function it_should_schedule_smss()
{
$smsFeature = self::$smsapiService->smsFeature();
- $scheduleSmssBag = $this->givenSmssToSchedule();
+ $scheduleSmssBag = $this->givenSmssToSchedule(2);
$scheduleSmssBag->test = true;
$results = $smsFeature->scheduleSmss($scheduleSmssBag);
- $this->assertCount(count($scheduleSmssBag->to), $results);
+ $this->assertCount(2, $results);
}
/**
@@ -171,7 +171,7 @@ public function it_should_schedule_flash_sms()
public function it_should_delete_scheduled_smss()
{
$smsFeature = self::$smsapiService->smsFeature();
- $scheduleSmssBag = $this->givenSmssToSchedule();
+ $scheduleSmssBag = $this->givenSmssToSchedule(2);
$results = $smsFeature->scheduleSmss($scheduleSmssBag);
$smsIds = array_map(function (Sms $sms) {
@@ -190,12 +190,9 @@ private function givenSmsToSend(): SendSmsBag
return SendSmsBag::withMessage($someReceiver, 'some message');
}
- private function givenSmssToSend(): SendSmssBag
+ private function givenSmssToSend(int $x): SendSmssBag
{
- $receivers = [
- PhoneNumberFixture::anyValidMobile(),
- PhoneNumberFixture::anyValidMobile(),
- ];
+ $receivers = PhoneNumberFixture::xValidMobile($x);
return SendSmssBag::withMessage($receivers, 'some message');
}
@@ -206,13 +203,10 @@ private function givenSmsToSchedule(): ScheduleSmsBag
return ScheduleSmsBag::withMessage($someDate, $someReceiver, 'some message');
}
- private function givenSmssToSchedule(): ScheduleSmssBag
+ private function givenSmssToSchedule(int $x): ScheduleSmssBag
{
$someDate = new DateTime('+1 day noon');
- $receivers = [
- PhoneNumberFixture::anyValidMobile(),
- PhoneNumberFixture::anyValidMobile(),
- ];
+ $receivers = PhoneNumberFixture::xValidMobile($x);
return ScheduleSmssBag::withMessage($someDate, $receivers, 'some message');
}
}
diff --git a/tests/SmsapiClientIntegrationTestCase.php b/tests/SmsapiClientIntegrationTestCase.php
index 6c547c8..09cc561 100644
--- a/tests/SmsapiClientIntegrationTestCase.php
+++ b/tests/SmsapiClientIntegrationTestCase.php
@@ -27,16 +27,8 @@ public static function prepare()
$apiUri = Config::get('API URI');
- if (!filter_var($apiUri, FILTER_VALIDATE_URL)) {
- throw new RuntimeException('Invalid API URI');
- }
-
$smsapiHttpClient = new SmsapiHttpClient();
- if (Config::get('logger')) {
- $smsapiHttpClient->setLogger(new TestLogger());
- }
-
$serviceName = Config::get('Service name');
if ($serviceName === ServiceName::SMSAPI_PL) {
self::$smsapiService = $smsapiHttpClient->smsapiPlServiceWithUri(self::$apiToken, $apiUri);
diff --git a/tests/TestLogger.php b/tests/TestLogger.php
deleted file mode 100644
index 3ff6519..0000000
--- a/tests/TestLogger.php
+++ /dev/null
@@ -1,37 +0,0 @@
- $value) {
- if ($value instanceof RequestInterface) {
- $context[$item] = [
- 'headers' => $value->getHeaders(),
- 'uri' => $value->getUri()->__toString(),
- 'method' => $value->getMethod(),
- 'contents' => $value->getBody()->__toString(),
- ];
- } elseif ($value instanceof ResponseInterface) {
- $context[$item] = [
- 'headers' => $value->getHeaders(),
- 'status_code' => $value->getStatusCode(),
- 'contents' => $value->getBody()->__toString(),
- ];
- }
- }
-
- echo sprintf("[%s] %s (%s)\n", $level, $message, print_r($context));
- }
-}
diff --git a/tests/Unit/Curl/HttpHeadersParserTest.php b/tests/Unit/Curl/HttpHeadersParserTest.php
new file mode 100644
index 0000000..cdfdbd8
--- /dev/null
+++ b/tests/Unit/Curl/HttpHeadersParserTest.php
@@ -0,0 +1,85 @@
+assertArrayNotHasKey('HTTP/1.1 202 OK', $headers);
+ $this->assertNotContains('HTTP/1.1 202 OK', $headers);
+ }
+
+ /**
+ * @test
+ */
+ public function not_bypass_non_http_status_line_first_line()
+ {
+ $rawHeaders = "Header1: any\r\nHeader2: any, other\r\n";
+
+ $headers = HttpHeadersParser::parse($rawHeaders);
+
+ $this->assertArrayHasKey('Header1', $headers);
+ }
+
+ /**
+ * @test
+ */
+ public function bypass_empty_line()
+ {
+ $rawHeaders = "HTTP/1.1 202 OK\r\nHeader1: any\r\nHeader2: any, other\r\n\r\n";
+
+ $headers = HttpHeadersParser::parse($rawHeaders);
+
+ $this->assertCount(2, array_keys($headers));
+ }
+
+ /**
+ * @test
+ */
+ public function add_all_headers()
+ {
+ $rawHeaders = "HTTP/1.1 202 OK\r\nHeader1: any\r\nHeader2: any, other\r\n";
+
+ $headers = HttpHeadersParser::parse($rawHeaders);
+
+ $this->assertArrayHasKey('Header1', $headers);
+ $this->assertArrayHasKey('Header2', $headers);
+ }
+
+ /**
+ * @test
+ */
+ public function add_single_value_headers()
+ {
+ $rawHeaders = "HTTP/1.1 202 OK\r\nHeader1: any\r\nHeader2: any, other\r\n";
+
+ $headers = HttpHeadersParser::parse($rawHeaders);
+
+ $this->assertEquals('any', $headers['Header1']);
+ }
+
+ /**
+ * @test
+ */
+ public function add_multi_value_headers()
+ {
+ $rawHeaders = "HTTP/1.1 202 OK\r\nHeader1: any\r\nHeader2: any, other\r\n";
+
+ $headers = HttpHeadersParser::parse($rawHeaders);
+
+ $this->assertEquals('any, other', $headers['Header2']);
+ }
+}
\ No newline at end of file
diff --git a/tests/Unit/Infrastructure/HttpClient/Decorator/BaseUriDecoratorTest.php b/tests/Unit/Infrastructure/HttpClient/Decorator/BaseUriDecoratorTest.php
new file mode 100644
index 0000000..0e538bd
--- /dev/null
+++ b/tests/Unit/Infrastructure/HttpClient/Decorator/BaseUriDecoratorTest.php
@@ -0,0 +1,162 @@
+sendRequestToAnyEndpoint($decorator);
+
+ $this->assertEquals($expectedRequestUri, (string)$sentRequestSpy->getLastSentRequest()->getUri());
+ $this->assertEquals($expectedRequestSchema, $sentRequestSpy->getLastSentRequest()->getUri()->getScheme());
+ }
+
+ /**
+ * @test
+ * @testWith
+ * ["example.com"]
+ * ["example.com/base/"]
+ * ["example.com:80"]
+ * ["example.com:80/base/"]
+ * ["any://"]
+ * ["any:///"]
+ * ["any://:80/"]
+ */
+ public function dont_send_request_without_base_schema_or_host(string $baseUri)
+ {
+ $sentRequestSpy = new HttpClientRequestSpy();
+ $decorator = new BaseUriDecorator($sentRequestSpy, $baseUri);
+
+ $this->expectException(RequestException::class);
+ $this->expectExceptionMessage('Invalid Base URI');
+ $this->sendRequestToAnyEndpoint($decorator);
+ }
+
+ /**
+ * @test
+ * @testWith
+ * ["any://example.com", "any://example.com/endpoint", "example.com"]
+ * ["any://example.com:80", "any://example.com:80/endpoint", "example.com"]
+ * ["any://example", "any://example/endpoint", "example"]
+ * ["any://example:80", "any://example:80/endpoint", "example"]
+ */
+ public function send_request_with_base_host(string $baseUri, string $expectedRequestUri, string $expectedRequestHost)
+ {
+ $sentRequestSpy = new HttpClientRequestSpy();
+ $decorator = new BaseUriDecorator($sentRequestSpy, $baseUri);
+
+ $this->sendRequestToAnyEndpoint($decorator);
+
+ $this->assertEquals($expectedRequestUri, (string)$sentRequestSpy->getLastSentRequest()->getUri());
+ $this->assertEquals($expectedRequestHost, $sentRequestSpy->getLastSentRequest()->getUri()->getHost());
+ }
+
+ /**
+ * @test
+ * @testWith
+ * ["any://example.com:80", "any://example.com:80/endpoint", "80"]
+ * ["any://example:80", "any://example:80/endpoint", "80"]
+ */
+ public function send_request_with_base_port(string $baseUri, string $expectedRequestUri, string $expectedRequestPort)
+ {
+ $sentRequestSpy = new HttpClientRequestSpy();
+ $decorator = new BaseUriDecorator($sentRequestSpy, $baseUri);
+
+ $this->sendRequestToAnyEndpoint($decorator);
+
+ $this->assertEquals($expectedRequestUri, (string)$sentRequestSpy->getLastSentRequest()->getUri());
+ $this->assertEquals($expectedRequestPort, $sentRequestSpy->getLastSentRequest()->getUri()->getPort());
+ }
+
+ /**
+ * @test
+ * @testWith
+ * ["any://example.com", "any://example.com/endpoint"]
+ * ["any://example", "any://example/endpoint"]
+ * ["any://example.com/base", "any://example.com/base/endpoint"]
+ * ["any://example/base", "any://example/base/endpoint"]
+ */
+ public function send_request_without_base_port(string $baseUri, string $expectedRequestUri)
+ {
+ $sentRequestSpy = new HttpClientRequestSpy();
+ $decorator = new BaseUriDecorator($sentRequestSpy, $baseUri);
+
+ $this->sendRequestToAnyEndpoint($decorator);
+
+ $this->assertEquals($expectedRequestUri, (string)$sentRequestSpy->getLastSentRequest()->getUri());
+ $this->assertEquals('', $sentRequestSpy->getLastSentRequest()->getUri()->getPort());
+ }
+
+ /**
+ * @test
+ * @testWith
+ * ["any://example.com/base", "any://example.com/base/endpoint", "/base/endpoint"]
+ * ["any://example.com:80/base/", "any://example.com:80/base/endpoint", "/base/endpoint"]
+ * ["any://example:80/base", "any://example:80/base/endpoint", "/base/endpoint"]
+ * ["any://example.com/base/", "any://example.com/base/endpoint", "/base/endpoint"]
+ * ["any://example/base/", "any://example/base/endpoint", "/base/endpoint"]
+ * ["any://example.com:80/base/", "any://example.com:80/base/endpoint", "/base/endpoint"]
+ * ["any://example:80/base", "any://example:80/base/endpoint", "/base/endpoint"]
+ */
+ public function send_request_with_base_path(string $baseUri, string $expectedRequestUri, string $expectedRequestPath)
+ {
+ $sentRequestSpy = new HttpClientRequestSpy();
+ $decorator = new BaseUriDecorator($sentRequestSpy, $baseUri);
+
+ $this->sendRequestToAnyEndpoint($decorator);
+
+ $this->assertEquals($expectedRequestUri, (string)$sentRequestSpy->getLastSentRequest()->getUri());
+ $this->assertEquals($expectedRequestPath, $sentRequestSpy->getLastSentRequest()->getUri()->getPath());
+ }
+
+ /**
+ * @test
+ * @testWith
+ * ["any://example.com", "any://example.com/endpoint", "/endpoint"]
+ * ["any://example", "any://example/endpoint", "/endpoint"]
+ * ["any://example.com:80", "any://example.com:80/endpoint", "/endpoint"]
+ * ["any://example:80", "any://example:80/endpoint", "/endpoint"]
+ * ["any://example.com/", "any://example.com/endpoint", "/endpoint"]
+ * ["any://example/", "any://example/endpoint", "/endpoint"]
+ * ["any://example.com:80/", "any://example.com:80/endpoint", "/endpoint"]
+ * ["any://example:80/", "any://example:80/endpoint", "/endpoint"]
+ */
+ public function send_request_without_base_path(string $baseUri, string $expectedRequestUri, string $expectedRequestPath)
+ {
+ $sentRequestSpy = new HttpClientRequestSpy();
+ $decorator = new BaseUriDecorator($sentRequestSpy, $baseUri);
+
+ $this->sendRequestToAnyEndpoint($decorator);
+
+ $this->assertEquals($expectedRequestUri, (string)$sentRequestSpy->getLastSentRequest()->getUri());
+ $this->assertEquals($expectedRequestPath, $sentRequestSpy->getLastSentRequest()->getUri()->getPath());
+ }
+
+ private function sendRequestToAnyEndpoint(BaseUriDecorator $decorator)
+ {
+ $request = new Request('ANY', 'endpoint');
+ $decorator->sendRequest($request);
+ }
+}
\ No newline at end of file
diff --git a/tests/Unit/Infrastructure/RequestMapper/LegacyRequestMapperTest.php b/tests/Unit/Infrastructure/RequestMapper/LegacyRequestMapperTest.php
index 63f910f..9b5246a 100644
--- a/tests/Unit/Infrastructure/RequestMapper/LegacyRequestMapperTest.php
+++ b/tests/Unit/Infrastructure/RequestMapper/LegacyRequestMapperTest.php
@@ -25,10 +25,69 @@ public function init()
/**
* @test
*/
- public function it_should_create_post_request_with_parameters()
+ public function it_should_use_path_as_request_uri()
{
$path = 'anyPath';
+ $request = $this->mapper->map($path, []);
+
+ $this->assertEquals($path, $request->getUri());
+ }
+
+ /**
+ * @test
+ */
+ public function it_should_send_request_as_post()
+ {
+ $request = $this->mapper->map('anyPath', []);
+
+ $this->assertEquals(RequestHttpMethod::POST, $request->getMethod());
+ }
+
+ /**
+ * @test
+ */
+ public function it_should_always_set_format_json_parameter()
+ {
+ $builtInParameters = [];
+ $userParameters = [];
+
+ $request = $this->mapper->map('anyPath', $builtInParameters, $userParameters);
+
+ $this->assertEquals('format=json', $request->getBody());
+ }
+
+ /**
+ * @test
+ */
+ public function it_should_prepend_format_parameter_to_built_in_parameters_when_none()
+ {
+ $builtInParameters = [];
+ $userParameters = ['any2' => 'any'];
+
+ $request = $this->mapper->map('anyPath', $builtInParameters, $userParameters);
+
+ $this->assertEquals('format=json&any2=any', $request->getBody());
+ }
+
+ /**
+ * @test
+ */
+ public function it_should_prepend_format_parameter_to_built_in_parameters_when_set()
+ {
+ $builtInParameters = ['any1' => 'any'];
+ $userParameters = [];
+
+ $request = $this->mapper->map('anyPath', $builtInParameters, $userParameters);
+
+ $this->assertEquals('format=json&any1=any', $request->getBody());
+ }
+
+ /**
+ * @test
+ */
+ public function it_should_merge_both_built_in_and_user_parameters()
+ {
$builtInParameters = [
'any1' => 'any',
];
@@ -36,11 +95,8 @@ public function it_should_create_post_request_with_parameters()
'any2' => 'any',
];
- $request = $this->mapper->map($path, $builtInParameters, $userParameters);
-
- $this->assertEquals($path, $request->getUri());
- $this->assertEquals(RequestHttpMethod::POST, $request->getMethod());
+ $request = $this->mapper->map('anyPath', $builtInParameters, $userParameters);
- $this->assertEquals('any1=any&format=json&any2=any', $request->getBody());
+ $this->assertEquals('format=json&any1=any&any2=any', $request->getBody());
}
}
diff --git a/tests/Unit/Infrastructure/ResponseMapper/RestResponseMapperTest.php b/tests/Unit/Infrastructure/ResponseMapper/RestResponseMapperTest.php
index dfbb087..9419e90 100644
--- a/tests/Unit/Infrastructure/ResponseMapper/RestResponseMapperTest.php
+++ b/tests/Unit/Infrastructure/ResponseMapper/RestResponseMapperTest.php
@@ -92,6 +92,18 @@ public function it_should_throw_exception_on_service_unavailable()
$this->restResponseMapper->map($responseWithServiceUnavailable);
}
+ /**
+ * @test
+ */
+ public function it_should_throw_exception_on_request_timeout()
+ {
+ $responseWithServiceUnavailable = new Response(ResponseHttpCode::REQUEST_TIMEOUT);
+
+ $this->expectException(ApiErrorException::class);
+ $this->expectExceptionMessage("Request timed out");
+ $this->restResponseMapper->map($responseWithServiceUnavailable);
+ }
+
/**
* @test
*/