Skip to content

Drop the phpspec/prophecy dev dependency #770

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 24, 2023
Merged
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
3 changes: 0 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@
"doctrine/dbal": "^2.13||^3.0",
"doctrine/doctrine-bundle": "^1.12||^2.5",
"friendsofphp/php-cs-fixer": "^2.19||<=3.16.0",
"jangregor/phpstan-prophecy": "^1.0",
"monolog/monolog": "^1.3||^2.0",
"phpspec/prophecy": "!=1.11.0",
"phpspec/prophecy-phpunit": "^1.1||^2.0",
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "^1.3",
"phpstan/phpstan-phpunit": "^1.0",
Expand Down
38 changes: 28 additions & 10 deletions src/Command/SentryTestCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,37 @@
namespace Sentry\SentryBundle\Command;

use Sentry\SentrySdk;
use Sentry\State\HubInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
* @final since version 4.12
*/
class SentryTestCommand extends Command
{
/**
* @var HubInterface
*/
private $hub;

public function __construct(?HubInterface $hub = null)
{
parent::__construct();

if (null === $hub) {
@trigger_error(sprintf('Not passing an instance of the "%s" interface as argument of the constructor is deprecated since version 4.12 and will not work since version 5.0.', HubInterface::class), \E_USER_DEPRECATED);
}

$this->hub = $hub ?? SentrySdk::getCurrentHub();
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$currentHub = SentrySdk::getCurrentHub();
$client = $currentHub->getClient();
$client = $this->hub->getClient();

if (!$client) {
if (null === $client) {
$output->writeln('<error>No client found</error>');
$output->writeln('<info>Your DSN is probably missing, check your configuration</info>');

Expand All @@ -25,28 +44,27 @@ protected function execute(InputInterface $input, OutputInterface $output): int

$dsn = $client->getOptions()->getDsn();

if ($dsn) {
$output->writeln('<info>DSN correctly configured in the current client</info>');
} else {
if (null === $dsn) {
$output->writeln('<error>No DSN configured in the current client, please check your configuration</error>');
$output->writeln('<info>To debug further, try bin/console debug:config sentry</info>');

return 1;
}

$output->writeln('<info>DSN correctly configured in the current client</info>');
$output->writeln('Sending test message...');

$eventId = $currentHub->captureMessage('This is a test message from the Sentry bundle');
$eventId = $this->hub->captureMessage('This is a test message from the Sentry bundle');

if ($eventId) {
$output->writeln("<info>Message sent successfully with ID $eventId</info>");
} else {
if (null === $eventId) {
$output->writeln('<error>Message not sent!</error>');
$output->writeln('<warning>Check your DSN or your before_send callback if used</warning>');

return 1;
}

$output->writeln("<info>Message sent successfully with ID $eventId</info>");

return 0;
}
}
2 changes: 2 additions & 0 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@
</service>

<service id="Sentry\SentryBundle\Command\SentryTestCommand" class="Sentry\SentryBundle\Command\SentryTestCommand">
<argument type="service" id="Sentry\State\HubInterface" />

<tag name="console.command" command="sentry:test" />
</service>

Expand Down
24 changes: 0 additions & 24 deletions tests/BaseTestCase.php

This file was deleted.

165 changes: 85 additions & 80 deletions tests/Command/SentryTestCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,129 +4,134 @@

namespace Sentry\SentryBundle\Tests\Command;

use Prophecy\Argument;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Sentry\ClientInterface;
use Sentry\EventId;
use Sentry\Options;
use Sentry\SentryBundle\Command\SentryTestCommand;
use Sentry\SentryBundle\Tests\BaseTestCase;
use Sentry\SentrySdk;
use Sentry\State\HubInterface;
use Symfony\Component\Console\Application;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Symfony\Component\Console\Tester\CommandTester;

class SentryTestCommandTest extends BaseTestCase
final class SentryTestCommandTest extends TestCase
{
protected function tearDown(): void
use ExpectDeprecationTrait;

/**
* @var HubInterface&MockObject
*/
private $hub;

/**
* @var ClientInterface&MockObject
*/
private $client;

/**
* @var CommandTester
*/
private $command;

protected function setUp(): void
{
parent::tearDown();
parent::setUp();

// reset current Hub to avoid leaking the mock outside of this tests
SentrySdk::init();
$this->hub = $this->createMock(HubInterface::class);
$this->client = $this->createMock(ClientInterface::class);
$this->command = new CommandTester(new SentryTestCommand($this->hub));
}

public function testExecuteSuccessfully(): void
public function testExecute(): void
{
$options = new Options(['dsn' => 'http://public:[email protected]/sentry/1']);
$client = $this->prophesize(ClientInterface::class);
$client->getOptions()
->willReturn($options);

$hub = $this->prophesize(HubInterface::class);
$hub->getClient()
->willReturn($client->reveal());
$lastEventId = EventId::generate();
$hub->captureMessage(Argument::containingString('test'), Argument::cetera())
->shouldBeCalled()
->willReturn($lastEventId);

SentrySdk::setCurrentHub($hub->reveal());
$this->client->expects($this->once())
->method('getOptions')
->willReturn(new Options(['dsn' => 'https://public:[email protected]/sentry/1']));

$this->hub->expects($this->once())
->method('getClient')
->willReturn($this->client);

$this->hub->expects($this->once())
->method('captureMessage')
->with('This is a test message from the Sentry bundle')
->willReturn($lastEventId);

$commandTester = $this->executeCommand();
$exitCode = $this->command->execute([]);
$output = $this->command->getDisplay();

$output = $commandTester->getDisplay();
$this->assertStringContainsString('DSN correctly configured', $output);
$this->assertStringContainsString('Sending test message', $output);
$this->assertStringContainsString('Message sent', $output);
$this->assertStringContainsString((string) $lastEventId, $output);
$this->assertSame(0, $commandTester->getStatusCode());
$this->assertSame(0, $exitCode);
$this->assertStringContainsString('DSN correctly configured in the current client', $output);
$this->assertStringContainsString('Sending test message...', $output);
$this->assertStringContainsString("Message sent successfully with ID $lastEventId", $output);
}

public function testExecuteFailsDueToMissingDSN(): void
{
$client = $this->prophesize(ClientInterface::class);
$client->getOptions()
$this->client->expects($this->once())
->method('getOptions')
->willReturn(new Options());

$hub = $this->prophesize(HubInterface::class);
$hub->getClient()
->willReturn($client->reveal());
$this->hub->expects($this->once())
->method('getClient')
->willReturn($this->client);

SentrySdk::setCurrentHub($hub->reveal());
$exitCode = $this->command->execute([]);
$output = $this->command->getDisplay();

$commandTester = $this->executeCommand();

$this->assertNotSame(0, $commandTester->getStatusCode());
$output = $commandTester->getDisplay();
$this->assertStringContainsString('No DSN configured', $output);
$this->assertStringContainsString('try bin/console debug:config sentry', $output);
$this->assertSame(1, $exitCode);
$this->assertStringContainsString('No DSN configured in the current client, please check your configuration', $output);
$this->assertStringContainsString('To debug further, try bin/console debug:config sentry', $output);
}

public function testExecuteFailsDueToMessageNotSent(): void
{
$options = new Options(['dsn' => 'http://public:[email protected]/sentry/1']);
$client = $this->prophesize(ClientInterface::class);
$client->getOptions()
->willReturn($options);

$hub = $this->prophesize(HubInterface::class);
$hub->getClient()
->willReturn($client->reveal());
$hub->captureMessage(Argument::containingString('test'), Argument::cetera())
->shouldBeCalled()
->willReturn(null);
$this->client->expects($this->once())
->method('getOptions')
->willReturn(new Options(['dsn' => 'https://public:[email protected]/sentry/1']));

SentrySdk::setCurrentHub($hub->reveal());
$this->hub->expects($this->once())
->method('getClient')
->willReturn($this->client);

$this->hub->expects($this->once())
->method('captureMessage')
->with('This is a test message from the Sentry bundle')
->willReturn(null);

$commandTester = $this->executeCommand();
$exitCode = $this->command->execute([]);
$output = $this->command->getDisplay();

$this->assertNotSame(0, $commandTester->getStatusCode());
$output = $commandTester->getDisplay();
$this->assertStringContainsString('DSN correctly configured', $output);
$this->assertStringContainsString('Sending test message', $output);
$this->assertStringContainsString('Message not sent', $output);
$this->assertSame(1, $exitCode);
$this->assertStringContainsString('DSN correctly configured in the current client', $output);
$this->assertStringContainsString('Sending test message...', $output);
$this->assertStringContainsString('Message not sent!', $output);
$this->assertStringContainsString('Check your DSN or your before_send callback if used', $output);
}

public function testExecuteFailsDueToMissingClient(): void
{
$hub = $this->prophesize(HubInterface::class);
$hub->getClient()
$this->hub->expects($this->once())
->method('getClient')
->willReturn(null);

SentrySdk::setCurrentHub($hub->reveal());
$exitCode = $this->command->execute([]);
$output = $this->command->getDisplay();

$commandTester = $this->executeCommand();

$this->assertNotSame(0, $commandTester->getStatusCode());
$output = $commandTester->getDisplay();
$this->assertSame(1, $exitCode);
$this->assertStringContainsString('No client found', $output);
$this->assertStringContainsString('DSN is probably missing', $output);
$this->assertStringContainsString('Your DSN is probably missing, check your configuration', $output);
}

private function executeCommand(): CommandTester
/**
* @group legacy
*/
public function testConstructorTriggersDeprecationErrorIfHubIsNotPassedToConstructor(): void
{
$command = new SentryTestCommand();
$command->setName('sentry:test');

$application = new Application();
$application->add($command);

$command = $application->find('sentry:test');
$commandTester = new CommandTester($command);
$commandTester->execute([
'command' => $command->getName(),
]);
$this->expectDeprecation('Not passing an instance of the "Sentry\State\HubInterface" interface as argument of the constructor is deprecated since version 4.12 and will not work since version 5.0.');

return $commandTester;
new SentryTestCommand();
}
}