[Notifier] Add Slack bridge tests

This commit is contained in:
Jeroeny 2019-11-23 15:02:30 +01:00 committed by Fabien Potencier
parent 255f557a30
commit 626fdaa9a4
3 changed files with 272 additions and 0 deletions

View File

@ -0,0 +1,57 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Notifier\Bridge\Slack\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Notifier\Bridge\Slack\SlackTransportFactory;
use Symfony\Component\Notifier\Exception\IncompleteDsnException;
use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\Dsn;
final class SlackTransportFactoryTest extends TestCase
{
public function testCreateWithDsn(): void
{
$factory = new SlackTransportFactory();
$host = 'testHost';
$channel = 'testChannel';
$transport = $factory->create(Dsn::fromString(sprintf('slack://testUser@%s/?channel=%s', $host, $channel)));
$this->assertSame(sprintf('slack://%s?channel=%s', $host, $channel), (string) $transport);
}
public function testCreateWithNoTokenThrowsMalformed(): void
{
$factory = new SlackTransportFactory();
$this->expectException(IncompleteDsnException::class);
$factory->create(Dsn::fromString(sprintf('slack://%s/?channel=%s', 'testHost', 'testChannel')));
}
public function testSupportsSlackScheme(): void
{
$factory = new SlackTransportFactory();
$this->assertTrue($factory->supports(Dsn::fromString('slack://host/?channel=testChannel')));
$this->assertFalse($factory->supports(Dsn::fromString('somethingElse://host/?channel=testChannel')));
}
public function testNonSlackSchemeThrows(): void
{
$factory = new SlackTransportFactory();
$this->expectException(UnsupportedSchemeException::class);
$factory->create(Dsn::fromString('somethingElse://user:pwd@host/?channel=testChannel'));
}
}

View File

@ -0,0 +1,212 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Notifier\Bridge\Slack\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\Notifier\Bridge\Slack\SlackOptions;
use Symfony\Component\Notifier\Bridge\Slack\SlackTransport;
use Symfony\Component\Notifier\Exception\LogicException;
use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\MessageOptionsInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\Recipient;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
final class SlackTransportTest extends TestCase
{
public function testToStringContainsProperties(): void
{
$host = 'testHost';
$channel = 'testChannel';
$transport = new SlackTransport('testToken', $channel, $this->createMock(HttpClientInterface::class));
$transport->setHost('testHost');
$this->assertSame(sprintf('slack://%s?channel=%s', $host, $channel), (string) $transport);
}
public function testSupportsChatMessage(): void
{
$transport = new SlackTransport('testToken', 'testChannel', $this->createMock(HttpClientInterface::class));
$this->assertTrue($transport->supports(new ChatMessage('testChatMessage')));
$this->assertFalse($transport->supports($this->createMock(MessageInterface::class)));
}
public function testSendNonChatMessageThrows(): void
{
$this->expectException(LogicException::class);
$transport = new SlackTransport('testToken', 'testChannel', $this->createMock(HttpClientInterface::class));
$transport->send($this->createMock(MessageInterface::class));
}
public function testSendWithEmptyArrayResponseThrows(): void
{
$this->expectException(TransportException::class);
$response = $this->createMock(ResponseInterface::class);
$response->expects($this->exactly(2))
->method('getStatusCode')
->willReturn(500);
$response->expects($this->once())
->method('getContent')
->willReturn('[]');
$client = new MockHttpClient(static function () use ($response): ResponseInterface {
return $response;
});
$transport = new SlackTransport('testToken', 'testChannel', $client);
$transport->send(new ChatMessage('testMessage'));
}
public function testSendWithErrorResponseThrows(): void
{
$this->expectException(TransportException::class);
$this->expectExceptionMessageRegExp('/testErrorCode/');
$response = $this->createMock(ResponseInterface::class);
$response->expects($this->exactly(2))
->method('getStatusCode')
->willReturn(400);
$response->expects($this->once())
->method('getContent')
->willReturn(json_encode(['error' => 'testErrorCode']));
$client = new MockHttpClient(static function () use ($response): ResponseInterface {
return $response;
});
$transport = new SlackTransport('testToken', 'testChannel', $client);
$transport->send(new ChatMessage('testMessage'));
}
public function testSendWithOptions(): void
{
$token = 'testToken';
$channel = 'testChannel';
$message = 'testMessage';
$response = $this->createMock(ResponseInterface::class);
$response->expects($this->exactly(2))
->method('getStatusCode')
->willReturn(200);
$response->expects($this->once())
->method('getContent')
->willReturn(json_encode(['ok' => true]));
$expectedBody = sprintf('token=%s&channel=%s&text=%s', $token, $channel, $message);
$client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response, $expectedBody): ResponseInterface {
$this->assertSame($expectedBody, $options['body']);
return $response;
});
$transport = new SlackTransport($token, $channel, $client);
$transport->send(new ChatMessage('testMessage'));
}
public function testSendWithNotification(): void
{
$token = 'testToken';
$channel = 'testChannel';
$message = 'testMessage';
$response = $this->createMock(ResponseInterface::class);
$response->expects($this->exactly(2))
->method('getStatusCode')
->willReturn(200);
$response->expects($this->once())
->method('getContent')
->willReturn(json_encode(['ok' => true]));
$notification = new Notification($message);
$chatMessage = ChatMessage::fromNotification($notification, new Recipient('test-email@example.com'));
$options = SlackOptions::fromNotification($notification);
$expectedBody = http_build_query([
'blocks' => $options->toArray()['blocks'],
'token' => $token,
'channel' => $channel,
'text' => $message,
]);
$client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response, $expectedBody): ResponseInterface {
$this->assertSame($expectedBody, $options['body']);
return $response;
});
$transport = new SlackTransport($token, $channel, $client);
$transport->send($chatMessage);
}
public function testSendWithInvalidOptions(): void
{
$this->expectException(LogicException::class);
$client = new MockHttpClient(function (string $method, string $url, array $options = []): ResponseInterface {
return $this->createMock(ResponseInterface::class);
});
$transport = new SlackTransport('testToken', 'testChannel', $client);
$transport->send(new ChatMessage('testMessage', $this->createMock(MessageOptionsInterface::class)));
}
public function testSendWith200ResponseButNotOk(): void
{
$token = 'testToken';
$channel = 'testChannel';
$message = 'testMessage';
$this->expectException(TransportException::class);
$response = $this->createMock(ResponseInterface::class);
$response->expects($this->exactly(2))
->method('getStatusCode')
->willReturn(200);
$response->expects($this->once())
->method('getContent')
->willReturn(json_encode(['ok' => false, 'error' => 'testErrorCode']));
$expectedBody = sprintf('token=%s&channel=%s&text=%s', $token, $channel, $message);
$client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response, $expectedBody): ResponseInterface {
$this->assertSame($expectedBody, $options['body']);
return $response;
});
$transport = new SlackTransport($token, $channel, $client);
$transport->send(new ChatMessage('testMessage'));
}
}

View File

@ -20,6 +20,9 @@
"symfony/http-client": "^4.3|^5.0",
"symfony/notifier": "~5.0.0"
},
"require-dev": {
"symfony/event-dispatcher": "^4.3|^5.0"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Notifier\\Bridge\\Slack\\": "" },
"exclude-from-classmap": [