From 67291c19da5ecfc8fac1ac3402dd0c3de6df3ace Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 11 Jul 2022 15:06:18 +0200 Subject: [PATCH] add tests for some classes --- Tests/ClientTest.php | 5 +- Tests/RecipientsList/RecipientsListTest.php | 478 ++++++++++++++++++++ Tests/UrlTest.php | 2 +- Tests/ValueObject/RecipientTest.php | 164 +++++++ Tests/ValueObject/SenderTest.php | 159 +++++++ Tests/ValueObject/SmsBinaryMessageTest.php | 243 ++++++++++ Tests/ValueObject/SmsTextMessageTest.php | 115 +++++ composer.json | 2 +- src/Client.php | 4 +- src/RecipientsList/RecipientsList.php | 27 +- src/SMS/RequestFactory.php | 1 - src/ValueObject/Recipient.php | 10 +- src/ValueObject/Sender.php | 10 +- src/ValueObject/SmsBinaryMessage.php | 7 +- src/ValueObject/SmsMessageAbstract.php | 18 +- src/ValueObject/SmsMessageInterface.php | 2 +- src/ValueObject/SmsTextMessage.php | 3 +- src/ValueObject/StringValueObject.php | 2 +- 18 files changed, 1225 insertions(+), 27 deletions(-) create mode 100644 Tests/RecipientsList/RecipientsListTest.php create mode 100644 Tests/ValueObject/RecipientTest.php create mode 100644 Tests/ValueObject/SenderTest.php create mode 100644 Tests/ValueObject/SmsBinaryMessageTest.php create mode 100644 Tests/ValueObject/SmsTextMessageTest.php diff --git a/Tests/ClientTest.php b/Tests/ClientTest.php index a1b7be6..3cc8678 100644 --- a/Tests/ClientTest.php +++ b/Tests/ClientTest.php @@ -37,10 +37,9 @@ use ReflectionException; class ClientTest extends ApiTestCase { - public string $fixtureApiKey = 'fixtureApiKey'; + public $fixtureApiKey = 'fixtureApiKey'; /** @var Client */ - public Client $api; - public string $jsonFixture = 'json_content'; + public $api; /** * @return void diff --git a/Tests/RecipientsList/RecipientsListTest.php b/Tests/RecipientsList/RecipientsListTest.php new file mode 100644 index 0000000..a8021b5 --- /dev/null +++ b/Tests/RecipientsList/RecipientsListTest.php @@ -0,0 +1,478 @@ + + * @link http://www.oxidmodule.com + */ + +declare( strict_types = 1 ); + +namespace D3\LinkmobilityClient\Tests\RecipientsList; + +use D3\LinkmobilityClient\Client; +use D3\LinkmobilityClient\RecipientsList\RecipientsList; +use D3\LinkmobilityClient\Tests\ApiTestCase; +use D3\LinkmobilityClient\ValueObject\Recipient; +use libphonenumber\NumberParseException; +use libphonenumber\PhoneNumber; +use libphonenumber\PhoneNumberType; +use libphonenumber\PhoneNumberUtil; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\AbstractLogger; +use Psr\Log\LoggerInterface; +use ReflectionException; +use stdClass; + +class RecipientsListTest extends ApiTestCase +{ + /** @var RecipientsList */ + public $recipientsList; + + private $phoneNumberFixture = '01527565839'; + private $phoneCountryFixture = 'DE'; + + /** + * @return void + */ + public function setUp():void + { + parent::setUp(); + + /** @var Client|MockObject $clientMock */ + $clientMock = $this->getMockBuilder(Client::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->recipientsList = new RecipientsList($clientMock); + } + + /** + * @return void + */ + public function tearDown(): void + { + parent::tearDown(); + + unset($this->recipientsList); + } + + /** + * @test + * @return void + */ + public function testConstruct() + { + /** @var Client|MockObject $clientMock */ + $clientMock = $this->getMockBuilder(Client::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->recipientsList = new RecipientsList($clientMock); + + $this->assertSame( + $this->recipientsList->getClient(), + $clientMock + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function testGetPhoneNumberUtil() + { + $this->assertInstanceOf( + PhoneNumberUtil::class, + $this->callMethod( + $this->recipientsList, + 'getPhoneNumberUtil' + ) + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function testAddValidNumber() + { + /** @var PhoneNumberUtil|MockObject $phoneNumberUtilMock */ + $phoneNumberUtilMock = $this->getMockBuilder(PhoneNumberUtil::class) + ->onlyMethods(['parse', 'isValidNumber', 'getNumberType']) + ->disableOriginalConstructor() + ->getMock(); + $phoneNumberUtilMock->method('parse')->willReturn(new PhoneNumber()); + $phoneNumberUtilMock->method('isValidNumber')->willReturn(true); + $phoneNumberUtilMock->method('getNumberType')->willReturn(PhoneNumberType::MOBILE); + + /** @var Recipient|MockObject $recipientMock */ + $recipientMock = $this->getMockBuilder(Recipient::class) + ->onlyMethods(['get', 'getCountryCode']) + ->setConstructorArgs([$this->phoneNumberFixture, $this->phoneCountryFixture]) + ->getMock(); + $recipientMock->method('get')->willReturn($this->phoneNumberFixture); + $recipientMock->method('getCountryCode')->willReturn($this->phoneCountryFixture); + + /** @var RecipientsList|MockObject $recListMock */ + $recListMock = $this->getMockBuilder(RecipientsList::class) + ->onlyMethods(['getPhoneNumberUtil']) + ->setConstructorArgs([$this->recipientsList->getClient()]) + ->getMock(); + $recListMock->method('getPhoneNumberUtil')->willReturn($phoneNumberUtilMock); + + $this->recipientsList = $recListMock; + + $this->assertCount( + 0, + $this->callMethod($this->recipientsList, 'getRecipientsList') + ); + + $this->assertSame( + $this->recipientsList, + $this->callMethod( + $this->recipientsList, + 'add', + [$recipientMock] + ) + ); + + $this->assertCount( + 1, + $this->callMethod($this->recipientsList, 'getRecipientsList') + ); + } + + /** + * @test + * @throws ReflectionException + * @dataProvider addInvalidNumberDataProvider + */ + public function testAddInvalidNumber($unparsable, $invalidNumber, $invalidNumberType) + { + /** @var PhoneNumberUtil|MockObject $phoneNumberUtilMock */ + $phoneNumberUtilMock = $this->getMockBuilder(PhoneNumberUtil::class) + ->onlyMethods(['parse', 'isValidNumber', 'getNumberType']) + ->disableOriginalConstructor() + ->getMock(); + + if ($unparsable) { + $phoneNumberUtilMock->method( 'parse' )->willThrowException(new NumberParseException(0, 'message')); + } else { + $phoneNumberUtilMock->method( 'parse' )->willReturn( new PhoneNumber() ); + } + $phoneNumberUtilMock->method( 'isValidNumber' )->willReturn( !$invalidNumber ); + $phoneNumberUtilMock->method('getNumberType')->willReturn($invalidNumberType ? PhoneNumberType::FIXED_LINE : PhoneNumberType::MOBILE); + + /** @var Recipient|MockObject $recipientMock */ + $recipientMock = $this->getMockBuilder(Recipient::class) + ->onlyMethods(['get', 'getCountryCode']) + ->setConstructorArgs([$this->phoneNumberFixture, $this->phoneCountryFixture]) + ->getMock(); + $recipientMock->method('get')->willReturn($this->phoneNumberFixture); + $recipientMock->method('getCountryCode')->willReturn($this->phoneCountryFixture); + + /** @var LoggerInterface|MockObject $loggerMock */ + $loggerMock = $this->getMockBuilder(AbstractLogger::class) + ->onlyMethods(['info', 'log']) + ->getMock(); + $loggerMock->expects($this->atLeastOnce())->method('info')->willReturn(true); + + /** @var Client|MockObject $clientMock */ + $clientMock = $this->getMockBuilder(Client::class) + ->disableOriginalConstructor() + ->onlyMethods(['hasLogger', 'getLogger']) + ->getMock(); + $clientMock->method('hasLogger')->willReturn(true); + $clientMock->method('getLogger')->willReturn($loggerMock); + + /** @var RecipientsList|MockObject $recListMock */ + $recListMock = $this->getMockBuilder(RecipientsList::class) + ->onlyMethods(['getPhoneNumberUtil']) + ->setConstructorArgs([$clientMock]) + ->getMock(); + $recListMock->method('getPhoneNumberUtil')->willReturn($phoneNumberUtilMock); + + $this->recipientsList = $recListMock; + + $this->assertCount( + 0, + $this->callMethod($this->recipientsList, 'getRecipientsList') + ); + + $this->assertSame( + $this->recipientsList, + $this->callMethod( + $this->recipientsList, + 'add', + [$recipientMock] + ) + ); + + $this->assertCount( + 0, + $this->callMethod($this->recipientsList, 'getRecipientsList') + ); + } + + /** + * @return array[] + */ + public function addInvalidNumberDataProvider(): array + { + return [ + 'unparsable' => [true, false, false], + 'invalid number' => [false, true, false], + 'invalid number type' => [false, false, true], + ]; + } + + /** + * @test + * @throws ReflectionException + */ + public function testClearRecipents() + { + $this->addRecipientFixture(); + + $this->assertCount( + 2, + $this->callMethod($this->recipientsList, 'getRecipientsList') + ); + + $this->assertInstanceOf( + RecipientsList::class, + $this->callMethod( + $this->recipientsList, + 'clearRecipents' + ) + ); + + $this->assertCount( + 0, + $this->callMethod($this->recipientsList, 'getRecipientsList') + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function testGetRecipients() + { + $this->assertCount( + 0, + $this->callMethod( + $this->recipientsList, + 'getRecipients' + ) + ); + + $this->addRecipientFixture(); + + $this->assertSame( + [ + $this->phoneNumberFixture, + $this->phoneNumberFixture + ], + $this->callMethod( + $this->recipientsList, + 'getRecipients' + ) + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function testGetRecipientsList() + { + $this->assertCount( + 0, + $this->callMethod( + $this->recipientsList, + 'getRecipientsList' + ) + ); + + $this->addRecipientFixture(); + + $recipientsList = $this->callMethod( + $this->recipientsList, + 'getRecipientsList' + ); + + $this->assertCount( + 2, + $recipientsList + ); + $this->assertInstanceOf( + Recipient::class, + $recipientsList['fixture'] + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function testCurrentNextKeyRewind() + { + $list = $this->addRecipientFixture(); + + $current = $this->callMethod( + $this->recipientsList, + 'current' + ); + + $this->assertInstanceOf( + Recipient::class, + $current + ); + + $this->assertSame( + $list['fixture2'], + $this->callMethod( + $this->recipientsList, + 'next' + ) + ); + + $this->assertSame( + 'fixture2', + $this->callMethod( + $this->recipientsList, + 'key' + ) + ); + + $this->callMethod( + $this->recipientsList, + 'rewind' + ); + + $this->assertSame( + 'fixture', + $this->callMethod( + $this->recipientsList, + 'key' + ) + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function testValid() + { + $this->addRecipientFixture(); + + $this->assertTrue( + $this->callMethod( + $this->recipientsList, + 'valid' + ) + ); + + $this->setValue( + $this->recipientsList, + 'recipients', + [ + 'fixture' => new stdClass() + ] + ); + + $this->assertFalse( + $this->callMethod( + $this->recipientsList, + 'valid' + ) + ); + } + + /** + * @test + * @throws ReflectionException + */ + public function testSetGetClient() + { + /** @var Client|MockObject $clientMock */ + $clientMock = $this->getMockBuilder(Client::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + RecipientsList::class, + $this->callMethod( + $this->recipientsList, + 'setClient', + [$clientMock] + ) + ); + + $this->assertSame( + $clientMock, + $this->callMethod( + $this->recipientsList, + 'getClient' + ) + ); + } + + /** + * @return Recipient[]|MockObject[] + * @throws ReflectionException + */ + protected function addRecipientFixture(): array + { + /** @var Recipient|MockObject $recipientMock */ + $recipientMock = $this->getMockBuilder( Recipient::class ) + ->onlyMethods( [ + 'get', + 'getCountryCode' + ] ) + ->setConstructorArgs( [ + $this->phoneNumberFixture, + $this->phoneCountryFixture + ] ) + ->getMock(); + $recipientMock->method( 'get' )->willReturn( $this->phoneNumberFixture ); + $recipientMock->method( 'getCountryCode' )->willReturn( $this->phoneCountryFixture ); + + /** @var Recipient|MockObject $recipientMock2 */ + $recipientMock2 = $this->getMockBuilder( Recipient::class ) + ->onlyMethods( [ + 'get', + 'getCountryCode' + ] ) + ->setConstructorArgs( [ + $this->phoneNumberFixture, + $this->phoneCountryFixture + ] ) + ->getMock(); + $recipientMock2->method( 'get' )->willReturn( $this->phoneNumberFixture ); + $recipientMock2->method( 'getCountryCode' )->willReturn( $this->phoneCountryFixture ); + + $list = [ + 'fixture' => $recipientMock, + 'fixture2' => $recipientMock2 + ]; + + $this->setValue( + $this->recipientsList, + 'recipients', + $list + ); + + return $list; + } +} \ No newline at end of file diff --git a/Tests/UrlTest.php b/Tests/UrlTest.php index c08b710..0948d17 100644 --- a/Tests/UrlTest.php +++ b/Tests/UrlTest.php @@ -23,7 +23,7 @@ use ReflectionException; class UrlTest extends ApiTestCase { /** @var Url */ - public Url $url; + public $url; /** * @return void diff --git a/Tests/ValueObject/RecipientTest.php b/Tests/ValueObject/RecipientTest.php new file mode 100644 index 0000000..c47464f --- /dev/null +++ b/Tests/ValueObject/RecipientTest.php @@ -0,0 +1,164 @@ + + * @link http://www.oxidmodule.com + */ + +declare( strict_types = 1 ); + +namespace D3\LinkmobilityClient\Tests\ValueObject; + +use Assert\InvalidArgumentException; +use D3\LinkmobilityClient\Tests\ApiTestCase; +use D3\LinkmobilityClient\ValueObject\Recipient; +use libphonenumber\NumberParseException; +use libphonenumber\PhoneNumber; +use libphonenumber\PhoneNumberUtil; +use PHPUnit\Framework\MockObject\MockObject; +use ReflectionException; + +class RecipientTest extends ApiTestCase +{ + /** @var Recipient */ + public $recipient; + + private $phoneNumberFixture = '01527565839'; + private $phoneCountryFixture = 'DE'; + + /** + * @return void + * @throws NumberParseException + */ + public function setUp():void + { + parent::setUp(); + + $this->recipient = new Recipient($this->phoneNumberFixture, $this->phoneCountryFixture); + } + + /** + * @return void + */ + public function tearDown(): void + { + parent::tearDown(); + + unset($this->recipient); + } + + /** + * @test + * @return void + * @throws NumberParseException + * @throws ReflectionException + */ + public function testConstructValid() + { + /** @var PhoneNumberUtil|MockObject $phoneNumberUtilMock */ + $phoneNumberUtilMock = $this->getMockBuilder(PhoneNumberUtil::class) + ->onlyMethods(['parse', 'format']) + ->disableOriginalConstructor() + ->getMock(); + $phoneNumberUtilMock->method('parse')->willReturn(new PhoneNumber()); + $phoneNumberUtilMock->method('format')->willReturn('+491527565839'); + + /** @var Recipient|MockObject $recipientMock */ + $recipientMock = $this->getMockBuilder(Recipient::class) + ->onlyMethods(['getPhoneNumberUtil']) + ->disableOriginalConstructor() + ->getMock(); + $recipientMock->method('getPhoneNumberUtil')->willReturn($phoneNumberUtilMock); + $recipientMock->__construct($this->phoneNumberFixture, $this->phoneCountryFixture); + + $this->assertSame( + '491527565839', + $this->callMethod( + $recipientMock, + 'get' + ) + ); + + $this->assertSame( + $this->phoneCountryFixture, + $this->callMethod( + $recipientMock, + 'getCountryCode' + ) + ); + } + + /** + * @test + * + * @param $number + * @param $country + * @param $validNumber + * @param $expectedException + * + * @return void + * @throws NumberParseException + * @dataProvider constructInvalidDataProvider + */ + public function testConstructInvalid($number, $country, $validNumber, $expectedException) + { + /** @var PhoneNumberUtil|MockObject $phoneNumberUtilMock */ + $phoneNumberUtilMock = $this->getMockBuilder(PhoneNumberUtil::class) + ->onlyMethods(['parse', 'format', 'isValidNumber']) + ->disableOriginalConstructor() + ->getMock(); + if ($number === 'abc') { + $phoneNumberUtilMock->method( 'parse' )->willThrowException(new NumberParseException(0, 'message')); + } else { + $phoneNumberUtilMock->method( 'parse' )->willReturn( new PhoneNumber() ); + } + $phoneNumberUtilMock->method('format')->willReturn($number); + $phoneNumberUtilMock->method('isValidNumber')->willReturn($validNumber); + + /** @var Recipient|MockObject $recipientMock */ + $recipientMock = $this->getMockBuilder(Recipient::class) + ->onlyMethods(['getPhoneNumberUtil']) + ->disableOriginalConstructor() + ->getMock(); + $recipientMock->method('getPhoneNumberUtil')->willReturn($phoneNumberUtilMock); + + $this->expectException($expectedException); + $recipientMock->__construct($number, $country); + } + + /** + * @return string[][] + */ + public function constructInvalidDataProvider(): array + { + return [ + 'empty number' => ['', 'DE', true, InvalidArgumentException::class], + 'invalid country code' => [$this->phoneNumberFixture, 'DEX', true, InvalidArgumentException::class], + 'unparsable' => ['abc', 'DE', true, NumberParseException::class], + 'invalid number' => ['abc', 'DE', false, NumberParseException::class] + ]; + } + + /** + * @test + * @throws ReflectionException + */ + public function testGetPhoneNumberUtil() + { + $this->assertInstanceOf( + PhoneNumberUtil::class, + $this->callMethod( + $this->recipient, + 'getPhoneNumberUtil' + ) + ); + } +} \ No newline at end of file diff --git a/Tests/ValueObject/SenderTest.php b/Tests/ValueObject/SenderTest.php new file mode 100644 index 0000000..5cd0941 --- /dev/null +++ b/Tests/ValueObject/SenderTest.php @@ -0,0 +1,159 @@ + + * @link http://www.oxidmodule.com + */ + +declare( strict_types = 1 ); + +namespace D3\LinkmobilityClient\Tests\ValueObject; + +use Assert\InvalidArgumentException; +use D3\LinkmobilityClient\Exceptions\RecipientException; +use D3\LinkmobilityClient\Tests\ApiTestCase; +use D3\LinkmobilityClient\ValueObject\Sender; +use libphonenumber\NumberParseException; +use libphonenumber\PhoneNumber; +use libphonenumber\PhoneNumberUtil; +use PHPUnit\Framework\MockObject\MockObject; +use ReflectionException; + +class SenderTest extends ApiTestCase +{ + /** @var Sender */ + public $sender; + + private $phoneNumberFixture = '015792300219'; + private $phoneCountryFixture = 'DE'; + + /** + * @return void + * @throws NumberParseException + * @throws RecipientException + */ + public function setUp():void + { + parent::setUp(); + + $this->sender = new Sender( $this->phoneNumberFixture, $this->phoneCountryFixture); + } + + /** + * @return void + */ + public function tearDown(): void + { + parent::tearDown(); + + unset($this->sender); + } + + /** + * @test + * @return void + * @throws NumberParseException + * @throws RecipientException + * @throws ReflectionException + */ + public function testConstructValid() + { + /** @var PhoneNumberUtil|MockObject $phoneNumberUtilMock */ + $phoneNumberUtilMock = $this->getMockBuilder(PhoneNumberUtil::class) + ->onlyMethods(['parse', 'format', 'isValidNumber']) + ->disableOriginalConstructor() + ->getMock(); + $phoneNumberUtilMock->method('parse')->willReturn(new PhoneNumber()); + $phoneNumberUtilMock->method('format')->willReturn('4915792300219'); + $phoneNumberUtilMock->method('isValidNumber')->willReturn(true); + + /** @var Sender|MockObject $senderMock */ + $senderMock = $this->getMockBuilder(Sender::class) + ->onlyMethods(['getPhoneNumberUtil']) + ->disableOriginalConstructor() + ->getMock(); + $senderMock->method('getPhoneNumberUtil')->willReturn($phoneNumberUtilMock); + $senderMock->__construct($this->phoneNumberFixture, $this->phoneCountryFixture); + + $this->assertSame( + '4915792300219', + $this->callMethod( + $senderMock, + 'get' + ) + ); + } + + /** + * @test + * @param $number + * @param $country + * @param $validNumber + * @param $expectedException + * + * @throws NumberParseException + * @throws RecipientException + * @dataProvider constructInvalidDataProvider + */ + public function testConstructInvalid($number, $country, $validNumber, $expectedException) + { + /** @var PhoneNumberUtil|MockObject $phoneNumberUtilMock */ + $phoneNumberUtilMock = $this->getMockBuilder(PhoneNumberUtil::class) + ->onlyMethods(['parse', 'format', 'isValidNumber']) + ->disableOriginalConstructor() + ->getMock(); + if ($number === 'abc') { + $phoneNumberUtilMock->method( 'parse' )->willThrowException(new NumberParseException(0, 'message')); + } else { + $phoneNumberUtilMock->method( 'parse' )->willReturn( new PhoneNumber() ); + } + $phoneNumberUtilMock->method('format')->willReturn($number); + $phoneNumberUtilMock->method('isValidNumber')->willReturn($validNumber); + + /** @var Sender|MockObject $senderMock */ + $senderMock = $this->getMockBuilder(Sender::class) + ->onlyMethods(['getPhoneNumberUtil']) + ->disableOriginalConstructor() + ->getMock(); + $senderMock->method('getPhoneNumberUtil')->willReturn($phoneNumberUtilMock); + + $this->expectException($expectedException); + $senderMock->__construct($number, $country); + } + + /** + * @return string[][] + */ + public function constructInvalidDataProvider(): array + { + return [ + 'empty number' => ['', 'DE', true, InvalidArgumentException::class], + 'invalid country code' => [$this->phoneNumberFixture, 'DEX', true, InvalidArgumentException::class], + 'unparsable' => ['abc', 'DE', true, NumberParseException::class], + 'invalid number' => ['abc', 'DE', false, NumberParseException::class] + ]; + } + + /** + * @test + * @throws ReflectionException + */ + public function testGetPhoneNumberUtil() + { + $this->assertInstanceOf( + PhoneNumberUtil::class, + $this->callMethod( + $this->sender, + 'getPhoneNumberUtil' + ) + ); + } +} \ No newline at end of file diff --git a/Tests/ValueObject/SmsBinaryMessageTest.php b/Tests/ValueObject/SmsBinaryMessageTest.php new file mode 100644 index 0000000..13fd6ed --- /dev/null +++ b/Tests/ValueObject/SmsBinaryMessageTest.php @@ -0,0 +1,243 @@ + + * @link http://www.oxidmodule.com + */ + +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\SmsLength; +use PHPUnit\Framework\MockObject\MockObject; +use ReflectionException; + +class SmsBinaryMessageTest extends ApiTestCase +{ + /** @var SmsBinaryMessage */ + public $message; + + private $messageFixture = "testMessage"; + + /** + * @return void + */ + public function setUp():void + { + parent::setUp(); + + $this->message = new SmsBinaryMessage( $this->messageFixture); + } + + /** + * @return void + */ + public function tearDown(): void + { + parent::tearDown(); + + unset($this->message); + } + + /** + * @test + * @return void + * @throws ReflectionException + */ + public function testConstructValid() + { + /** @var SmsLength|MockObject $smsLengthMock */ + $smsLengthMock = $this->getMockBuilder(SmsLength::class) + ->disableOriginalConstructor() + ->onlyMethods(['validate']) + ->getMock(); + $smsLengthMock->expects($this->atLeastOnce())->method('validate')->willReturn(true); + + /** @var SmsBinaryMessage|MockObject $message */ + $message = $this->getMockBuilder(SmsBinaryMessage::class) + ->onlyMethods(['getSmsLength']) + ->disableOriginalConstructor() + ->getMock(); + $message->method('getSmsLength')->willReturn($smsLengthMock); + $message->__construct($this->messageFixture); + + $this->assertSame( + $this->messageFixture, + $this->callMethod( + $message, + 'get' + ) + ); + } + + /** + * @test + * + * @param $binaryMessage + * @param $valid + * @param $expectedException + * + * @throws ReflectionException + * @dataProvider constructInvalidDataProvider + */ + public function testConstructInvalid($binaryMessage, $valid, $expectedException) + { + /** @var SmsLength|MockObject $smsLengthMock */ + $smsLengthMock = $this->getMockBuilder(SmsLength::class) + ->disableOriginalConstructor() + ->onlyMethods(['validate']) + ->getMock(); + if ($valid) { + $smsLengthMock->expects( $this->never() )->method( 'validate' )->willReturn( true ); + } else { + $smsLengthMock->expects( $this->atLeastOnce() )->method( 'validate' )->willThrowException(new \Phlib\SmsLength\Exception\InvalidArgumentException()); + } + + /** @var SmsBinaryMessage|MockObject $message */ + $message = $this->getMockBuilder(SmsBinaryMessage::class) + ->onlyMethods(['getSmsLength']) + ->disableOriginalConstructor() + ->getMock(); + $message->method('getSmsLength')->willReturn($smsLengthMock); + + $this->expectException($expectedException); + $message->__construct($binaryMessage); + + $this->assertSame( + $message, + $this->callMethod( + $message, + 'get' + ) + ); + } + + /** + * @return string[][] + */ + public function constructInvalidDataProvider(): array + { + return [ + 'empty message' => ['', true, InvalidArgumentException::class], + 'invalid sms message' => ['abc', false, \Phlib\SmsLength\Exception\InvalidArgumentException::class] + ]; + } + + /** + * @test + * @throws ReflectionException + */ + public function testGetSmsLengthInstance() + { + $this->assertInstanceOf( + SmsLength::class, + $this->callMethod( + $this->message, + 'getSmsLength' + ) + ); + } + + /** + * @throws ReflectionException + */ + public function testGetChunkCount() + { + $expected = 2; + + /** @var SmsLength|MockObject $smsLengthMock */ + $smsLengthMock = $this->getMockBuilder(SmsLength::class) + ->onlyMethods(['getMessageCount', 'validate']) + ->disableOriginalConstructor() + ->getMock(); + $smsLengthMock->expects($this->once())->method('getMessageCount')->willReturn($expected); + $smsLengthMock->method('validate')->willReturn(true); + + /** @var SmsBinaryMessage|MockObject $message */ + $message = $this->getMockBuilder(SmsBinaryMessage::class) + ->onlyMethods(['getSmsLength']) + ->disableOriginalConstructor() + ->getMock(); + $message->method('getSmsLength')->willReturn($smsLengthMock); + + $this->assertSame( + $expected, + $this->callMethod( + $message, + 'chunkCount' + ) + ); + } + + /** + * @throws ReflectionException + */ + public function testGetSize() + { + $expected = 55; + + /** @var SmsLength|MockObject $smsLengthMock */ + $smsLengthMock = $this->getMockBuilder(SmsLength::class) + ->onlyMethods(['getSize', 'validate']) + ->disableOriginalConstructor() + ->getMock(); + $smsLengthMock->expects($this->once())->method('getSize')->willReturn($expected); + $smsLengthMock->method('validate')->willReturn(true); + + /** @var SmsBinaryMessage|MockObject $message */ + $message = $this->getMockBuilder(SmsBinaryMessage::class) + ->onlyMethods(['getSmsLength']) + ->disableOriginalConstructor() + ->getMock(); + $message->method('getSmsLength')->willReturn($smsLengthMock); + + $this->assertSame( + $expected, + $this->callMethod( + $message, + 'length' + ) + ); + } + + /** + * @throws ReflectionException + */ + public function testGetMessageContent() + { + /** @var SmsLength|MockObject $smsLengthMock */ + $smsLengthMock = $this->getMockBuilder(SmsLength::class) + ->onlyMethods(['validate']) + ->disableOriginalConstructor() + ->getMock(); + $smsLengthMock->method('validate')->willReturn(true); + + /** @var SmsBinaryMessage|MockObject $message */ + $message = $this->getMockBuilder(SmsBinaryMessage::class) + ->onlyMethods(['getSmsLength']) + ->disableOriginalConstructor() + ->getMock(); + $message->method('getSmsLength')->willReturn($smsLengthMock); + $message->__construct($this->messageFixture); + + $this->assertSame( + ['dGVzdE1lc3NhZ2U='], // binary content + $this->callMethod( + $message, + 'getMessageContent' + ) + ); + } +} \ No newline at end of file diff --git a/Tests/ValueObject/SmsTextMessageTest.php b/Tests/ValueObject/SmsTextMessageTest.php new file mode 100644 index 0000000..59eb580 --- /dev/null +++ b/Tests/ValueObject/SmsTextMessageTest.php @@ -0,0 +1,115 @@ + + * @link http://www.oxidmodule.com + */ + +declare( strict_types = 1 ); + +namespace D3\LinkmobilityClient\Tests\ValueObject; + +use D3\LinkmobilityClient\ValueObject\SmsTextMessage; +use Phlib\SmsLength\Exception\InvalidArgumentException; +use Phlib\SmsLength\SmsLength; +use PHPUnit\Framework\MockObject\MockObject; +use ReflectionException; + +class SmsTextMessageTest extends SmsBinaryMessageTest +{ + /** @var SmsTextMessage */ + public $message; + + private $messageFixture = "testMessage"; + + /** + * @return void + */ + public function setUp():void + { + parent::setUp(); + + $this->message = new SmsTextMessage( $this->messageFixture); + } + + /** + * @test + * @return void + * @throws ReflectionException + */ + public function testConstructValid() + { + /** @var SmsLength|MockObject $smsLengthMock */ + $smsLengthMock = $this->getMockBuilder(SmsLength::class) + ->disableOriginalConstructor() + ->onlyMethods(['validate']) + ->getMock(); + $smsLengthMock->expects($this->atLeastOnce())->method('validate')->willReturn(true); + + /** @var SmsTextMessage|MockObject $message */ + $message = $this->getMockBuilder(SmsTextMessage::class) + ->onlyMethods(['getSmsLength']) + ->disableOriginalConstructor() + ->getMock(); + $message->method('getSmsLength')->willReturn($smsLengthMock); + $message->__construct($this->messageFixture); + + $this->assertSame( + $this->messageFixture, + $this->callMethod( + $message, + 'get' + ) + ); + } + + /** + * @test + * + * @param $binaryMessage + * @param $valid + * @param $expectedException + * + * @throws ReflectionException + * @dataProvider constructInvalidDataProvider + */ + public function testConstructInvalid($binaryMessage, $valid, $expectedException) + { + /** @var SmsLength|MockObject $smsLengthMock */ + $smsLengthMock = $this->getMockBuilder(SmsLength::class) + ->disableOriginalConstructor() + ->onlyMethods(['validate']) + ->getMock(); + if ($valid) { + $smsLengthMock->expects( $this->never() )->method( 'validate' )->willReturn( true ); + } else { + $smsLengthMock->expects( $this->atLeastOnce() )->method( 'validate' )->willThrowException(new InvalidArgumentException()); + } + + /** @var SmsTextMessage|MockObject $message */ + $message = $this->getMockBuilder(SmsTextMessage::class) + ->onlyMethods(['getSmsLength']) + ->disableOriginalConstructor() + ->getMock(); + $message->method('getSmsLength')->willReturn($smsLengthMock); + + $this->expectException($expectedException); + $message->__construct($binaryMessage); + + $this->assertSame( + $message, + $this->callMethod( + $message, + 'get' + ) + ); + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index 9131273..ef89d2b 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "ext-json": "*" }, "require-dev": { - "php": "^7.2", + "php": "^7.2", "phpunit/phpunit" : "^8.0", "friendsofphp/php-cs-fixer": "^2.0" }, diff --git a/src/Client.php b/src/Client.php index ac57166..31ee96e 100644 --- a/src/Client.php +++ b/src/Client.php @@ -114,9 +114,9 @@ class Client } /** - * @return LoggerInterface + * @return LoggerInterface|null */ - public function getLogger(): ?LoggerInterface + public function getLogger() { return $this->hasLogger() ? $this->logger : null; } diff --git a/src/RecipientsList/RecipientsList.php b/src/RecipientsList/RecipientsList.php index c831181..7030b00 100644 --- a/src/RecipientsList/RecipientsList.php +++ b/src/RecipientsList/RecipientsList.php @@ -43,9 +43,22 @@ class RecipientsList implements RecipientsListInterface, Iterator $this->setClient($client); } + /** + * @return PhoneNumberUtil + */ + protected function getPhoneNumberUtil(): PhoneNumberUtil + { + return PhoneNumberUtil::getInstance(); + } + + /** + * @param Recipient $recipient + * + * @return RecipientsListInterface + */ public function add(Recipient $recipient) : RecipientsListInterface { - $phoneUtil = PhoneNumberUtil::getInstance(); + $phoneUtil = $this->getPhoneNumberUtil(); try { $phoneNumber = $phoneUtil->parse( $recipient->get(), $recipient->getCountryCode() ); @@ -64,6 +77,7 @@ class RecipientsList implements RecipientsListInterface, Iterator } $this->recipients[ md5( serialize( $recipient ) ) ] = $recipient; + } catch (NumberParseException $e) { if ($this->getClient()->hasLogger()) { $this->getClient()->getLogger()->info($e->getMessage()); @@ -77,6 +91,9 @@ class RecipientsList implements RecipientsListInterface, Iterator return $this; } + /** + * @return RecipientsListInterface + */ public function clearRecipents() : RecipientsListInterface { $this->recipients = []; @@ -127,7 +144,7 @@ class RecipientsList implements RecipientsListInterface, Iterator public function rewind() { - return reset($this->recipients); + reset($this->recipients); } public function valid(): bool @@ -145,9 +162,13 @@ class RecipientsList implements RecipientsListInterface, Iterator /** * @param Client $client + * + * @return RecipientsList */ - public function setClient( Client $client ) + public function setClient( Client $client ): RecipientsList { $this->client = $client; + + return $this; } } \ No newline at end of file diff --git a/src/SMS/RequestFactory.php b/src/SMS/RequestFactory.php index 4778ee5..d6d63d8 100644 --- a/src/SMS/RequestFactory.php +++ b/src/SMS/RequestFactory.php @@ -19,7 +19,6 @@ namespace D3\LinkmobilityClient\SMS; use D3\LinkmobilityClient\Client; use D3\LinkmobilityClient\ValueObject\SmsBinaryMessage; -use D3\LinkmobilityClient\ValueObject\SmsMessageInterface; use D3\LinkmobilityClient\ValueObject\SmsTextMessage; use Phlib\SmsLength\SmsLength; diff --git a/src/ValueObject/Recipient.php b/src/ValueObject/Recipient.php index d6cc086..2139dd6 100644 --- a/src/ValueObject/Recipient.php +++ b/src/ValueObject/Recipient.php @@ -26,7 +26,7 @@ class Recipient extends StringValueObject { Assert::that($iso2CountryCode)->string()->length(2); - $phoneUtil = PhoneNumberUtil::getInstance(); + $phoneUtil = $this->getPhoneNumberUtil(); $phoneNumber = $phoneUtil->parse($number, strtoupper($iso2CountryCode)); $number = ltrim($phoneUtil->format($phoneNumber, PhoneNumberFormat::E164), '+'); @@ -35,6 +35,14 @@ class Recipient extends StringValueObject $this->countryCode = $iso2CountryCode; } + /** + * @return PhoneNumberUtil + */ + protected function getPhoneNumberUtil(): PhoneNumberUtil + { + return PhoneNumberUtil::getInstance(); + } + /** * @return string */ diff --git a/src/ValueObject/Sender.php b/src/ValueObject/Sender.php index c835e9d..949f08f 100644 --- a/src/ValueObject/Sender.php +++ b/src/ValueObject/Sender.php @@ -24,7 +24,7 @@ class Sender extends StringValueObject { Assert::that($iso2CountryCode)->string()->length(2); - $phoneUtil = PhoneNumberUtil::getInstance(); + $phoneUtil = $this->getPhoneNumberUtil(); $phoneNumber = $phoneUtil->parse( $number, strtoupper($iso2CountryCode) ); $number = $phoneUtil->format( $phoneNumber, PhoneNumberFormat::E164 ); @@ -35,4 +35,12 @@ class Sender extends StringValueObject parent::__construct( $number); } + + /** + * @return PhoneNumberUtil + */ + protected function getPhoneNumberUtil(): PhoneNumberUtil + { + return PhoneNumberUtil::getInstance(); + } } diff --git a/src/ValueObject/SmsBinaryMessage.php b/src/ValueObject/SmsBinaryMessage.php index 84e502c..8f84db6 100644 --- a/src/ValueObject/SmsBinaryMessage.php +++ b/src/ValueObject/SmsBinaryMessage.php @@ -15,17 +15,16 @@ class SmsBinaryMessage extends SmsMessageAbstract { parent::__construct( $message); - $smsLength = new SmsLength($this->value); - $smsLength->validate(); + $this->getSmsLength()->validate(); } /** - * @return array|false|string + * @return array|false */ public function getMessageContent() { return str_split( - base64_encode($this->value), + base64_encode($this->get()), SmsLength::MAXIMUM_CHARACTERS_UCS2_SINGLE ); } diff --git a/src/ValueObject/SmsMessageAbstract.php b/src/ValueObject/SmsMessageAbstract.php index baea32a..a67e7c2 100644 --- a/src/ValueObject/SmsMessageAbstract.php +++ b/src/ValueObject/SmsMessageAbstract.php @@ -8,13 +8,20 @@ use Phlib\SmsLength\SmsLength; abstract class SmsMessageAbstract extends StringValueObject implements SmsMessageInterface { + /** + * @return SmsLength + */ + public function getSmsLength(): SmsLength + { + return new SmsLength($this->get()); + } + /** * @return int */ public function chunkCount() : int { - $smsLength = new SmsLength($this->value); - return $smsLength->getMessageCount(); + return $this->getSmsLength()->getMessageCount(); } /** @@ -22,12 +29,11 @@ abstract class SmsMessageAbstract extends StringValueObject implements SmsMessag */ public function length() : int { - $smsLength = new SmsLength($this->value); - return $smsLength->getSize(); + return $this->getSmsLength()->getSize(); } - public function getMessageContent() : string + public function getMessageContent() { - return (string) $this->value; + return $this->get(); } } diff --git a/src/ValueObject/SmsMessageInterface.php b/src/ValueObject/SmsMessageInterface.php index f5e4a23..34e927a 100644 --- a/src/ValueObject/SmsMessageInterface.php +++ b/src/ValueObject/SmsMessageInterface.php @@ -21,5 +21,5 @@ interface SmsMessageInterface public function length() : int; - public function getMessageContent() : string; + public function getMessageContent(); } \ No newline at end of file diff --git a/src/ValueObject/SmsTextMessage.php b/src/ValueObject/SmsTextMessage.php index ca86b8b..a0368db 100644 --- a/src/ValueObject/SmsTextMessage.php +++ b/src/ValueObject/SmsTextMessage.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace D3\LinkmobilityClient\ValueObject; use InvalidArgumentException; -use Phlib\SmsLength\SmsLength; class SmsTextMessage extends SmsMessageAbstract { @@ -17,7 +16,7 @@ class SmsTextMessage extends SmsMessageAbstract { parent::__construct( $message); - $smsLength = new SmsLength($this->value); + $smsLength = $this->getSmsLength(); $smsLength->validate(); } } diff --git a/src/ValueObject/StringValueObject.php b/src/ValueObject/StringValueObject.php index 0dc9611..b0e703f 100644 --- a/src/ValueObject/StringValueObject.php +++ b/src/ValueObject/StringValueObject.php @@ -20,7 +20,7 @@ abstract class StringValueObject extends ValueObject return $this->get(); } - public function get() : string + public function get(): string { return $this->value; }