Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ phpunit.xml
vendor
.phpunit.result.cache
node_modules
test/coverage
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
"@auto-scripts"
],
"serve": "php -S 0.0.0.0:8000 -t test/sandbox/public test/sandbox/public/router.php",
"test": "phpunit"
"test": "vendor/bin/phpunit",
"test-html": "vendor/bin/phpunit --coverage-html=test/coverage",
"test-text": "vendor/bin/phpunit --coverage-text",
"test-clover": "vendor/bin/phpunit --coverage-clover=coverage.clover.xml",
"lint": "vendor/bin/phpcs -v --standard=phpcs.xml src/*"
}
}
11 changes: 8 additions & 3 deletions src/Listener/SendSentryEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,25 @@
use Sentry\State\Scope;

/**
* TODO: description
* Listener to send events to a Sentry instance upon MVC error events.
*
* @author Mathias Gelhausen
* TODO: write tests
*/
class SendSentryEvent implements ListenerAggregateInterface
{
use ListenerAggregateTrait;

// phpcs:ignore

// phpcs:disable
/**
* @var arrray[]
* @see ListenerAggregateTrait
*/
private $events = [
[MvcEvent::EVENT_DISPATCH_ERROR, 'execute', -100],
[MvcEvent::EVENT_RENDER_ERROR, 'execute', -100],
];
// phpcs:enable

/** @var HubInterface */
private $hub;
Expand Down
1 change: 0 additions & 1 deletion src/Listener/SendSentryEventFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
* Factory for \YkSentry\Listener\SendSentryEvent
*
* @author Mathias Gelhausen
* TODO: write tests
*/
class SendSentryEventFactory
{
Expand Down
5 changes: 1 addition & 4 deletions src/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,13 @@
use YkSentry\Options\ModuleOptions;

/**
* TODO: description
*
* @author Mathias Gelhausen
* TODO: write tests
*/
class Module implements BootstrapListenerInterface, ConfigProviderInterface, VersionProviderInterface
{
use VersionProviderTrait;

const VERSION = '0.1.0';
public const VERSION = '0.1.0';

public function getConfig()
{
Expand Down
6 changes: 1 addition & 5 deletions src/Options/ModuleOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,13 @@
* TODO: description
*
* @author Mathias Gelhausen
* TODO: write tests
*/
class ModuleOptions extends AbstractOptions
{

/** @var bool */
private $isEnabled = true;

/**
* @var array
*/
/** @var array */
private $sentryConfig = [];

/**
Expand Down
1 change: 0 additions & 1 deletion src/Service/SentryClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
* Factory for creating a Sentry client interface instance.
*
* @author Mathias Gelhausen
* TODO: write tests
*/
class SentryClientFactory
{
Expand Down
1 change: 0 additions & 1 deletion src/Service/SentryHubFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
* Factory for creating a sentry Hub instance
*
* @author Mathias Gelhausen
* TODO: write tests
*/
class SentryHubFactory
{
Expand Down
43 changes: 43 additions & 0 deletions test/src/Listener/SendSentryEventFactoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

/**
* YAWIK Sentry Integration
*
* @see https://github.com/yawik/sentry for the canonical source repository
* @copyright https://github.com/yawik/sentry/blob/master/COPYRIGHT
* @license https://github.com/yawik/sentry/blob/master/LICENSE
*/

declare(strict_types=1);

namespace YkSentryTest\Listener;

use Cross\TestUtils\TestCase\ContainerDoubleTrait;
use PHPUnit\Framework\TestCase;
use Sentry\State\HubInterface;
use YkSentry\Listener\SendSentryEvent;
use YkSentry\Listener\SendSentryEventFactory;

/**
* Tests for \YkSentry\Listener\SendSentryEventFactory
*
* @author Mathias Gelhausen
* @covers \YkSentry\Listener\SendSentryEventFactory
*/
class SendSentryEventFactoryTest extends TestCase
{

use ContainerDoubleTrait;

public function testCreatesListener()
{
$hub = $this->prophesize(HubInterface::class);
$container = $this->createContainerDouble([
HubInterface::class => [$hub->reveal(), 1]
]);

$listener = (new SendSentryEventFactory())($container, 'irrelevant');

static::assertInstanceOf(SendSentryEvent::class, $listener);
}
}
183 changes: 183 additions & 0 deletions test/src/Listener/SendSentryEventTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
<?php

/**
* YAWIK Sentry Integration
*
* @see https://github.com/yawik/sentry for the canonical source repository
* @copyright https://github.com/yawik/sentry/blob/master/COPYRIGHT
* @license https://github.com/yawik/sentry/blob/master/LICENSE
*/

declare(strict_types=1);

namespace YkSentryTest\Listener;

use Core\EventManager\ListenerAggregateTrait;
use Cross\TestUtils\TestCase\SetupTargetTrait;
use Cross\TestUtils\TestCase\TestInheritanceTrait;
use Cross\TestUtils\TestCase\TestUsesTraitsTrait;
use Laminas\EventManager\EventManagerInterface;
use Laminas\EventManager\ListenerAggregateInterface;
use Laminas\Mvc\Application;
use Laminas\Mvc\MvcEvent;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Sentry\Event;
use Sentry\Severity;
use Sentry\State\HubInterface;
use Sentry\State\Scope;
use YkSentry\Listener\SendSentryEvent;

/**
* Tests for \YkSentry\Listener\SendSentryEvent
*
* @author Mathias Gelhausen
* @covers \YkSentry\Listener\SendSentryEvent
*/
class SendSentryEventTest extends TestCase
{
use SetupTargetTrait, TestInheritanceTrait, TestUsesTraitsTrait;

/**
* @var array|SendSentryEvent
*/
private $target = [
'create' => [
[
'for' => ['testInheritance', 'testUsesTraits'],
'reflection' => SendSentryEvent::class,
],
[
'callback' => 'createTarget',
]
]
];

private $inheritance = [ ListenerAggregateInterface::class ];

private $usesTraits = [ ListenerAggregateTrait::class ];

/**
* Test double for the sentry hub
* @var \Prophecy\Prophecy\ObjectProphecy
*/
private $hub;

private function createTarget()
{
$this->hub = $this->prophesize(HubInterface::class);

return [SendSentryEvent::class, $this->hub->reveal()];
}

public function testRegistersToTheCorrectEventsWithCorrectPriority()
{
$events = $this->prophesize(EventManagerInterface::class);
$events
->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this->target, 'execute'], -100)
->willReturn('handle1')
->shouldBeCalled()
;
$events
->attach(MvcEvent::EVENT_RENDER_ERROR, [$this->target, 'execute'], -100)
->willReturn('handle2')
->shouldBeCalled()
;

$this->target->attach($events->reveal());
}

public function testScopeIsConfiguredCorrectlyForExceptionErrors()
{
$exception = new \Exception('dummyexception');

$event = new MvcEvent();
$event->setError(Application::ERROR_EXCEPTION);
$event->setParam('exception', $exception);

$this->hub->configureScope(Argument::that(function ($cb) {
$scope = new Scope();
$event = new Event();
$cb($scope);
$scope->applyToEvent($event, []);
$tags = $event->getTagsContext();
$level = $event->getLevel()->__toString();

return
isset($tags['type'])
&& $tags['type'] === Application::ERROR_EXCEPTION
&& $level === Severity::ERROR
;
}))->shouldBeCalled();

$this->hub->captureException(Argument::any());

$this->target->execute($event);
}

public function testScopeIsConfiguredCorrectlyForRouteNotMatchErrors()
{
$event = new MvcEvent();
$event->setError(Application::ERROR_ROUTER_NO_MATCH);

$this->hub->configureScope(Argument::that(function ($cb) {
$scope = new Scope();
$event = new Event();
$cb($scope);
$scope->applyToEvent($event, []);
$tags = $event->getTagsContext();
$level = $event->getLevel()->__toString();

return
isset($tags['type'])
&& $tags['type'] === Application::ERROR_ROUTER_NO_MATCH
&& $level === Severity::WARNING
;
}))->shouldBeCalled();

$this->hub->captureMessage(Argument::any());

$this->target->execute($event);
}

public function testSendExceptionEvent()
{
$exception = new \Exception('Test Exception');

$event = new MvcEvent();
$event->setError(Application::ERROR_EXCEPTION);
$event->setParam('exception', $exception);

$this->hub->configureScope(Argument::any());
$this->hub->captureException(Argument::is($exception))->shouldBeCalled();

$this->target->execute($event);
}

public function provideSendMessageEventTestData()
{
return [
[Application::ERROR_CONTROLLER_CANNOT_DISPATCH, 'Controller can not be dispatched.'],
[Application::ERROR_CONTROLLER_INVALID, 'Invalid controller invoked.'],
[Application::ERROR_CONTROLLER_NOT_FOUND, 'Controller can not be found.'],
[Application::ERROR_MIDDLEWARE_CANNOT_DISPATCH, 'Middleware can not be dispatched'],
[Application::ERROR_ROUTER_NO_MATCH, 'No route matched.'],
['unknown', 'An unknown error occured.'],
];
}

/**
* @dataProvider provideSendMessageEventTestData()
*/
public function testSendMessageEvent($error, $expectedMessage)
{
$event = new MvcEvent();
$event->setError($error);

$this->hub->configureScope(Argument::any());
$this->hub->captureException(Argument::any())->shouldNotBeCalled();
$this->hub->captureMessage($expectedMessage)->shouldBeCalled();

$this->target->execute($event);
}
}
Loading