Skip to content

Commit ca6b252

Browse files
committed
Search SMS rejections capability. Returns list of matching messages
Implements #42
1 parent e03dc4c commit ca6b252

File tree

7 files changed

+152
-0
lines changed

7 files changed

+152
-0
lines changed

src/Message/Client.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,56 @@ public function search($idOrMessage)
213213
return $message;
214214
}
215215

216+
public function searchRejections(Query $query) {
217+
218+
$params = $query->getParams();
219+
$request = new Request(
220+
\Nexmo\Client::BASE_REST . '/search/messages?' . http_build_query($params),
221+
'GET',
222+
'php://temp',
223+
['Accept' => 'application/json']
224+
);
225+
226+
$response = $this->client->send($request);
227+
$response->getBody()->rewind();
228+
$data = json_decode($response->getBody()->getContents(), true);
229+
230+
if($response->getStatusCode() != '200' && isset($data['error-code'])){
231+
throw new Exception\Request($data['error-code-label'], $data['error-code']);
232+
} elseif($response->getStatusCode() != '200'){
233+
throw new Exception\Request('error status from API', $response->getStatusCode());
234+
}
235+
236+
if(!isset($data['items'])){
237+
throw new Exception\Exception('unexpected response from API');
238+
}
239+
240+
if(count($data['items']) == 0){
241+
return [];
242+
}
243+
244+
$collection = [];
245+
246+
foreach($data['items'] as $index => $item){
247+
switch($item['type']){
248+
case 'MT':
249+
$new = new Message($item['message-id']);
250+
break;
251+
case 'MO':
252+
$new = new InboundMessage($item['message-id']);
253+
break;
254+
default:
255+
throw new Exception\Exception('unexpected response from API');
256+
}
257+
258+
$new->setResponse($response);
259+
$new->setIndex($index);
260+
$collection[] = $new;
261+
}
262+
263+
return $collection;
264+
}
265+
216266
/**
217267
* @param array $message
218268
* @return Message

test/Message/ClientTest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88

99
namespace NexmoTest\Message;
1010

11+
use Nexmo\Client\Exception;
1112
use Nexmo\Message\Client;
1213
use Nexmo\Message\Message;
1314
use Nexmo\Message\Text;
1415
use NexmoTest\Psr7AssertionTrait;
16+
use NexmoTest\MessageAssertionTrait;
1517
use Prophecy\Argument;
1618
use Psr\Http\Message\RequestInterface;
1719
use Zend\Diactoros\Request;
@@ -20,6 +22,7 @@
2022
class ClientTest extends \PHPUnit_Framework_TestCase
2123
{
2224
use Psr7AssertionTrait;
25+
use MessageAssertionTrait;
2326

2427
protected $nexmoClient;
2528

@@ -202,6 +205,53 @@ public function testRateLimitRetires()
202205
$this->assertEquals($success, $message->getResponse());
203206
}
204207

208+
/**
209+
* @dataProvider searchRejectionsProvider
210+
*/
211+
public function testCanSearchRejections($date, $to, $responseFile, $expectedResponse, $expectedHttpCode, $expectedException)
212+
{
213+
$query = new \Nexmo\Message\Query($date, $to);
214+
215+
$apiResponse = $this->getResponse($responseFile, $expectedHttpCode);
216+
217+
$this->nexmoClient->send(Argument::that(function (Request $request) use ($to, $date) {
218+
$this->assertRequestQueryContains('to', $to, $request);
219+
$this->assertRequestQueryContains('date', $date->format('Y-m-d'), $request);
220+
return true;
221+
}))->willReturn($apiResponse);
222+
223+
224+
// If we're expecting this to throw an exception, listen for it in advance
225+
if ($expectedException !== null) {
226+
$this->expectException($expectedException);
227+
$this->expectExceptionMessage($expectedResponse);
228+
}
229+
230+
// Make the request and assert that our responses match
231+
$rejectionsResponse = $this->messageClient->searchRejections($query);
232+
$this->assertListOfMessagesEqual($expectedResponse, $rejectionsResponse);
233+
}
234+
235+
public function searchRejectionsProvider()
236+
{
237+
$r = [];
238+
239+
$r['no rejections found'] = [new \DateTime(), '123456', 'search-rejections-empty', [], 200, null];
240+
241+
// Build up our expected message object
242+
$message = new Message('0C0000005BA0B864');
243+
$message->setResponse($this->getResponse('search-rejections'));
244+
$message->setIndex(0);
245+
$r['rejection found'] = [new \DateTime(), '123456', 'search-rejections', [$message], 200, null];
246+
247+
$r['error-code provided (validation)'] = [new \DateTime(), '123456', 'search-rejections-error-provided-validation', 'Validation error: You forgot to do something', 400, Exception\Request::class];
248+
$r['error-code provided (server error)'] = [new \DateTime(), '123456', 'search-rejections-error-provided-server-error', 'Gremlins! There are gremlins in the system!', 500, Exception\Request::class];
249+
$r['error-code not provided'] = [new \DateTime(), '123456', 'empty', 'error status from API', 500, Exception\Request::class];
250+
$r['missing items key in response on 200'] = [new \DateTime(), '123456', 'empty', 'unexpected response from API', 200, Exception\Exception::class];
251+
252+
return $r;
253+
}
254+
205255
/**
206256
* Get the API response we'd expect for a call to the API. Message API currently returns 200 all the time, so only
207257
* change between success / fail is body of the message.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"count": 0,
3+
"items": []
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"error-code": 99,
3+
"error-code-label": "Gremlins! There are gremlins in the system!"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"error-code": 42,
3+
"error-code-label": "Validation error: You forgot to do something"
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"count":1,"items":[{"message-id":"0C0000005BA0B864","account-id":"7c9738e6","network":"US-PREMIUM","from":"12013800826","to":"14155550100","body":"A text message sent using the Nexmo SMS API","price":"0","date-received":"2017-09-04 15:08:44","status":"REJECTD","error-code":"1","error-code-label":"Unknown","type":"MT"}]}

test/MessageAssertionTrait.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
/**
3+
* Nexmo Client Library for PHP
4+
*
5+
* @copyright Copyright (c) 2016 Nexmo, Inc. (http://nexmo.com)
6+
* @license https://github.com/Nexmo/nexmo-php/blob/master/LICENSE.txt MIT License
7+
*/
8+
9+
namespace NexmoTest;
10+
11+
use GuzzleHttp\Psr7\Request;
12+
use Nexmo\Message\Message;
13+
14+
trait MessageAssertionTrait
15+
{
16+
public static function assertListOfMessagesEqual(array $expected, array $actual)
17+
{
18+
$expectedCount = count($expected);
19+
$actualCount = count($actual);
20+
21+
if ($expectedCount !== $actualCount) {
22+
throw new \InvalidArgumentException('Expected count and actual count must match');
23+
}
24+
25+
// If passed empty arrays, there are no messages to compare
26+
if ($expectedCount === 0) {
27+
return;
28+
}
29+
30+
foreach ($expected as $k => $item) {
31+
self::assertMessagesEqual($expected[$k], $actual[$k]);
32+
}
33+
}
34+
35+
public static function assertMessagesEqual(Message $expected, Message $actual)
36+
{
37+
self::assertEquals($expected->getResponseData(), $actual->getResponseData());
38+
}
39+
}

0 commit comments

Comments
 (0)