create(['email' => 'kunde@example.com']); $this->actingAs($user); report(new RuntimeException('Import für kunde@example.com fehlgeschlagen')); expect($glitchTip->events)->toHaveCount(1); $event = $glitchTip->events[0]; expect($event->getUser()?->getId())->toBe($user->id) ->and($event->getUser()?->getEmail())->toBeNull() ->and($event->getExceptions()[0]->getValue())->toBe('Import für [email] fehlgeschlagen'); }); test('exceptions laravel does not report stay out of glitchtip', function () { $glitchTip = FakeGlitchTip::install(); $this->get('/diese-seite-gibt-es-nicht')->assertNotFound(); expect($glitchTip->events)->toBe([]); }); test('a mistyped artisan command is not reported', function () { $glitchTip = FakeGlitchTip::install(); report(new CommandNotFoundException('Command "config:cachels" is not defined.')); expect($glitchTip->events)->toBe([]); }); test('request data loses tokens, signatures and bodies', function () { $scrubbed = ErrorReportScrubber::scrubRequest([ 'url' => 'https://pressekonto.test/newsroom/claim/5?signature=abc123&expires=1700000000&src=mail_publish', 'query_string' => 'signature=abc123&expires=1700000000&src=mail_publish&utm_source=nl', 'data' => ['password' => 'geheim'], 'cookies' => ['pressekonto_session' => 'x'], 'headers' => ['referer' => ['https://pressekonto.test/reset-password/'.str_repeat('a', 64).'?email=kunde@example.com']], ]); expect($scrubbed['url'])->toBe('https://pressekonto.test/newsroom/claim/5?signature=%5BFiltered%5D&expires=%5BFiltered%5D&src=mail_publish') ->and($scrubbed['query_string'])->toBe('signature=%5BFiltered%5D&expires=%5BFiltered%5D&src=mail_publish&utm_source=nl') ->and($scrubbed)->not->toHaveKeys(['data', 'cookies']) ->and($scrubbed['headers']['referer'][0])->toBe('https://pressekonto.test/reset-password/[Filtered]?email=%5BFiltered%5D'); }); test('route parameters named like secrets are removed from the url', function () { Route::middleware('web')->get('/_test/magic/{token}', function () { $event = Event::createEvent(); $event->setRequest(['url' => request()->fullUrl()]); return ErrorReportScrubber::beforeSend($event)?->getRequest()['url']; }); $this->get('/_test/magic/kurz123') ->assertSuccessful() ->assertSee('/_test/magic/[Filtered]', false) ->assertDontSee('kurz123'); }); test('messages and exception values lose e-mail addresses', function () { $event = Event::createEvent(); $event->setMessage('Bounce von info@firma.de', [], 'Bounce von info@firma.de'); $event->setExceptions([new ExceptionDataBag(new RuntimeException('Duplicate entry \'a.b@c.org\''))]); $scrubbed = ErrorReportScrubber::beforeSend($event); expect($scrubbed?->getMessage())->toBe('Bounce von [email]') ->and($scrubbed?->getMessageFormatted())->toBe('Bounce von [email]') ->and($scrubbed?->getExceptions()[0]->getValue())->toBe('Duplicate entry \'[email]\'') ->and($scrubbed?->getUser())->toBeNull(); }); test('the test suite never reports to the real glitchtip', function () { // Ohne diese Absicherung landeten absichtlich provozierte Fehler // („Queue weg“, „Datenbank nicht erreichbar“) als Issues in GlitchTip. expect(config('sentry.dsn'))->toBeEmpty() ->and(config('monitoring.browser.dsn'))->toBeEmpty() ->and(SentrySdk::getCurrentHub()->getClient()?->getOptions()->getDsn())->toBeNull(); });