Comparer les révisions

..

Pas de révisions en commun. "main" et "2.0.3" ont des historiques entièrement différents.
main ... 2.0.3

21 fichiers modifiés avec 130 ajouts et 185 suppressions

Voir le fichier

@ -4,40 +4,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased](https://git.d3data.de/D3Public/linkmobility-php-client/compare/2.2.0...rel_2.x)
## [Unreleased](https://git.d3data.de/D3Private/linkmobility-php-client/compare/2.0.3...rel_2.x)
## [2.2.0](https://git.d3data.de/D3Public/linkmobility-php-client/compare/2.1.0...2.2.0) - 2023-06-29
### Added
- bump psr/http-message dependency to version 2
### Changed
- use assertion exception
## [2.1.0](https://git.d3data.de/D3Public/linkmobility-php-client/compare/2.0.3...2.1.0) - 2023-01-20
### Added
- installable in PHP > 8.0
- debug logger to log all comunications in debug mode (default Guzzle client only)
- retry middleware to request again in defined error cases (default Guzzle client only)
### Fixed
- missing getRecipientsList() in RecipientsListInterface
### Deprecated
- unused client argument in recipient list class
### Removed
- unused ApiException class
## [2.0.3](https://git.d3data.de/D3Public/linkmobility-php-client/compare/2.0.2...2.0.3) - 2022-12-26
## [2.0.3](https://git.d3data.de/D3Private/linkmobility-php-client/compare/2.0.2...2.0.3) - 2022-12-26
### Changed
- allow Guzzle v7.3 for more backward compatibility
## [2.0.2](https://git.d3data.de/D3Public/linkmobility-php-client/compare/2.0.1...2.0.2) - 2022-07-28
## [2.0.2](https://git.d3data.de/D3Private/linkmobility-php-client/compare/2.0.1...2.0.2) - 2022-07-28
### Changed
- add support note
- adjust readme
## [2.0.1](https://git.d3data.de/D3Public/linkmobility-php-client/compare/2.0.0...2.0.1) - 2022-07-28
## [2.0.1](https://git.d3data.de/D3Private/linkmobility-php-client/compare/2.0.0...2.0.1) - 2022-07-28
### Added
- phpstan code checks
@ -48,18 +26,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- wrong return type of LoggerHandler::getInstance
## [2.0.0](https://git.d3data.de/D3Public/linkmobility-php-client/compare/1.3.0...2.0.0) - 2022-07-19
## [2.0.0](https://git.d3data.de/D3Private/linkmobility-php-client/compare/1.3.0...2.0.0) - 2022-07-19
### Changed
- adjust to PHP >= 7.3 and current dependency packages
## [1.3.1](https://git.d3data.de/D3Public/linkmobility-php-client/compare/1.3.0...1.3.1) - 2022-07-28
## [1.3.1](https://git.d3data.de/D3Private/linkmobility-php-client/compare/1.3.0...1.3.1) - 2022-07-28
### Changed
- improve code quality
### Fixed
- wrong return type of LoggerHandler::getInstance
## [1.3.0](https://git.d3data.de/D3Public/linkmobility-php-client/compare/1.2.1...1.3.0) - 2022-07-18
## [1.3.0](https://git.d3data.de/D3Private/linkmobility-php-client/compare/1.2.1...1.3.0) - 2022-07-18
### Added
- tests added
@ -67,12 +45,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- tests use generated example phone numbers
- move recipient checks from list to recipient itself
## [1.2.1](https://git.d3data.de/D3Public/linkmobility-php-client/compare/1.2.0...1.2.1) - 2022-07-15
## [1.2.1](https://git.d3data.de/D3Private/linkmobility-php-client/compare/1.2.0...1.2.1) - 2022-07-15
### Changed
- extend log messages
- sanitize special phone number format before request
## [1.2.0](https://git.d3data.de/D3Public/linkmobility-php-client/compare/1.1.0...1.2.0) - 2022-07-14
## [1.2.0](https://git.d3data.de/D3Private/linkmobility-php-client/compare/1.1.0...1.2.0) - 2022-07-14
### Added
- collect exception messages in a class
- collect URI parts in a class
@ -82,14 +60,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- assign sender address type only if sender is set
- extract logger handler from client
## [1.1.0](https://git.d3data.de/D3Public/linkmobility-php-client/compare/1.0.0...1.1.0) - 2022-07-13
## [1.1.0](https://git.d3data.de/D3Private/linkmobility-php-client/compare/1.0.0...1.1.0) - 2022-07-13
### Added
- make installable in PHP 8
### Removed
- remove unused dependency
## [1.0.0](https://git.d3data.de/D3Public/linkmobility-php-client/releases/tag/1.0.0) - 2022-07-13
## [1.0.0](https://git.d3data.de/D3Private/linkmobility-php-client/releases/tag/1.0.0) - 2022-07-13
### Added
- initial implementation
- SMS requests (text or binary)

Voir le fichier

@ -18,8 +18,8 @@ composer require d3/linkmobility-php-client
```
```
$client = new \D3\LinkmobilityClient\Client('personal accesstoken');
\D3\LinkmobilityClient\LoggerHandler::getInstance()->setLogger($logger); // optional
$client = new Client('personal accesstoken');
$client->setLogger($logger); // optional
$request = new D3\LinkmobilityClient\SMS\RequestFactory($message, $client)->getSmsRequest())
->addRecipient(new D3\LinkmobilityClient\ValueObject\Recipient('recipient number', 'DE'));
$response = $client->request($request)

Voir le fichier

@ -18,8 +18,8 @@ composer require d3/linkmobility-php-client
```
```
$client = new \D3\LinkmobilityClient\Client('personal accesstoken');
\D3\LinkmobilityClient\LoggerHandler::getInstance()->setLogger($logger); // optional
$client = new Client('personal accesstoken');
$client->setLogger($logger); // optional
$request = new D3\LinkmobilityClient\SMS\RequestFactory($message, $client)->getSmsRequest())
->addRecipient(new D3\LinkmobilityClient\ValueObject\Recipient('recipient number', 'DE'));
$response = $client->request($request)

Voir le fichier

@ -31,7 +31,7 @@ abstract class ApiTestCase extends TestCase
* @return mixed
* @throws ReflectionException
*/
public function callMethod($object, string $methodName, array $arguments = [])
public function callMethod(object $object, string $methodName, array $arguments = [])
{
$class = new ReflectionClass($object);
$method = $class->getMethod($methodName);
@ -47,7 +47,7 @@ abstract class ApiTestCase extends TestCase
* @param $value
* @throws ReflectionException
*/
public function setValue($object, string $valueName, $value)
public function setValue(object $object, string $valueName, $value)
{
$reflection = new ReflectionClass($object);
$property = $reflection->getProperty($valueName);
@ -63,7 +63,7 @@ abstract class ApiTestCase extends TestCase
* @return mixed
* @throws ReflectionException
*/
public function getValue($object, string $valueName)
public function getValue(object $object, string $valueName)
{
$reflection = new ReflectionClass($object);
$property = $reflection->getProperty($valueName);

Voir le fichier

@ -17,6 +17,7 @@ namespace D3\LinkmobilityClient\Tests;
use Assert\InvalidArgumentException;
use D3\LinkmobilityClient\Client;
use D3\LinkmobilityClient\Exceptions\ApiException;
use D3\LinkmobilityClient\LoggerHandler;
use D3\LinkmobilityClient\Request\RequestInterface;
use D3\LinkmobilityClient\Response\Response;
@ -26,9 +27,11 @@ use D3\LinkmobilityClient\Url\Url;
use D3\LinkmobilityClient\Url\UrlInterface;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Psr7\Response as GuzzleResponse;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Http\Message\ResponseInterface as MessageResponseInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Log\AbstractLogger;
use Psr\Log\LoggerInterface;
use ReflectionException;
class ClientTest extends ApiTestCase
@ -97,28 +100,6 @@ class ClientTest extends ApiTestCase
];
}
/**
* @test
* @throws ReflectionException
* @return void
* @covers \D3\LinkmobilityClient\Client::getDefaultClient
*/
public function testGetDefaultClient()
{
/** @var Client|MockObject $sut */
$sut = $this->getMockBuilder(Client::class)
->setConstructorArgs(['accessTokenFixture'])
->getMock();
$this->assertInstanceOf(
GuzzleClient::class,
$this->callMethod(
$sut,
'getDefaultClient'
)
);
}
/**
* @test
* @return void
@ -192,20 +173,41 @@ class ClientTest extends ApiTestCase
/**
* @test
* @param $okStatus
* @return void
* @throws ReflectionException
* @dataProvider rawRequestDataProvider
* @covers \D3\LinkmobilityClient\Client::rawRequest
*/
public function testRawRequest()
public function testRawRequest($okStatus)
{
$statusCode = $okStatus ? '200' : '301';
/** @var StreamInterface|MockObject $streamMock */
$streamMock = $this->getMockBuilder(StreamInterface::class)
->getMock();
/** @var GuzzleResponse|MockObject $responseMock */
$responseMock = $this->getMockBuilder( GuzzleResponse::class)
/** @var MessageResponseInterface|MockObject $responseMock */
$responseMock = $this->getMockBuilder(MessageResponseInterface::class)
->onlyMethods([
'getStatusCode',
'getBody',
'withStatus',
'getReasonPhrase',
'getProtocolVersion',
'withProtocolVersion',
'getHeaders',
'hasHeader',
'getHeader',
'getHeaderLine',
'withHeader',
'withAddedHeader',
'withoutHeader',
'withBody',
])
->disableOriginalConstructor()
->getMock();
$responseMock->expects($this->atLeastOnce())->method('getStatusCode')->willReturn($statusCode);
$responseMock->expects($this->atLeastOnce())
->method('getBody')->willReturn($streamMock);
@ -215,6 +217,17 @@ class ClientTest extends ApiTestCase
->getMock();
$requestClientMock->expects($this->once())->method('request')->willReturn($responseMock);
/** @var LoggerInterface|MockObject $loggerMock */
$loggerMock = $this->getMockBuilder(AbstractLogger::class)
->onlyMethods(['debug', 'error', 'log'])
->getMock();
/** @var LoggerHandler|MockObject $loggerHandlerMock */
$loggerHandlerMock = $this->getMockBuilder(LoggerHandler::class)
->onlyMethods(['getLogger'])
->getMock();
$loggerHandlerMock->method('getLogger')->willReturn($loggerMock);
/** @var Client|MockObject $clientMock */
$clientMock = $this->getMockBuilder(Client::class)
->disableOriginalConstructor()
@ -222,14 +235,30 @@ class ClientTest extends ApiTestCase
'getLoggerHandler',
])
->getMock();
$clientMock->expects($this->atLeastOnce())
->method('getLoggerHandler')->willReturn($loggerHandlerMock);
$this->setValue($clientMock, 'requestClient', $requestClientMock);
if (false === $okStatus) {
$this->expectException(ApiException::class);
}
$this->assertSame(
$responseMock,
$this->callMethod($clientMock, 'rawRequest', ['myUrl'])
);
}
/**
* @return array
*/
public function rawRequestDataProvider(): array
{
return [
'OK status' => [true],
'NOK status' => [false],
];
}
/**
* @test
* @return void
@ -246,38 +275,4 @@ class ClientTest extends ApiTestCase
)
);
}
/**
* @test
* @return void
* @throws \PHPUnit\Framework\ExpectationFailedException
* @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
* @covers \D3\LinkmobilityClient\Client::getLoggerMiddleware
*/
public function testGetLoggerMiddleware()
{
$this->assertIsCallable(
$this->callMethod(
$this->api,
'getLoggerMiddleware'
)
);
}
/**
* @test
* @return void
* @throws \PHPUnit\Framework\ExpectationFailedException
* @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
* @covers \D3\LinkmobilityClient\Client::getRetryMiddleware
*/
public function testGetRetryMiddleware()
{
$this->assertIsCallable(
$this->callMethod(
$this->api,
'getRetryMiddleware'
)
);
}
}

Voir le fichier

@ -7,5 +7,5 @@ composer create-project -s dev --prefer-source [--repository '{"type": "vcs", "u
# Run tests
```
./vendor/bin/phpunit [--no-coverage] [--coverage-html=cov]
./vendor/bin/phpunit [--no-coverage]
```

Voir le fichier

@ -15,8 +15,9 @@ declare(strict_types=1);
namespace D3\LinkmobilityClient\Tests\ValueObject;
use Assert\InvalidArgumentException;
use D3\LinkmobilityClient\Tests\ApiTestCase;
use D3\LinkmobilityClient\ValueObject\SmsBinaryMessage;
use Phlib\SmsLength\Exception\InvalidArgumentException;
use Phlib\SmsLength\SmsLength;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
@ -93,7 +94,7 @@ class SmsBinaryMessageTest extends SmsMessageAbstractTest
if ($valid) {
$smsLengthMock->expects($this->never())->method('validate')->willReturn(true);
} else {
$smsLengthMock->expects($this->atLeastOnce())->method('validate')->willThrowException(new InvalidArgumentException());
$smsLengthMock->expects($this->atLeastOnce())->method('validate')->willThrowException(new \Phlib\SmsLength\Exception\InvalidArgumentException());
}
/** @var SmsBinaryMessage|MockObject $message */

Voir le fichier

@ -19,6 +19,7 @@ use Assert\InvalidArgumentException;
use D3\LinkmobilityClient\Tests\ApiTestCase;
use D3\LinkmobilityClient\ValueObject\SmsBinaryMessage;
use Phlib\SmsLength\SmsLength;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
abstract class SmsMessageAbstractTest extends ApiTestCase

Voir le fichier

@ -21,13 +21,12 @@
"GPL-3.0-or-later"
],
"require": {
"php": "^7.3 || ^8.0.3",
"php": "^7.3 || ~8.0.3",
"beberlei/assert": "^3.3",
"guzzlehttp/guzzle": "^7.3",
"psr/http-message": "^1.0 || ^2.0",
"psr/http-message": "~1.0",
"phlib/sms-length": "^2.0",
"giggsey/libphonenumber-for-php": "^8.12.50",
"caseyamcl/guzzle_retry_middleware": "^2.8",
"ext-json": "*"
},
"require-dev": {

Voir le fichier

@ -15,17 +15,14 @@ declare(strict_types=1);
namespace D3\LinkmobilityClient;
use Assert\InvalidArgumentException;
use D3\LinkmobilityClient\Exceptions\ApiException;
use D3\LinkmobilityClient\Exceptions\ExceptionMessages;
use D3\LinkmobilityClient\Request\RequestInterface;
use D3\LinkmobilityClient\Url\Url;
use D3\LinkmobilityClient\Url\UrlInterface;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\MessageFormatter;
use GuzzleHttp\Middleware;
use GuzzleRetry\GuzzleRetryMiddleware;
use InvalidArgumentException;
use Psr\Http\Message\ResponseInterface;
class Client
@ -38,28 +35,14 @@ class Client
{
$this->accessToken = $accessToken;
$this->apiUrl = $apiUrl ?: new Url();
$this->requestClient = $client ?: $this->getDefaultClient();
}
/**
* @return GuzzleClient
*/
protected function getDefaultClient(): GuzzleClient
{
$handlerStack = HandlerStack::create();
$handlerStack->push($this->getLoggerMiddleware());
$handlerStack->push($this->getRetryMiddleware());
return new GuzzleClient( [
'base_uri' => $this->apiUrl->getBaseUri(),
'handler' => $handlerStack
]);
$this->requestClient = $client ?: new \GuzzleHttp\Client([ 'base_uri' => $this->apiUrl->getBaseUri() ]);
}
/**
* @param RequestInterface $request
*
* @return Response\ResponseInterface
* @throws ApiException
* @throws GuzzleException
* @throws InvalidArgumentException
*/
@ -78,14 +61,30 @@ class Client
* @param array $options
*
* @return ResponseInterface
* @throws ApiException
* @throws GuzzleException
*/
protected function rawRequest($url, string $method = RequestInterface::METHOD_GET, array $options = []): ResponseInterface
{
$options['headers']['Authorization'] = 'Bearer '.$this->accessToken;
$response = $this->requestClient->request($method, $url, $options);
$this->getLoggerHandler()->getLogger()->debug('linkmobility request: '.$url, $options);
$response = $this->requestClient->request(
$method,
$url,
$options
);
if ($response->getStatusCode() != 200) {
$message = sprintf(ExceptionMessages::NOK_REQUEST_RETURN, $url, $response->getStatusCode());
$response->getBody()->rewind();
$this->getLoggerHandler()->getLogger()->error($message, [$response->getBody()->getContents()]);
throw new ApiException($message);
}
$response->getBody()->rewind();
$this->getLoggerHandler()->getLogger()->debug('response', [$response->getBody()->getContents()]);
return $response;
}
@ -97,28 +96,4 @@ class Client
{
return LoggerHandler::getInstance();
}
/**
* @param string $loglevel
*
* @return callable
*/
protected function getLoggerMiddleware(string $loglevel = 'debug'): callable
{
return Middleware::log(
$this->getLoggerHandler()->getLogger(),
new MessageFormatter(MessageFormatter::DEBUG),
$loglevel
);
}
/**
* @return callable
*/
protected function getRetryMiddleware(): callable
{
return GuzzleRetryMiddleware::factory([
'max_retry_attempts' => 3
]);
}
}

Voir le fichier

@ -0,0 +1,20 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\LinkmobilityClient\Exceptions;
class ApiException extends LinkmobilityException
{
}

Voir le fichier

@ -31,15 +31,9 @@ class RecipientsList implements RecipientsListInterface, Iterator
*/
private $recipients = [];
/**
* @deprecated unused client parameter will remove
* @param Client|null $client
*/
public function __construct(Client $client = null)
public function __construct(Client $client)
{
if ($client) {
$this->setClient( $client );
}
$this->setClient($client);
}
/**
@ -119,7 +113,6 @@ class RecipientsList implements RecipientsListInterface, Iterator
}
/**
* @deprecated
* @return Client
*/
public function getClient(): Client
@ -128,7 +121,6 @@ class RecipientsList implements RecipientsListInterface, Iterator
}
/**
* @deprecated
* @param Client $client
*
* @return RecipientsList

Voir le fichier

@ -20,10 +20,6 @@ use D3\LinkmobilityClient\ValueObject\Recipient;
interface RecipientsListInterface
{
/**
* @deprecated unused client parameter will remove
* @param Client $client
*/
public function __construct(Client $client);
public function add(Recipient $recipient): RecipientsListInterface;
@ -31,6 +27,4 @@ interface RecipientsListInterface
public function clearRecipents(): RecipientsListInterface;
public function getRecipients(): array;
public function getRecipientsList(): array;
}

Voir le fichier

@ -16,7 +16,6 @@ declare(strict_types=1);
namespace D3\LinkmobilityClient\Request;
use Assert\Assert;
use Assert\InvalidArgumentException;
use D3\LinkmobilityClient\Client;
use D3\LinkmobilityClient\Exceptions\ExceptionMessages;
use D3\LinkmobilityClient\RecipientsList\RecipientsList;
@ -26,7 +25,9 @@ use D3\LinkmobilityClient\ValueObject\Recipient;
use D3\LinkmobilityClient\ValueObject\Sender;
use D3\LinkmobilityClient\ValueObject\SmsMessageAbstract;
use D3\LinkmobilityClient\ValueObject\SmsMessageInterface;
use D3\LinkmobilityClient\ValueObject\StringValueObject;
use GuzzleHttp\RequestOptions;
use InvalidArgumentException;
abstract class Request implements RequestInterface
{

Voir le fichier

@ -15,16 +15,15 @@ declare(strict_types=1);
namespace D3\LinkmobilityClient\Request;
use Assert\InvalidArgumentException;
use D3\LinkmobilityClient\Client;
use D3\LinkmobilityClient\RecipientsList\RecipientsListInterface;
use D3\LinkmobilityClient\ValueObject\SmsMessageInterface;
use InvalidArgumentException;
use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
use D3\LinkmobilityClient\Response\ResponseInterface as LMResponseInterface;
interface RequestInterface
{
// @codeCoverageIgnoreStart
public const METHOD_GET = 'GET';
public const METHOD_POST = 'POST';
public const METHOD_PUT = 'PUT';
@ -43,7 +42,6 @@ interface RequestInterface
public const SENDERADDRESSTYPE_INTERNATIONAL = 'international';
public const SENDERADDRESSTYPE_ALPHANUMERIC = 'alphanumeric';
public const SENDERADDRESSTYPE_SHORTCODE = 'shortcode';
// @codeCoverageIgnoreEnd
/**
* @param SmsMessageInterface $message

Voir le fichier

@ -16,10 +16,10 @@ declare(strict_types=1);
namespace D3\LinkmobilityClient\SMS;
use Assert\Assert;
use Assert\InvalidArgumentException;
use D3\LinkmobilityClient\Request\Request;
use D3\LinkmobilityClient\Url\Url;
use D3\LinkmobilityClient\ValueObject\SmsBinaryMessage;
use InvalidArgumentException;
class BinaryRequest extends Request implements SmsRequestInterface
{

Voir le fichier

@ -16,10 +16,10 @@ declare(strict_types=1);
namespace D3\LinkmobilityClient\SMS;
use Assert\Assert;
use Assert\InvalidArgumentException;
use D3\LinkmobilityClient\Request\Request;
use D3\LinkmobilityClient\Url\Url;
use D3\LinkmobilityClient\ValueObject\SmsTextMessage;
use InvalidArgumentException;
class TextRequest extends Request implements SmsRequestInterface
{

Voir le fichier

@ -16,7 +16,6 @@ declare(strict_types=1);
namespace D3\LinkmobilityClient\ValueObject;
use Assert\Assert;
use Assert\InvalidArgumentException;
use D3\LinkmobilityClient\Exceptions\ExceptionMessages;
use D3\LinkmobilityClient\Exceptions\RecipientException;
use libphonenumber\NumberParseException;
@ -45,7 +44,6 @@ class Recipient extends StringValueObject
*
* @throws NumberParseException
* @throws RecipientException
* @throws InvalidArgumentException
*/
public function __construct(string $number, string $iso2CountryCode)
{

Voir le fichier

@ -16,7 +16,6 @@ declare(strict_types=1);
namespace D3\LinkmobilityClient\ValueObject;
use Assert\Assert;
use Assert\InvalidArgumentException;
use D3\LinkmobilityClient\Exceptions\ExceptionMessages;
use D3\LinkmobilityClient\Exceptions\NoSenderDefinedException;
use D3\LinkmobilityClient\Exceptions\RecipientException;
@ -33,7 +32,6 @@ class Sender extends ValueObject
*
* @throws NumberParseException
* @throws RecipientException
* @throws InvalidArgumentException
*/
public function __construct(string $number = null, string $iso2CountryCode = null)
{

Voir le fichier

@ -15,7 +15,7 @@ declare(strict_types=1);
namespace D3\LinkmobilityClient\ValueObject;
use Assert\InvalidArgumentException;
use InvalidArgumentException;
class SmsTextMessage extends SmsMessageAbstract
{

Voir le fichier

@ -16,16 +16,11 @@ declare(strict_types=1);
namespace D3\LinkmobilityClient\ValueObject;
use Assert\Assert;
use Assert\InvalidArgumentException;
abstract class ValueObject
{
protected $value;
/**
* @param string $number
* @throws InvalidArgumentException
*/
public function __construct(string $number)
{
Assert::that($number)->notEmpty();