Skip to content

Commit

Permalink
minor #34549 [Notifier] Add Slack bridge tests (Jeroeny)
Browse files Browse the repository at this point in the history
This PR was squashed before being merged into the 5.0 branch (closes #34549).

Discussion
----------

[Notifier] Add Slack bridge tests

| Q             | A
| ------------- | ---
| Branch?       | 5.0
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Tickets       | See #33687
| License       | MIT

Adds tests for the Slack bridge of the Notifier component.

#SymfonyHackday

Commits
-------

626fdaa [Notifier] Add Slack bridge tests
  • Loading branch information
fabpot committed Nov 30, 2019
2 parents bb11cac + 626fdaa commit 0be4647
Show file tree
Hide file tree
Showing 3 changed files with 272 additions and 0 deletions.
@@ -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'));
}
}
@@ -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'));
}
}
3 changes: 3 additions & 0 deletions src/Symfony/Component/Notifier/Bridge/Slack/composer.json
Expand Up @@ -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": [
Expand Down

0 comments on commit 0be4647

Please sign in to comment.