/tests/ClientTest.php
https://gitlab.com/twinscom/notifier-php-client · PHP · 450 lines · 354 code · 85 blank · 11 comment · 0 complexity · 26c37f9002b472561f918d3f6211777b MD5 · raw file
- <?php
- declare(strict_types=1);
- namespace twinscom\Notifier\Tests;
- use GuzzleHttp\Client as GuzzleHttpClient;
- use GuzzleHttp\Exception\RequestException;
- use GuzzleHttp\Exception\TransferException;
- use GuzzleHttp\Handler\MockHandler;
- use GuzzleHttp\HandlerStack;
- use GuzzleHttp\Middleware;
- use GuzzleHttp\Psr7\Request;
- use GuzzleHttp\Psr7\Response;
- use PHPUnit\Framework\TestCase;
- use twinscom\GuzzleComponents\RetryDecider;
- use twinscom\Notifier\Client;
- /**
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- *
- * @internal
- */
- final class ClientTest extends TestCase
- {
- public function testSend(): void
- {
- $this->send('sendEmail', '/email');
- $this->send('sendPush', '/push');
- }
- public function testOnSuccess(): void
- {
- $this->onSuccess('sendEmail');
- $this->onSuccess('sendPush');
- }
- public function testOnError(): void
- {
- $this->onError('sendEmail');
- $this->onError('sendPush');
- }
- public function testTransferException(): void
- {
- $this->transferException('sendEmail');
- $this->transferException('sendPush');
- }
- public function testClientError(): void
- {
- $this->clientError('sendEmail');
- $this->clientError('sendPush');
- }
- public function testResponselessException(): void
- {
- $this->responselessException('sendEmail');
- $this->responselessException('sendPush');
- }
- public function testGuzzleInstantiation(): void
- {
- $baseUri = 'http://localhost/test/';
- $notifierClient = new Client([
- 'baseUri' => $baseUri,
- 'apiKey' => 'test-api-key',
- ]);
- $reflectionClass = new \ReflectionClass($notifierClient);
- $paramsProperty = $reflectionClass->getProperty('params');
- $paramsProperty->setAccessible(true);
- $notifierClientParams = $paramsProperty->getValue($notifierClient);
- $guzzleHttpClient = $notifierClientParams['guzzleHttpClient'];
- self::assertInstanceOf(GuzzleHttpClient::class, $guzzleHttpClient);
- self::assertSame(
- $baseUri,
- (string) $guzzleHttpClient->getConfig('base_uri')
- );
- self::assertContains(
- 'Middleware::retry',
- $guzzleHttpClient->getConfig('handler')->__toString()
- );
- }
- public function testRetryMechanism(): void
- {
- $mockHandler = new MockHandler([
- new Response(500, [], json_encode([
- 'message' => 'You should not see it',
- ])),
- new Response(200, [], '[123]'),
- ]);
- $container = [];
- $notifierClient = new Client([
- 'guzzleHttpClient' => $this->getGuzzleHttpClient(
- $mockHandler,
- $container
- ),
- 'apiKey' => 'test-api-key',
- ]);
- $message = [
- 'key' => 'value',
- ];
- $notifierClient->sendEmail([
- 'templateId' => 'welcome',
- 'message' => $message,
- ]);
- $request = $container[1]['request'];
- assert($request instanceof Request);
- self::assertSame('POST', $request->getMethod());
- self::assertSame('/email', $request->getUri()->getPath());
- self::assertContains(
- 'template-id=welcome',
- $request->getUri()->getQuery()
- );
- self::assertContains(
- 'api-key=test-api-key',
- $request->getUri()->getQuery()
- );
- self::assertSame(
- $message,
- json_decode($request->getBody()->getContents(), true)
- );
- }
- /**
- * @SuppressWarnings(PHPMD.StaticAccess)
- */
- private function getGuzzleHttpClient(
- MockHandler $mockHandler,
- array &$container
- ) {
- $history = Middleware::history($container);
- $handlerStack = HandlerStack::create($mockHandler);
- $handlerStack->push(
- Middleware::retry(
- RetryDecider::make(1)
- )
- );
- $handlerStack->push($history);
- return new GuzzleHttpClient([
- 'handler' => $handlerStack,
- ]);
- }
- private function send(string $methodName, string $path): void
- {
- $mockHandler = new MockHandler([
- new Response(202, [], ''),
- ]);
- $container = [];
- $guzzleHttpClient = $this->getGuzzleHttpClient(
- $mockHandler,
- $container
- );
- $notifierClient = new Client([
- 'guzzleHttpClient' => $guzzleHttpClient,
- 'apiKey' => 'test-api-key',
- ]);
- $message = [
- 'key' => 'value',
- ];
- $notifierClient->{$methodName}([
- 'templateId' => 'welcome',
- 'message' => $message,
- ]);
- $request = $container[0]['request'];
- assert($request instanceof Request);
- self::assertSame('POST', $request->getMethod());
- self::assertSame($path, $request->getUri()->getPath());
- self::assertContains(
- 'template-id=welcome',
- $request->getUri()->getQuery()
- );
- self::assertContains(
- 'api-key=test-api-key',
- $request->getUri()->getQuery()
- );
- self::assertSame(
- $message,
- json_decode($request->getBody()->getContents(), true)
- );
- }
- private function onSuccess(string $methodName): void
- {
- $mockHandler = new MockHandler([
- new Response(202, [], ''),
- ]);
- $container = [];
- $guzzleHttpClient = $this->getGuzzleHttpClient(
- $mockHandler,
- $container
- );
- $onSuccessMock = $this
- ->getMockBuilder(\stdClass::class)
- ->setMethods(['onSuccess'])
- ->getMock();
- $notifierClient = new Client([
- 'guzzleHttpClient' => $guzzleHttpClient,
- 'apiKey' => 'test-api-key',
- ]);
- $message = [
- 'key' => 'value',
- ];
- $onSuccessMock
- ->expects(self::once())
- ->method('onSuccess');
- $notifierClient->{$methodName}([
- 'templateId' => 'welcome',
- 'message' => $message,
- 'onSuccess' => [$onSuccessMock, 'onSuccess'],
- ]);
- }
- private function onError(string $methodName): void
- {
- $response = [
- 'code' => 'UnauthorizedError',
- 'message' => 'Unauthorized',
- ];
- $mockHandler = new MockHandler([
- new Response(401, [], json_encode($response)),
- new Response(401, [], json_encode($response)),
- ]);
- $container = [];
- $guzzleHttpClient = $this->getGuzzleHttpClient(
- $mockHandler,
- $container
- );
- $onSuccessMock = $this
- ->getMockBuilder(\stdClass::class)
- ->setMethods(['onSuccess'])
- ->getMock();
- $onErrorMock = $this
- ->getMockBuilder(\stdClass::class)
- ->setMethods(['onError'])
- ->getMock();
- $notifierClient = new Client([
- 'guzzleHttpClient' => $guzzleHttpClient,
- 'apiKey' => 'test-api-key',
- ]);
- $message = [
- 'key' => 'value',
- ];
- $onSuccessMock
- ->expects(self::never())
- ->method('onSuccess');
- $onErrorMock
- ->expects(self::once())
- ->method('onError')
- ->with(self::equalTo($response['message']));
- // This should not throw:
- $notifierClient->{$methodName}([
- 'templateId' => 'welcome',
- 'message' => $message,
- ]);
- $notifierClient->{$methodName}([
- 'templateId' => 'welcome',
- 'message' => $message,
- 'onError' => [$onErrorMock, 'onError'],
- 'onSuccess' => [$onSuccessMock, 'onSuccess'],
- ]);
- }
- private function transferException(string $methodName): void
- {
- // It has to be 2 responses because of the retry mechanism
- $mockHandler = new MockHandler([
- new TransferException('TransferException message'),
- new TransferException('TransferException message'),
- ]);
- $container = [];
- $guzzleHttpClient = $this->getGuzzleHttpClient(
- $mockHandler,
- $container
- );
- $onSuccessMock = $this
- ->getMockBuilder(\stdClass::class)
- ->setMethods(['onSuccess'])
- ->getMock();
- $onErrorMock = $this
- ->getMockBuilder(\stdClass::class)
- ->setMethods(['onError'])
- ->getMock();
- $notifierClient = new Client([
- 'guzzleHttpClient' => $guzzleHttpClient,
- 'apiKey' => 'test-api-key',
- ]);
- $message = [
- 'key' => 'value',
- ];
- $onSuccessMock
- ->expects(self::never())
- ->method('onSuccess');
- $onErrorMock
- ->expects(self::once())
- ->method('onError')
- ->with(self::equalTo('TransferException message'));
- $notifierClient->{$methodName}([
- 'templateId' => 'welcome',
- 'message' => $message,
- 'onError' => [$onErrorMock, 'onError'],
- 'onSuccess' => [$onSuccessMock, 'onSuccess'],
- ]);
- }
- private function clientError(string $methodName): void
- {
- $response = [
- 'code' => 'some code',
- 'message' => 'response message',
- ];
- $mockHandler = new MockHandler([
- new Response(401, [], json_encode($response)),
- ]);
- $container = [];
- $guzzleHttpClient = $this->getGuzzleHttpClient(
- $mockHandler,
- $container
- );
- $onErrorMock = $this
- ->getMockBuilder(\stdClass::class)
- ->setMethods(['onError'])
- ->getMock();
- $notifierClient = new Client([
- 'guzzleHttpClient' => $guzzleHttpClient,
- 'apiKey' => 'test-api-key',
- ]);
- $message = [
- 'key' => 'value',
- ];
- $onErrorMock
- ->expects(self::once())
- ->method('onError')
- ->with(self::equalTo($response['message']));
- $notifierClient->{$methodName}([
- 'templateId' => 'welcome',
- 'message' => $message,
- 'onError' => [$onErrorMock, 'onError'],
- ]);
- }
- private function responselessException(string $methodName): void
- {
- // It has to be 2 responses because of the retry mechanism
- $mockHandler = new MockHandler([
- new RequestException(
- 'RequestException message',
- new Request('POST', '/email')
- ),
- new RequestException(
- 'RequestException message',
- new Request('POST', '/email')
- ),
- ]);
- $container = [];
- $guzzleHttpClient = $this->getGuzzleHttpClient(
- $mockHandler,
- $container
- );
- $onErrorMock = $this
- ->getMockBuilder(\stdClass::class)
- ->setMethods(['onError'])
- ->getMock();
- $notifierClient = new Client([
- 'guzzleHttpClient' => $guzzleHttpClient,
- 'apiKey' => 'test-api-key',
- ]);
- $message = [
- 'key' => 'value',
- ];
- $onErrorMock
- ->expects(self::once())
- ->method('onError')
- ->with(self::equalTo('RequestException message'));
- $notifierClient->{$methodName}([
- 'templateId' => 'welcome',
- 'message' => $message,
- 'onError' => [$onErrorMock, 'onError'],
- ]);
- }
- }