<?php
namespace WebPower\gcm\server;
class MockHttpClient implements HttpClient
{
public $apiKey;
public $url;
public $mimeType;
public $requestBody;
public $responseList = array();
public function post($apiKey, $url, $mimeType, $requestBody)
{
$this->apiKey = $apiKey;
$this->url = $url;
$this->mimeType = $mimeType;
$this->requestBody = $requestBody;
return array_shift($this->responseList);
}
}
class SenderTest extends \PHPUnit_Framework_TestCase
{
private $regId = "15;16";
private $collapseKey = "collapseKey";
private $delayWhileIdle = true;
private $ttl = 108;
private $authKey = "4815162342";
/** @var Message */
private $message;
/** @var MockHttpClient */
private $mockClient;
/** @var Sender */
private $sender;
protected function setUp()
{
parent::setUp();
$this->message = Message::builder()
->collapseKey($this->collapseKey)
->delayWhileIdle($this->delayWhileIdle)
->timeToLive($this->ttl)
->addData('k1', 'v1')
->addData('k2', 'v2')
->addData('k3', 'v3')
->build();
$this->mockClient = new MockHttpClient();
$this->sender = new Sender($this->authKey);
$this->sender->setHttpClient($this->mockClient);
}
public function setResponseExpectations($statusCode, $content)
{
$this->mockClient->responseList[] = new HttpClientResponse($statusCode, $content);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testConstructorNull()
{
new Sender(null);
}
public function testSendNoRetry_ok()
{
$this->setResponseExpectations(200, "id=4815162342");
$result = $this->sender->singleSendNoRetry($this->message, $this->regId);
$this->assertNotNull($result);
$this->assertEquals("4815162342", $result->getMessageId());
$this->assertNull($result->getCanonicalRegistrationId());
$this->assertNull($result->getErrorCodeName());
$this->assertRequestBody();
}
public function testSendNoRetry_ok_canonical()
{
$this->setResponseExpectations(
200,
"id=4815162342\nregistration_id=108"
);
$result = $this->sender->singleSendNoRetry($this->message, $this->regId);
$this->assertNotNull($result);
$this->assertEquals("4815162342", $result->getMessageId());
$this->assertEquals("108", $result->getCanonicalRegistrationId());
$this->assertNull($result->getErrorCodeName());
$this->assertRequestBody();
}
public function testSendNoRetry_unauthorized()
{
$this->setResponseExpectations(401, "");
try {
$this->sender->singleSendNoRetry($this->message, $this->regId);
$this->fail("Should have thrown InvalidRequestException");
} catch (InvalidRequestException $e) {
$this->assertEquals(401, $e->getHttpStatusCode());
}
$this->assertRequestBody();
}
public function testSendNoRetry_error()
{
$this->setResponseExpectations(200, "Error=D'OH!");
$result = $this->sender->singleSendNoRetry($this->message, $this->regId);
$this->assertNull($result->getMessageId());
$this->assertNull($result->getCanonicalRegistrationId());
$this->assertEquals("D'OH!", $result->getErrorCodeName());
$this->assertRequestBody();
}
public function testSendNoRetry_serviceUnavailable()
{
$this->setResponseExpectations(503, "");
$result = $this->sender->singleSendNoRetry($this->message, $this->regId);
$this->assertNull($result);
$this->assertRequestBody();
}
/**
* @expectedException \RuntimeException
*/
public function testSendNoRetry_emptyBody()
{
$this->setResponseExpectations(200, "");
$this->sender->singleSendNoRetry($this->message, $this->regId);
}
/**
* @expectedException \RuntimeException
*/
public function testSendNoRetry_noToken()
{
$this->setResponseExpectations(200, 'no token');
$this->sender->singleSendNoRetry($this->message, $this->regId);
}
/**
* @expectedException \RuntimeException
*/
public function testSendNoRetry_invalidToken()
{
$this->setResponseExpectations(200, 'bad=token');
$this->sender->singleSendNoRetry($this->message, $this->regId);
}
public function testSendNoRetry_invalidHttpStatusCode()
{
$this->setResponseExpectations(108, 'id=4815162342');
try {
$this->sender->singleSendNoRetry($this->message, $this->regId);
$this->fail('Should have thrown InvalidRequestException');
} catch (InvalidRequestException $e) {
$this->assertEquals(108, $e->getHttpStatusCode());
}
}
/**
* @expectedException \InvalidArgumentException
*/
public function testSendNoRetry_noRegistrationId()
{
$this->sender->singleSendNoRetry(Message::builder()->build(), null);
}
public function testSendNoRetry_json_badRequest()
{
$this->setResponseExpectations(42, "bad json");
try {
$this->sender->sendNoRetry($this->message, array("108"));
} catch (InvalidRequestException $e) {
$this->assertEquals(42, $e->getHttpStatusCode());
$this->assertEquals("bad json", $e->getDescription());
$this->assertRequestJsonBody(array("108"));
}
}
public function testSendNoRetry_json_ok()
{
$json = json_encode(array(
"multicast_id" => 108,
"success" => 2,
"failure" => 1,
"canonical_ids" => 1,
"results" => array(
array('message_id' => 16),
array('error' => 'DOH!'),
array('message_id' => 23, 'registration_id' => 42)
)
));
$this->setResponseExpectations(200, $json);
$registrationIds = array("4", "8", "15");
$multicastResponse = $this->sender->sendNoRetry(
$this->message,
$registrationIds
);
$this->assertNotNull($multicastResponse);
$this->assertEquals(3, $multicastResponse->getTotal());
$this->assertEquals(2, $multicastResponse->getSuccess());
$this->assertEquals(1, $multicastResponse->getFailure());
$this->assertEquals(1, $multicastResponse->getCanonicalIds());
$this->assertEquals(108, $multicastResponse->getMulticastId());
$results = $multicastResponse->getResults();
$this->assertNotNull($results);
$this->assertEquals(3, count($results));
$this->assertResult($results[0], "16", null, null);
$this->assertResult($results[1], null, 'DOH!', null);
$this->assertResult($results[2], "23", null, "42");
$this->assertRequestJsonBody($registrationIds);
}
private function assertRequestBody()
{
$body = $this->mockClient->requestBody;
$params = array();
foreach (explode('&', $body) as $param) {
list($key, $value) = explode('=', $param, 2);
$params[$key] = $value;
}
$this->assertEquals(7, count($params), $body);
$this->assertParameter($params, 'registration_id', $this->regId);
$this->assertParameter($params, 'collapse_key', $this->collapseKey);
$this->assertParameter($params, 'delay_while_idle', $this->delayWhileIdle ? "1" : "0");
$this->assertParameter($params, 'time_to_live', "" . $this->ttl);
$this->assertParameter($params, 'data.k1', 'v1');
$this->assertParameter($params, 'data.k2', 'v2');
$this->assertParameter($params, 'data.k3', 'v3');
}
private function assertParameter($params, $name, $expectedValue)
{
$this->assertEquals(
$expectedValue,
$params[$name],
"invalid value for request parameter parameter " . $name
);
}
private function assertRequestJsonBody(array $expectedRegIds)
{
$this->assertEquals(
Constants::GCM_SEND_ENDPOINT,
$this->mockClient->url
);
$this->assertEquals('application/json', $this->mockClient->mimeType);
$body = $this->mockClient->requestBody;
$json = json_decode($body, true);
$this->assertEquals($this->ttl, $json['time_to_live']);
$this->assertEquals($this->collapseKey, $json['collapse_key']);
$this->assertEquals($this->delayWhileIdle, $json['delay_while_idle']);
$payload = $json['data'];
$this->assertNotNull($payload, 'no payload');
$this->assertEquals(3, count($payload), 'wrong payload size');
$this->assertEquals('v1', $payload['k1']);
$this->assertEquals('v2', $payload['k2']);
$this->assertEquals('v3', $payload['k3']);
$actualRegIds = $json['registration_ids'];
$this->assertEquals(count($expectedRegIds), count($actualRegIds));
$this->assertEquals($expectedRegIds, $actualRegIds);
}
private function assertResult(
Result $result,
$messageId,
$error,
$canonicalRegistrationId
) {
$this->assertEquals($messageId, $result->getMessageId());
$this->assertEquals($error, $result->getErrorCodeName());
$this->assertEquals(
$canonicalRegistrationId,
$result->getCanonicalRegistrationId()
);
}
}
|