From 77ba3538cfb320a04a09af7f553abaabb8ca2cbf Mon Sep 17 00:00:00 2001 From: Glenn Jacobs Date: Tue, 23 Jun 2015 17:04:45 +0100 Subject: [PATCH 01/25] Adding status codes to PHP exceptions --- src/Service/Verify.php | 6 +++--- src/Service/VerifyCheck.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Service/Verify.php b/src/Service/Verify.php index f7eeec1..05bba5a 100644 --- a/src/Service/Verify.php +++ b/src/Service/Verify.php @@ -77,15 +77,15 @@ protected function validateResponse(array $response) } if (!empty($response['error_text'])) { - throw new Exception('Unable to verify number: ' . $response['error_text'] . ' - status ' . $response['status']); + throw new Exception('Unable to verify number: ' . $response['error_text'] . ' - status ' . $response['status'], $response['status']); } if ($response['status'] > 0) { - throw new Exception('Unable to verify number: status ' . $response['status']); + throw new Exception('Unable to verify number: status ' . $response['status'], $response['status']); } if (!isset($response['request_id'])) { - throw new Exception('request_id property expected'); + throw new Exception('request_id property expected', $response['status']); } return true; diff --git a/src/Service/VerifyCheck.php b/src/Service/VerifyCheck.php index faf3574..2353491 100644 --- a/src/Service/VerifyCheck.php +++ b/src/Service/VerifyCheck.php @@ -55,11 +55,11 @@ protected function validateResponse(array $response) } if (!empty($response['error_text'])) { - throw new Exception('Unable to verify number: ' . $response['error_text'] . ' - status ' . $response['status']); + throw new Exception('Unable to verify number: ' . $response['error_text'] . ' - status ' . $response['status'], $response['status']); } if ($response['status'] > 0) { - throw new Exception('Unable to verify number: status ' . $response['status']); + throw new Exception('Unable to verify number: status ' . $response['status'], $response['status']); } return true; From 0005043289b454d93c7985335f95205f5bcbfab0 Mon Sep 17 00:00:00 2001 From: thelaurence Date: Mon, 10 Aug 2015 16:48:57 -0600 Subject: [PATCH 02/25] Adapted Message.php for Nexmo's keyword marketing --- src/Service/MarketingMessage | 83 ++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/Service/MarketingMessage diff --git a/src/Service/MarketingMessage b/src/Service/MarketingMessage new file mode 100644 index 0000000..c951db6 --- /dev/null +++ b/src/Service/MarketingMessage @@ -0,0 +1,83 @@ +exec([ + 'from' => $from, + 'keyword' => $keyword, + 'to' => $to, + 'text' => $text + ]); + } + + protected function validateResponse(array $json) + { + if (!isset($json['message-count'])) { + throw new Exception('message-count property expected'); + } + + if (!isset($json['messages'])) { + throw new Exception('messages property expected'); + } + + foreach ($json['messages'] as $message) { + if (!isset($message['status'])) { + throw new Exception('status property expected'); + } + + if (!empty($message["error-text"])) { + throw new Exception("Unable to send sms message: " . $message["error-text"] . ' - status ' . $message['status']); + } + + if ($message['status'] > 0) { + throw new Exception("Unable to send sms message: status " . $message['status']); + } + } + + return true; + } +} From d549f5d03f490dc71e4c105af2f993e6be26c3bc Mon Sep 17 00:00:00 2001 From: thelaurence Date: Tue, 11 Aug 2015 15:50:30 -0600 Subject: [PATCH 03/25] Create MarketingMessageTest.php --- tests/Service/MarketingMessageTest.php | 89 ++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 tests/Service/MarketingMessageTest.php diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php new file mode 100644 index 0000000..45bcecb --- /dev/null +++ b/tests/Service/MarketingMessageTest.php @@ -0,0 +1,89 @@ +service = new MarketingMessageMock(); + $this->service->setClient($this->guzzle()); + } + public function testInvoke() + { + $this->service->invoke(62687, 'test-keyword', 5005551111, 'test message'); + $this->assertSame($this->service->executedParams, [ + 'from' => 62687, + 'keyword' => 'test-keyword', + 'to' => 5005551111, + 'text' => 'test message' + ]); + } + public function testGetEndpoint() + { + $this->assertEquals($this->service->getEndpoint(), 'sc/us/marketing/json'); + } + public function testFromParameterRequired() + { + $this->setExpectedException('\Nexmo\Exception', '$from parameter cannot be blank'); + $this->service->invoke(); + } + public function testKeywordParameterRequired() + { + $this->setExpectedException('\Nexmo\Exception', '$keyword parameter cannot be blank'); + $this->service->invoke(62687); + } + public function testToParameterRequired() + { + $this->setExpectedException('\Nexmo\Exception', '$to parameter cannot be blank'); + $this->service->invoke(62687, 'test-keyword'); + } + public function testTextParameterRequired() + { + $this->setExpectedException('\Nexmo\Exception', '$text parameter cannot be blank'); + $this->service->invoke(62687, 'test-keyword', 5005551111); + } + public function testValidateResponseMessageCountProperty() + { + $this->setExpectedException('\Nexmo\Exception', 'message-count property expected'); + $this->service->testValidateResponse([]); + } + public function testValidateResponseMessagesProperty() + { + $this->setExpectedException('\Nexmo\Exception', 'messages property expected'); + $this->service->testValidateResponse(['message-count' => 1]); + } + public function testValidateResponseStatusProperty() + { + $this->setExpectedException('\Nexmo\Exception', 'status property expected'); + $this->service->testValidateResponse(['message-count' => 1, 'messages' => ['error']]); + } + public function testValidateResponseStatusNotZero() + { + $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: status 1'); + $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 1]]]); + } + public function testValidateResponseErrorText() + { + $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: error - status 2'); + $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['error-text' => 'error', 'status' => 2]]]); + } + public function testValidateResponseSuccess() + { + $this->assertTrue($this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 0]]])); + } +} +class MarketingMessageMock extends MarketingMessage +{ + use TestServiceTrait; +} From c13c3112fd6734842e9d2381ac9beb613d500185 Mon Sep 17 00:00:00 2001 From: thelaurence Date: Tue, 11 Aug 2015 15:51:38 -0600 Subject: [PATCH 04/25] Update MarketingMessageTest.php --- tests/Service/MarketingMessageTest.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php index 45bcecb..fefe46b 100644 --- a/tests/Service/MarketingMessageTest.php +++ b/tests/Service/MarketingMessageTest.php @@ -1,10 +1,6 @@ Date: Tue, 11 Aug 2015 16:00:55 -0600 Subject: [PATCH 05/25] Update MarketingMessageTest.php --- tests/Service/MarketingMessageTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php index fefe46b..45bcecb 100644 --- a/tests/Service/MarketingMessageTest.php +++ b/tests/Service/MarketingMessageTest.php @@ -1,6 +1,10 @@ Date: Tue, 11 Aug 2015 16:08:52 -0600 Subject: [PATCH 06/25] Update MarketingMessageTest.php --- tests/Service/MarketingMessageTest.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php index 45bcecb..fefe46b 100644 --- a/tests/Service/MarketingMessageTest.php +++ b/tests/Service/MarketingMessageTest.php @@ -1,10 +1,6 @@ Date: Tue, 11 Aug 2015 16:22:34 -0600 Subject: [PATCH 07/25] empty MarketingMessageTest.php --- tests/Service/MarketingMessageTest.php | 84 -------------------------- 1 file changed, 84 deletions(-) diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php index fefe46b..b3d9bbc 100644 --- a/tests/Service/MarketingMessageTest.php +++ b/tests/Service/MarketingMessageTest.php @@ -1,85 +1 @@ service = new MarketingMessageMock(); - $this->service->setClient($this->guzzle()); - } - public function testInvoke() - { - $this->service->invoke(62687, 'test-keyword', 5005551111, 'test message'); - $this->assertSame($this->service->executedParams, [ - 'from' => 62687, - 'keyword' => 'test-keyword', - 'to' => 5005551111, - 'text' => 'test message' - ]); - } - public function testGetEndpoint() - { - $this->assertEquals($this->service->getEndpoint(), 'sc/us/marketing/json'); - } - public function testFromParameterRequired() - { - $this->setExpectedException('\Nexmo\Exception', '$from parameter cannot be blank'); - $this->service->invoke(); - } - public function testKeywordParameterRequired() - { - $this->setExpectedException('\Nexmo\Exception', '$keyword parameter cannot be blank'); - $this->service->invoke(62687); - } - public function testToParameterRequired() - { - $this->setExpectedException('\Nexmo\Exception', '$to parameter cannot be blank'); - $this->service->invoke(62687, 'test-keyword'); - } - public function testTextParameterRequired() - { - $this->setExpectedException('\Nexmo\Exception', '$text parameter cannot be blank'); - $this->service->invoke(62687, 'test-keyword', 5005551111); - } - public function testValidateResponseMessageCountProperty() - { - $this->setExpectedException('\Nexmo\Exception', 'message-count property expected'); - $this->service->testValidateResponse([]); - } - public function testValidateResponseMessagesProperty() - { - $this->setExpectedException('\Nexmo\Exception', 'messages property expected'); - $this->service->testValidateResponse(['message-count' => 1]); - } - public function testValidateResponseStatusProperty() - { - $this->setExpectedException('\Nexmo\Exception', 'status property expected'); - $this->service->testValidateResponse(['message-count' => 1, 'messages' => ['error']]); - } - public function testValidateResponseStatusNotZero() - { - $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: status 1'); - $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 1]]]); - } - public function testValidateResponseErrorText() - { - $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: error - status 2'); - $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['error-text' => 'error', 'status' => 2]]]); - } - public function testValidateResponseSuccess() - { - $this->assertTrue($this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 0]]])); - } -} -class MarketingMessageMock extends MarketingMessage -{ - use TestServiceTrait; -} From 0d56c8e9e829234608f52712cc9bcc51873d7dce Mon Sep 17 00:00:00 2001 From: thelaurence Date: Tue, 11 Aug 2015 17:20:46 -0600 Subject: [PATCH 08/25] add property-read\MarketingMessage --- src/Client.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Client.php b/src/Client.php index 77036f4..956c076 100644 --- a/src/Client.php +++ b/src/Client.php @@ -9,10 +9,11 @@ /** * Class Client * - * @property-read Service\Account $account Account management APIs - * @property-read Service\Message $message - * @property-read Service\Voice $voice - * @property-read Service\Verify $verify + * @property-read Service\Account $account Account management APIs + * @property-read Service\MarketingMessage $marketingmessage + * @property-read Service\Message $message + * @property-read Service\Voice $voice + * @property-read Service\Verify $verify * * @package Nexmo\Client */ From b4f161d03158a95fd76d40eb48aab682b19ec66d Mon Sep 17 00:00:00 2001 From: thelaurence Date: Tue, 11 Aug 2015 17:22:04 -0600 Subject: [PATCH 09/25] add MarketingMessage to testConstructor --- tests/ClientTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 8488e2b..83ac249 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -14,6 +14,7 @@ protected function setUp() public function testConstructor() { + $this->assertInstanceOf('\Nexmo\Service\MarketingMessage', $this->client->marketingmessage); $this->assertInstanceOf('\Nexmo\Service\Message', $this->client->message); $this->assertInstanceOf('\Nexmo\Service\Verify', $this->client->verify); $this->assertInstanceOf('\Nexmo\Service\voice', $this->client->voice); From de7b560480f90b7444bd4fabcee70c8de31fd187 Mon Sep 17 00:00:00 2001 From: thelaurence Date: Tue, 11 Aug 2015 17:23:43 -0600 Subject: [PATCH 10/25] put marketing tests back --- tests/Service/MarketingMessageTest.php | 86 ++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php index b3d9bbc..7cc1599 100644 --- a/tests/Service/MarketingMessageTest.php +++ b/tests/Service/MarketingMessageTest.php @@ -1 +1,87 @@ service = new MarketingMessageMock(); + $this->service->setClient($this->guzzle()); + } + public function testInvoke() + { + $this->service->invoke(62687, 'test-keyword', 5005551111, 'test message'); + $this->assertSame($this->service->executedParams, [ + 'from' => 62687, + 'keyword' => 'test-keyword', + 'to' => 5005551111, + 'text' => 'test message' + ]); + } + public function testGetEndpoint() + { + $this->assertEquals($this->service->getEndpoint(), 'sc/us/marketing/json'); + } + public function testFromParameterRequired() + { + $this->setExpectedException('\Nexmo\Exception', '$from parameter cannot be blank'); + $this->service->invoke(); + } + public function testKeywordParameterRequired() + { + $this->setExpectedException('\Nexmo\Exception', '$keyword parameter cannot be blank'); + $this->service->invoke(62687); + } + public function testToParameterRequired() + { + $this->setExpectedException('\Nexmo\Exception', '$to parameter cannot be blank'); + $this->service->invoke(62687, 'test-keyword'); + } + public function testTextParameterRequired() + { + $this->setExpectedException('\Nexmo\Exception', '$text parameter cannot be blank'); + $this->service->invoke(62687, 'test-keyword', 5005551111); + } + public function testValidateResponseMessageCountProperty() + { + $this->setExpectedException('\Nexmo\Exception', 'message-count property expected'); + $this->service->testValidateResponse([]); + } + public function testValidateResponseMessagesProperty() + { + $this->setExpectedException('\Nexmo\Exception', 'messages property expected'); + $this->service->testValidateResponse(['message-count' => 1]); + } + public function testValidateResponseStatusProperty() + { + $this->setExpectedException('\Nexmo\Exception', 'status property expected'); + $this->service->testValidateResponse(['message-count' => 1, 'messages' => ['error']]); + } + public function testValidateResponseStatusNotZero() + { + $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: status 1'); + $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 1]]]); + } + public function testValidateResponseErrorText() + { + $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: error - status 2'); + $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['error-text' => 'error', 'status' => 2]]]); + } + public function testValidateResponseSuccess() + { + $this->assertTrue($this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 0]]])); + } +} +class MarketingMessageMock extends MarketingMessage +{ + use TestServiceTrait; +} From dba8bafe05047b74b13b53daeec49c6ae2175930 Mon Sep 17 00:00:00 2001 From: thelaurence Date: Tue, 11 Aug 2015 17:33:11 -0600 Subject: [PATCH 11/25] just trying stuff --- tests/Service/MarketingMessageTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php index 7cc1599..918f714 100644 --- a/tests/Service/MarketingMessageTest.php +++ b/tests/Service/MarketingMessageTest.php @@ -81,7 +81,7 @@ public function testValidateResponseSuccess() $this->assertTrue($this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 0]]])); } } -class MarketingMessageMock extends MarketingMessage +class MarketingMessageMock extends \Nexmo\Service\MarketingMessage { use TestServiceTrait; } From 0baeb5e198faf5d71c32d6cbdc4f55b871912c98 Mon Sep 17 00:00:00 2001 From: thelaurence Date: Tue, 11 Aug 2015 17:40:12 -0600 Subject: [PATCH 12/25] Update MarketingMessageTest.php --- tests/Service/MarketingMessageTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php index 918f714..7cc1599 100644 --- a/tests/Service/MarketingMessageTest.php +++ b/tests/Service/MarketingMessageTest.php @@ -81,7 +81,7 @@ public function testValidateResponseSuccess() $this->assertTrue($this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 0]]])); } } -class MarketingMessageMock extends \Nexmo\Service\MarketingMessage +class MarketingMessageMock extends MarketingMessage { use TestServiceTrait; } From 2d8579a220421d6379214dab0e6cac7fce16fd93 Mon Sep 17 00:00:00 2001 From: thelaurence Date: Wed, 12 Aug 2015 13:17:29 -0600 Subject: [PATCH 13/25] Delete MarketingMessageTest.php --- tests/Service/MarketingMessageTest.php | 87 -------------------------- 1 file changed, 87 deletions(-) delete mode 100644 tests/Service/MarketingMessageTest.php diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php deleted file mode 100644 index 7cc1599..0000000 --- a/tests/Service/MarketingMessageTest.php +++ /dev/null @@ -1,87 +0,0 @@ -service = new MarketingMessageMock(); - $this->service->setClient($this->guzzle()); - } - public function testInvoke() - { - $this->service->invoke(62687, 'test-keyword', 5005551111, 'test message'); - $this->assertSame($this->service->executedParams, [ - 'from' => 62687, - 'keyword' => 'test-keyword', - 'to' => 5005551111, - 'text' => 'test message' - ]); - } - public function testGetEndpoint() - { - $this->assertEquals($this->service->getEndpoint(), 'sc/us/marketing/json'); - } - public function testFromParameterRequired() - { - $this->setExpectedException('\Nexmo\Exception', '$from parameter cannot be blank'); - $this->service->invoke(); - } - public function testKeywordParameterRequired() - { - $this->setExpectedException('\Nexmo\Exception', '$keyword parameter cannot be blank'); - $this->service->invoke(62687); - } - public function testToParameterRequired() - { - $this->setExpectedException('\Nexmo\Exception', '$to parameter cannot be blank'); - $this->service->invoke(62687, 'test-keyword'); - } - public function testTextParameterRequired() - { - $this->setExpectedException('\Nexmo\Exception', '$text parameter cannot be blank'); - $this->service->invoke(62687, 'test-keyword', 5005551111); - } - public function testValidateResponseMessageCountProperty() - { - $this->setExpectedException('\Nexmo\Exception', 'message-count property expected'); - $this->service->testValidateResponse([]); - } - public function testValidateResponseMessagesProperty() - { - $this->setExpectedException('\Nexmo\Exception', 'messages property expected'); - $this->service->testValidateResponse(['message-count' => 1]); - } - public function testValidateResponseStatusProperty() - { - $this->setExpectedException('\Nexmo\Exception', 'status property expected'); - $this->service->testValidateResponse(['message-count' => 1, 'messages' => ['error']]); - } - public function testValidateResponseStatusNotZero() - { - $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: status 1'); - $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 1]]]); - } - public function testValidateResponseErrorText() - { - $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: error - status 2'); - $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['error-text' => 'error', 'status' => 2]]]); - } - public function testValidateResponseSuccess() - { - $this->assertTrue($this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 0]]])); - } -} -class MarketingMessageMock extends MarketingMessage -{ - use TestServiceTrait; -} From 2fe24a121d1f79ce4c4d9adc54b61e991a59cb17 Mon Sep 17 00:00:00 2001 From: thelaurence Date: Wed, 12 Aug 2015 13:22:26 -0600 Subject: [PATCH 14/25] Update ClientTest.php --- tests/ClientTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 83ac249..8488e2b 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -14,7 +14,6 @@ protected function setUp() public function testConstructor() { - $this->assertInstanceOf('\Nexmo\Service\MarketingMessage', $this->client->marketingmessage); $this->assertInstanceOf('\Nexmo\Service\Message', $this->client->message); $this->assertInstanceOf('\Nexmo\Service\Verify', $this->client->verify); $this->assertInstanceOf('\Nexmo\Service\voice', $this->client->voice); From 26f1b8f224ea8226303e9aeff16f7aefdc58f72b Mon Sep 17 00:00:00 2001 From: thelaurence Date: Wed, 12 Aug 2015 13:47:30 -0600 Subject: [PATCH 15/25] Update MarketingMessage --- src/Service/MarketingMessage | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Service/MarketingMessage b/src/Service/MarketingMessage index c951db6..efd9f50 100644 --- a/src/Service/MarketingMessage +++ b/src/Service/MarketingMessage @@ -1,7 +1,9 @@ 0) { - throw new Exception("Unable to send sms message: status " . $message['status']); + throw new NexmoException("Unable to send sms message: status " . $message['status']); } } From ea9d4964c608aec1ac68272394359c969185dadc Mon Sep 17 00:00:00 2001 From: thelaurence Date: Mon, 24 Aug 2015 10:52:14 -0600 Subject: [PATCH 16/25] Rename MarketingMessage to MarketingMessage.php --- src/Service/{MarketingMessage => MarketingMessage.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Service/{MarketingMessage => MarketingMessage.php} (100%) diff --git a/src/Service/MarketingMessage b/src/Service/MarketingMessage.php similarity index 100% rename from src/Service/MarketingMessage rename to src/Service/MarketingMessage.php From f68a791269035f22ae2d453325c3c95a31f3af3f Mon Sep 17 00:00:00 2001 From: laurence Date: Mon, 24 Aug 2015 11:40:48 -0600 Subject: [PATCH 17/25] re-added tests --- tests/Service/MarketingMessageTest.php | 86 ++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 tests/Service/MarketingMessageTest.php diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php new file mode 100644 index 0000000..22bb2af --- /dev/null +++ b/tests/Service/MarketingMessageTest.php @@ -0,0 +1,86 @@ +service = new MarketingMessageMock(); + $this->service->setClient($this->guzzle()); + } + public function testInvoke() + { + $this->service->invoke(62687, 'test-keyword', 5005551111, 'test message'); + $this->assertSame($this->service->executedParams, [ + 'from' => 62687, + 'keyword' => 'test-keyword', + 'to' => 5005551111, + 'text' => 'test message' + ]); + } + public function testGetEndpoint() + { + $this->assertEquals($this->service->getEndpoint(), 'sc/us/marketing/json'); + } + public function testFromParameterRequired() + { + $this->setExpectedException('\Nexmo\Exception', '$from parameter cannot be blank'); + $this->service->invoke(); + } + public function testKeywordParameterRequired() + { + $this->setExpectedException('\Nexmo\Exception', '$keyword parameter cannot be blank'); + $this->service->invoke(62687); + } + public function testToParameterRequired() + { + $this->setExpectedException('\Nexmo\Exception', '$to parameter cannot be blank'); + $this->service->invoke(62687, 'test-keyword'); + } + public function testTextParameterRequired() + { + $this->setExpectedException('\Nexmo\Exception', '$text parameter cannot be blank'); + $this->service->invoke(62687, 'test-keyword', 5005551111); + } + public function testValidateResponseMessageCountProperty() + { + $this->setExpectedException('\Nexmo\Exception', 'message-count property expected'); + $this->service->testValidateResponse([]); + } + public function testValidateResponseMessagesProperty() + { + $this->setExpectedException('\Nexmo\Exception', 'messages property expected'); + $this->service->testValidateResponse(['message-count' => 1]); + } + public function testValidateResponseStatusProperty() + { + $this->setExpectedException('\Nexmo\Exception', 'status property expected'); + $this->service->testValidateResponse(['message-count' => 1, 'messages' => ['error']]); + } + public function testValidateResponseStatusNotZero() + { + $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: status 1'); + $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 1]]]); + } + public function testValidateResponseErrorText() + { + $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: error - status 2'); + $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['error-text' => 'error', 'status' => 2]]]); + } + public function testValidateResponseSuccess() + { + $this->assertTrue($this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 0]]])); + } +} +class MarketingMessageMock extends MarketingMessage +{ + use TestServiceTrait; +} \ No newline at end of file From 16c716b25886f4f60163f6eaddba103328c3d92c Mon Sep 17 00:00:00 2001 From: thelaurence Date: Mon, 24 Aug 2015 11:58:43 -0600 Subject: [PATCH 18/25] Update MarketingMessageTest.php --- tests/Service/MarketingMessageTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php index 22bb2af..467d44f 100644 --- a/tests/Service/MarketingMessageTest.php +++ b/tests/Service/MarketingMessageTest.php @@ -83,4 +83,4 @@ public function testValidateResponseSuccess() class MarketingMessageMock extends MarketingMessage { use TestServiceTrait; -} \ No newline at end of file +} From e44d8f440055053ac6aa57b7a54c645d19da7ffb Mon Sep 17 00:00:00 2001 From: Quinn Comendant Date: Sat, 29 Aug 2015 22:56:31 -0500 Subject: [PATCH 19/25] Added Number/Buy, Number/Search and Number/Cancel services. Modified Service->exec() to allow specifying http method (these services require POST requests). --- src/Service/Service.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Service/Service.php b/src/Service/Service.php index a9013b0..4e80e01 100644 --- a/src/Service/Service.php +++ b/src/Service/Service.php @@ -32,13 +32,13 @@ abstract protected function validateResponse(array $json); * @throws Exception * @return array */ - protected function exec($params) + protected function exec($params, $method = 'GET') { $params = array_filter($params); - $response = $this->client->get($this->getEndpoint(), [ + $response = $this->client->send($this->client->createRequest($method, $this->getEndpoint(), [ 'query' => $params - ]); + ])); try { $json = $response->json(); @@ -46,7 +46,10 @@ protected function exec($params) throw new Exception($e->getMessage(), 0, $e); } - $this->validateResponse($json); + // Because validateResponse() expects an array, we can only do so if the response body is not empty (which in some cases is a valid response), otherwise $json will be null. + if (strlen($response->getBody()) > 0) { + $this->validateResponse($json); + } return $json; } From 05fdead0bbad60b65714f6bc27a8878d3718dbbe Mon Sep 17 00:00:00 2001 From: Quinn Comendant Date: Sat, 29 Aug 2015 23:01:02 -0500 Subject: [PATCH 20/25] Added Number/Buy, Number/Search and Number/Cancel services. (New files for these services forgot to be added during previous commit.) --- src/Service/Number.php | 40 +++++++++++++++++ src/Service/Number/Buy.php | 81 +++++++++++++++++++++++++++++++++++ src/Service/Number/Cancel.php | 81 +++++++++++++++++++++++++++++++++++ src/Service/Number/Search.php | 66 ++++++++++++++++++++++++++++ 4 files changed, 268 insertions(+) create mode 100644 src/Service/Number.php create mode 100644 src/Service/Number/Buy.php create mode 100644 src/Service/Number/Cancel.php create mode 100644 src/Service/Number/Search.php diff --git a/src/Service/Number.php b/src/Service/Number.php new file mode 100644 index 0000000..2912972 --- /dev/null +++ b/src/Service/Number.php @@ -0,0 +1,40 @@ +search->invoke($country, $index, $size, $pattern, $searchPattern, $features); + } + + /** + * @return array + * @throws Exception + */ + public function buy($country, $msisdn) + { + return $this->buy->invoke($country, $msisdn); + } + /** + * @return array + * @throws Exception + */ + public function cancel($country, $msisdn) + { + return $this->cancel->invoke($country, $msisdn); + } +} diff --git a/src/Service/Number/Buy.php b/src/Service/Number/Buy.php new file mode 100644 index 0000000..ad9b06f --- /dev/null +++ b/src/Service/Number/Buy.php @@ -0,0 +1,81 @@ + + */ +class Buy extends Service +{ + /** + * @inheritdoc + */ + public function getRateLimit() + { + // Max number of requests per second. Nexmo developer API claims 3/sec max, but actually more than 2/sec causes error 429 Too Many Requests. + return 2; + } + + /** + * @inheritdoc + */ + public function getEndpoint() + { + return 'number/buy'; + } + + /** + * @param string $country + * @param string $msisdn + * + * @return boolean + * @throws Exception + */ + public function invoke($country = null, $msisdn = null) + { + if (!$country) { + throw new Exception("\$country parameter cannot be blank"); + } + if (!$msisdn) { + throw new Exception("\$msisdn parameter cannot be blank"); + } + + return $this->exec([ + // Nexmo API requires $country value to be uppercase. + 'country' => strtoupper($country), + 'msisdn' => $msisdn, + ], 'POST'); + } + + + /** + * @inheritdoc + */ + protected function validateResponse(array $json) + { + if (!isset($json['error-code'])) { + throw new Exception('no error code'); + } + + switch ($json['error-code']) { + case '200': + return true; + + case '401': + throw new Exception('error 401 wrong credentials'); + + case '420': + throw new Exception('error 420 wrong parameters'); + + default: + throw new Exception('unknown error code'); + } + } +} diff --git a/src/Service/Number/Cancel.php b/src/Service/Number/Cancel.php new file mode 100644 index 0000000..96c7cb3 --- /dev/null +++ b/src/Service/Number/Cancel.php @@ -0,0 +1,81 @@ + + */ +class Cancel extends Service +{ + /** + * @inheritdoc + */ + public function getRateLimit() + { + // Max number of requests per second. Nexmo developer API claims 3/sec max, but actually more than 2/sec causes error 429 Too Many Requests. + return 2; + } + + /** + * @inheritdoc + */ + public function getEndpoint() + { + return 'number/cancel'; + } + + /** + * @param string $country + * @param string $msisdn + * + * @return boolean + * @throws Exception + */ + public function invoke($country = null, $msisdn = null) + { + if (!$country) { + throw new Exception("\$country parameter cannot be blank"); + } + if (!$msisdn) { + throw new Exception("\$msisdn parameter cannot be blank"); + } + + return $this->exec([ + // Nexmo API requires $country value to be uppercase. + 'country' => strtoupper($country), + 'msisdn' => $msisdn, + ], 'POST'); + } + + + /** + * @inheritdoc + */ + protected function validateResponse(array $json) + { + if (!isset($json['error-code'])) { + throw new Exception('no error code'); + } + + switch ($json['error-code']) { + case '200': + return true; + + case '401': + throw new Exception('error 401 wrong credentials'); + + case '420': + throw new Exception('error 420 wrong parameters'); + + default: + throw new Exception('unknown error code'); + } + } +} diff --git a/src/Service/Number/Search.php b/src/Service/Number/Search.php new file mode 100644 index 0000000..4282936 --- /dev/null +++ b/src/Service/Number/Search.php @@ -0,0 +1,66 @@ +exec([ + // Nexmo API requires $country value to be uppercase. + 'country' => strtoupper($country), + 'index' => $index, + 'size' => $size, + 'pattern' => $pattern, + 'search_pattern' => $searchPattern, + 'features' => $features, + ])); + } + + /** + * @inheritdoc + */ + protected function validateResponse(array $json) + { + // If the 'numbers' element exists (which it won't if no numbers are available for a search), validate it is an array. + if (isset($json['numbers']) && !is_array($json['numbers'])) { + throw new Exception('numbers property not an array'); + } + } +} From e8b1ac649cc8984f03bb07ea3848343240d51bcf Mon Sep 17 00:00:00 2001 From: Quinn Comendant Date: Sun, 30 Aug 2015 00:15:35 -0500 Subject: [PATCH 21/25] Updated the Message->containsUnicode() method to detect characters which are outside the GSM default character set. Nexmo claims to be able to support the GSM 03.38 Basic Character Set in text (not unicode) messages. Here, I've changed this method to test specifically for these. The old method fails because many of these characters are outside the normal ASCII range, and because the characters cannot be converted safely using ord() and str_split(). --- src/Service/Message.php | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/Service/Message.php b/src/Service/Message.php index c724c15..ab00ebc 100644 --- a/src/Service/Message.php +++ b/src/Service/Message.php @@ -83,7 +83,8 @@ public function invoke( throw new Exception("\$text parameter cannot be blank"); } - if ($type === 'text' && $this->containsUnicode($text)) { + // If $type is empty, 'text' will be assumed by Nexmo's SMS API. + if (($type == '' || $type === 'text') && $this->containsUnicode($text)) { $type = 'unicode'; } @@ -104,9 +105,38 @@ public function invoke( ]); } + /** + * @param string $text + * @return int + */ protected function containsUnicode($text) { - return max(array_map('ord', str_split($text))) > 127; + // Valid GSM default character-set codepoint values from http://unicode.org/Public/MAPPINGS/ETSI/GSM0338.TXT + $gsm_0338_codepoints = [0x0040, 0x00A3, 0x0024, 0x00A5, 0x00E8, 0x00E9, 0x00F9, 0x00EC, 0x00F2, 0x00E7, 0x000A, 0x00D8, 0x00F8, 0x000D, 0x00C5, 0x00E5, 0x0394, 0x005F, 0x03A6, 0x0393, 0x039B, 0x03A9, 0x03A0, 0x03A8, 0x03A3, 0x0398, 0x039E, 0x00A0, 0x000C, 0x005E, 0x007B, 0x007D, 0x005C, 0x005B, 0x007E, 0x005D, 0x007C, 0x20AC, 0x00C6, 0x00E6, 0x00DF, 0x00C9, 0x0020, 0x0021, 0x0022, 0x0023, 0x00A4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x00A1, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x00C4, 0x00D6, 0x00D1, 0x00DC, 0x00A7, 0x00BF, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x00E4, 0x00F6, 0x00F1, 0x00FC, 0x00E0]; + + // Split $text into an array in a way that respects multibyte characters. + $text_chars = preg_split('//u', $text, null, PREG_SPLIT_NO_EMPTY); + + // Array of codepoint values for characters in $text. + $text_codepoints = array_map([$this, 'uord'], $text_chars); + + // Filter the array to contain only codepoints from $text that are not in the set of valid GSM codepoints. + $non_gsm_codepoints = array_diff($text_codepoints, $gsm_0338_codepoints); + + // The text contains unicode if the result is not empty. + return !empty($non_gsm_codepoints); + } + + /** + * @param char $unicode_char + * @return int + */ + public function uord($unicode_char) + { + $k = mb_convert_encoding($unicode_char, 'UCS-2LE', 'UTF-8'); + $k1 = ord(substr($k, 0, 1)); + $k2 = ord(substr($k, 1, 1)); + return $k2 * 256 + $k1; } /** From d1224061ff33f0eb811a781875df4c7509340329 Mon Sep 17 00:00:00 2001 From: Quinn Comendant Date: Sun, 30 Aug 2015 18:19:23 -0500 Subject: [PATCH 22/25] Updated README with usage examples. --- README.md | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/README.md b/README.md index c544360..9bee9cc 100644 --- a/README.md +++ b/README.md @@ -5,5 +5,133 @@ Unofficial [Nexmo](https://www.nexmo.com/) Rest Client [Nexmo API Documentation](https://docs.nexmo.com/) ## How to Install ```composer require connect-corp/nexmo-client``` + +## Usage examples + +### Setting up the client object + + $nexmo_client_options = array( + 'apiKey' => '…', + 'apiSecret' => '…', + 'debug' => false, + 'timeout' => 5.0, + ); + $nexmo = new \Nexmo\Client($nexmo_client_options); + +### Sending a message + + $from = '1234567890'; + $to = '15551232020'; + $text = 'hello world'; + try { + $response = $nexmo->message->invoke($from, $to, 'text', $text); + } catch (Exception $e) { + die($e->getMessage()); + } + foreach ($response['messages'] as $i => $m) { + switch ($m['status']) { + case '0': + echo 'Message sent successfully:'; + print_r($m); + break; + + default: + echo 'Message sending failed:' + print_r($m); + break; + } + } + +### Getting account balance + + try { + $response = $nexmo->account->balance(); + } catch (Exception $e) { + die($e->getMessage()); + } + echo "Account balance is $response"; + +### Getting pricing by destination country + + $country = 'US'; + try { + $response = $nexmo->account->pricing->country($country); + } catch (Exception $e) { + die($e->getMessage()); + } + echo 'Price is ' . $response->price(); + +### Getting pricing by recipient number + + $number = '15551232020'; + try { + // SMS pricing. + $response = $nexmo->account->pricing->sms($number); + // Voice pricing. + $response = $nexmo->account->pricing->voice($number); + } catch (Exception $e) { + die($e->getMessage()); + } + echo 'Price is ' . $response->price(); + + +### Search for long virtual numbers by country + + $country = 'US'; + try { + $response = $nexmo->number->search($country); + } catch (Exception $e) { + die($e->getMessage()); + } + $all = $response->all(); + if (isset($all['numbers'])) { + foreach ($all['numbers'] as $n) { + printf("%d \$%01.2f %-10s %-15s\n", $n['msisdn'], $n['cost'], $n['type'], join(',', $n['features'])); + } + } + +### Buy a long virtual number + + $country = 'US'; + $msisdn = '1234567890'; // Number found using $nexmo->number->search() + try { + $response = $nexmo->number->buy($country, $msisdn); + } catch (Exception $e) { + die($e->getMessage()); + } + if (200 == $response['error-code']) { + echo 'Number purchase success'; + } + +### List long virtual numbers in your account + + $country = 'US'; + try { + $response = $nexmo->account->numbers(); + } catch (Exception $e) { + die($e->getMessage()); + } + $all = $response->all(); + if (isset($all['numbers'])) { + foreach ($all['numbers'] as $n) { + printf("%d %-2s %-10s %-15s\n", $n['msisdn'], $n['country'], $n['type'], join(',', $n['features'])); + } + } + +### Cancel a long virtual number + + $country = 'US'; + $msisdn = '1234567890'; // Number found using $nexmo->account->numbers() + try { + $response = $nexmo->number->cancel($country, $msisdn); + } catch (Exception $e) { + die($e->getMessage()); + } + if (200 == $response['error-code']) { + echo 'Number cancel success'; + } + ## Contributors - @CarsonF +- @com + From a69e72d7df5554d4f5256c457ab2f9f60ce6ff44 Mon Sep 17 00:00:00 2001 From: thelaurence Date: Wed, 9 Sep 2015 10:24:30 -0600 Subject: [PATCH 23/25] fixing up unit tests --- tests/Service/MarketingMessageTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php index 467d44f..f204301 100644 --- a/tests/Service/MarketingMessageTest.php +++ b/tests/Service/MarketingMessageTest.php @@ -67,12 +67,12 @@ public function testValidateResponseStatusProperty() } public function testValidateResponseStatusNotZero() { - $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: status 1'); - $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 1]]]); + $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: Unknown - status code: 1'); + $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['error-text' => 'Unknown', 'status' => 1]]]); } public function testValidateResponseErrorText() { - $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: error - status 2'); + $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: error - status code: 2'); $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['error-text' => 'error', 'status' => 2]]]); } public function testValidateResponseSuccess() From d8024b93ccf04125bc4657f28cbf0f72f7b357ef Mon Sep 17 00:00:00 2001 From: Pavel Dubinin Date: Wed, 9 Mar 2016 13:31:03 +0300 Subject: [PATCH 24/25] Fixed strict php errors during tests --- tests/Service/Account/NumbersTest.php | 2 +- tests/Service/Account/Pricing/CountryTest.php | 2 +- tests/Service/Account/Pricing/InternationalTest.php | 2 +- tests/Service/Account/Pricing/PhoneTest.php | 2 +- tests/Service/TestServiceTrait.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Service/Account/NumbersTest.php b/tests/Service/Account/NumbersTest.php index a43b8f7..fb081e2 100644 --- a/tests/Service/Account/NumbersTest.php +++ b/tests/Service/Account/NumbersTest.php @@ -141,7 +141,7 @@ class NumbersMock extends Numbers { public $executedParams; - protected function exec($params) + protected function exec($params, $method = 'GET') { $this->executedParams = $params; return parent::exec($params); diff --git a/tests/Service/Account/Pricing/CountryTest.php b/tests/Service/Account/Pricing/CountryTest.php index da613c1..17c2c2e 100644 --- a/tests/Service/Account/Pricing/CountryTest.php +++ b/tests/Service/Account/Pricing/CountryTest.php @@ -123,7 +123,7 @@ class CountryMock extends Country { public $executedParams; - protected function exec($params) + protected function exec($params, $method = 'GET') { $this->executedParams = $params; return parent::exec($params); diff --git a/tests/Service/Account/Pricing/InternationalTest.php b/tests/Service/Account/Pricing/InternationalTest.php index 1ee5c99..7fd6964 100644 --- a/tests/Service/Account/Pricing/InternationalTest.php +++ b/tests/Service/Account/Pricing/InternationalTest.php @@ -96,7 +96,7 @@ class InternationalMock extends International { public $executedParams; - protected function exec($params) + protected function exec($params, $method = 'GET') { $this->executedParams = $params; return parent::exec($params); diff --git a/tests/Service/Account/Pricing/PhoneTest.php b/tests/Service/Account/Pricing/PhoneTest.php index 9a6f994..7f39bc4 100644 --- a/tests/Service/Account/Pricing/PhoneTest.php +++ b/tests/Service/Account/Pricing/PhoneTest.php @@ -100,7 +100,7 @@ class PhoneMock extends Phone { public $executedParams; - protected function exec($params) + protected function exec($params, $method = 'GET') { $this->executedParams = $params; return parent::exec($params); diff --git a/tests/Service/TestServiceTrait.php b/tests/Service/TestServiceTrait.php index e3112c5..cb930a5 100644 --- a/tests/Service/TestServiceTrait.php +++ b/tests/Service/TestServiceTrait.php @@ -11,7 +11,7 @@ public function testValidateResponse($params) return $this->validateResponse($params); } - protected function exec($params) + protected function exec($params, $method = 'GET') { $this->executedParams = $params; } From 5c82a4c323d1f52397e0d5fbebee3a26ef14d8b1 Mon Sep 17 00:00:00 2001 From: thelaurence Date: Tue, 15 Mar 2016 02:43:11 -0600 Subject: [PATCH 25/25] fixed build errors --- tests/Service/MarketingMessageTest.php | 4 ++-- tests/Service/MessageTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Service/MarketingMessageTest.php b/tests/Service/MarketingMessageTest.php index f204301..d5e133a 100644 --- a/tests/Service/MarketingMessageTest.php +++ b/tests/Service/MarketingMessageTest.php @@ -67,12 +67,12 @@ public function testValidateResponseStatusProperty() } public function testValidateResponseStatusNotZero() { - $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: Unknown - status code: 1'); + $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: Unknown - status 1'); $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['error-text' => 'Unknown', 'status' => 1]]]); } public function testValidateResponseErrorText() { - $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: error - status code: 2'); + $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: error - status 2'); $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['error-text' => 'error', 'status' => 2]]]); } public function testValidateResponseSuccess() diff --git a/tests/Service/MessageTest.php b/tests/Service/MessageTest.php index f684a2c..1e1c7b6 100644 --- a/tests/Service/MessageTest.php +++ b/tests/Service/MessageTest.php @@ -85,7 +85,7 @@ public function testValidateResponseStatusProperty() public function testValidateResponseStatusNotZero() { - $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: status 1'); + $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: Unknown - status code: 1'); $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['status' => 1]]]); } @@ -93,7 +93,7 @@ public function testValidateResponseStatusNotZero() public function testValidateResponseErrorText() { - $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: error - status 2'); + $this->setExpectedException('\Nexmo\Exception', 'Unable to send sms message: error - status code: 2'); $this->service->testValidateResponse(['message-count' => 1, 'messages' => [['error-text' => 'error', 'status' => 2]]]); }