diff --git a/.gitignore b/.gitignore index 7579f74..bd4ac31 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ +tests/cases/**/output +tests/tmp vendor +coverage.xml composer.lock diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b498dcd --- /dev/null +++ b/.travis.yml @@ -0,0 +1,52 @@ +language: php +php: + - 7.2 + - 7.3 + - 7.4 + +before_install: + # Turn off XDebug + - phpenv config-rm xdebug.ini || return 0 + +install: + # Composer + - travis_retry composer install --no-interaction --no-progress --prefer-dist + +script: + # Tests + - composer test + +after_failure: + # Print *.actual content + - for i in $(find tests -name \*.actual); do echo "--- $i"; cat $i; echo; echo; done + +jobs: + include: + - env: title="Lowest Dependencies 7.2" + php: 7.2 + install: + - travis_retry composer update --no-interaction --no-progress --prefer-dist --prefer-lowest + script: + - composer test + + - stage: cs + php: 7.4 + script: + - composer cs + +# - stage: Test Coverage +# if: branch = master AND type = push +# script: +# - composer coverage +# after_script: +# - wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.2.0/php-coveralls.phar +# - php php-coveralls.phar --verbose --config .coveralls.yml +# +# allow_failures: +# - stage: Test Coverage + +sudo: false + +cache: + directories: + - $HOME/.composer/cache diff --git a/Makefile b/Makefile index ba00e51..67f0dd2 100644 --- a/Makefile +++ b/Makefile @@ -2,4 +2,13 @@ vendor/autoload.php: composer install sniff: vendor/autoload.php - vendor/bin/phpcs --standard=PSR2 src -n --ignore=src/errbit-php \ No newline at end of file + composer cs + +sniff-fix: vendor/autoload.php + composer cs-fix + +test: vendor/autoload.php + composer test + +coverage: vendor/autoload.php + composer coverage diff --git a/composer.json b/composer.json index a80d385..b024c44 100644 --- a/composer.json +++ b/composer.json @@ -11,20 +11,30 @@ ], "type": "library", "require": { - "ext-iconv":"*", - "php": "^7.1", - "sentry/sdk": "^2.1", - "tracy/tracy": "~2.4", - "nette/di": "^2.4 || ^3.0", + "php": "^7.2", + "nette/di": "^2.4.7 || ^3.0", + "nette/http": "^2.4.7 || ^3.0", "nette/security": "^2.4 || ^3.0", - "nette/http": "^2.4 || ^3.0" + "nette/utils": "^2.4.5 || ^3.0", + "sentry/sdk": "^3.0", + "tracy/tracy": "^2.4" }, "require-dev": { + "ninjify/nunjuck": "^0.3", "squizlabs/php_codesniffer": "~3.5" }, "autoload": { "psr-4": { "Rootpd\\NetteSentry\\": "src" } + }, + "config": { + "sort-packages": true + }, + "scripts": { + "cs": "phpcs --standard=PSR2 --extensions=php,phpt src tests --ignore=tests/tmp", + "cs-fix": "phpcbf --standard=PSR2 --extensions=php,phpt src tests --ignore=tests/tmp", + "test": "tester -C tests", + "coverage": "tester -p phpdbg -C --coverage coverage.xml --coverage-src src tests" } } diff --git a/src/DI/SentryExtension.php b/src/DI/SentryExtension.php index e60112d..ea72816 100644 --- a/src/DI/SentryExtension.php +++ b/src/DI/SentryExtension.php @@ -5,6 +5,8 @@ namespace Rootpd\NetteSentry\DI; use Nette\DI\CompilerExtension; +use Nette\PhpGenerator\ClassType; +use Rootpd\NetteSentry\SentryLogger; use Tracy\Debugger; use Tracy\ILogger; @@ -35,7 +37,7 @@ public function loadConfiguration() $this->getContainerBuilder() ->addDefinition($this->prefix('logger')) - ->setFactory(\Rootpd\NetteSentry\SentryLogger::class) + ->setFactory(SentryLogger::class, [Debugger::$logDirectory]) ->addSetup( 'register', [ @@ -75,7 +77,7 @@ public function beforeCompile() } } - public function afterCompile(\Nette\PhpGenerator\ClassType $class) + public function afterCompile(ClassType $class) { if (!$this->enabled) { return; diff --git a/src/SentryLogger.php b/src/SentryLogger.php index dcf8760..2fea76f 100644 --- a/src/SentryLogger.php +++ b/src/SentryLogger.php @@ -7,16 +7,18 @@ use Nette\Http\Session; use Nette\Security\IIdentity; use Nette\Security\User; -use Sentry\ClientBuilder; use Sentry\Integration\RequestIntegration; use Sentry\Severity; -use Sentry\State\Hub; +use Sentry\State\Scope; +use Throwable; use Tracy\Debugger; +use Tracy\Dumper; use Tracy\ILogger; use Tracy\Logger; use function Sentry\captureException; use function Sentry\captureMessage; use function Sentry\configureScope; +use function Sentry\init; class SentryLogger extends Logger { @@ -34,27 +36,24 @@ class SentryLogger extends Logger public function register(string $dsn, string $environment) { - $options = new \Sentry\Options([ + init([ 'dsn' => $dsn, 'environment' => $environment, 'default_integrations' => false, + 'integrations' => [ + new RequestIntegration(), + ], ]); - $options->setIntegrations([ - new RequestIntegration($options), - ]); - - $builder = new ClientBuilder($options); - $client = $builder->getClient(); - Hub::setCurrent(new Hub($client)); - $this->email = & Debugger::$email; $this->directory = Debugger::$logDirectory; } public function setUser(User $user) { - $this->identity = $user->getIdentity(); + if ($user->isLoggedIn()) { + $this->identity = $user->getIdentity(); + } } public function setUserFields(array $userFields) @@ -89,7 +88,7 @@ public function log($value, $priority = ILogger::INFO) return $response; } - configureScope(function (\Sentry\State\Scope $scope) use ($severity) { + configureScope(function (Scope $scope) use ($severity) { if (!$severity) { return; } @@ -114,10 +113,10 @@ public function log($value, $priority = ILogger::INFO) } }); - if ($value instanceof \Throwable) { + if ($value instanceof Throwable) { captureException($value); } else { - captureMessage($value); + captureMessage(is_string($value) ? $value : Dumper::toText($value)); } return $response; diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..aa80ed9 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,10 @@ + 'https://123abc123abc123abc123abc123abc12@sentry.io/3', + ]; + + $loader = new ContainerLoader(TEMP_DIR, true); + $class = $loader->load(function (Compiler $compiler) use ($config): void { + $compiler->addExtension('sentry', new SentryExtension()) + ->addConfig([ + 'sentry' => $config, + ]); + }, 1); + + /** @var Container $container */ + $container = new $class(); + + /** @var SentryLogger $logger */ + $logger = $container->getService('sentry.logger'); + + Assert::type(SentryLogger::class, $logger); + + Assert::with($logger, function () use ($config): void { + Assert::null($this->session); + + Assert::null($this->identity); + + Assert::same([], $this->userFields); + + Assert::same([], $this->priorityMapping); + }); +}); + +// complex config +test(function (): void { + $config = [ + 'dsn' => 'https://123abc123abc123abc123abc123abc12@sentry.io/3', + 'environment' => 'test', + 'user_fields' => [ + 'email', + ], + 'priority_mapping' => [ + 'mypriority' => 'warning', + ] + ]; + + $loader = new ContainerLoader(TEMP_DIR, true); + $class = $loader->load(function (Compiler $compiler) use ($config): void { + $compiler->addExtension('http', new HttpExtension()); + $compiler->addExtension('security', new SecurityExtension()); + $compiler->addExtension('session', new SessionExtension()); + + $compiler->addExtension('sentry', new SentryExtension()) + ->addConfig([ + 'sentry' => $config, + ]); + }, 2); + + /** @var Container $container */ + $container = new $class(); + + $user = $container->getByType(User::class); + $identity = new Identity(1, null, ['email' => '']); + $user->login($identity); + + /** @var SentryLogger $logger */ + $logger = $container->getService('sentry.logger'); + + Assert::type(SentryLogger::class, $logger); + + Assert::with($logger, function () use ($config, $identity): void { + Assert::type(Session::class, $this->session); + + Assert::type(IIdentity::class, $this->identity); + Assert::same($identity, $this->identity); + + Assert::same($config['user_fields'], $this->userFields); + + Assert::same($config['priority_mapping'], $this->priorityMapping); + }); +});