Änderungen (relevant):

- Add‑on Checkout auf Transactions + Transaction‑ID speichern: app/Services/Addons/EventAddonCheckoutService.php
  - Paket/Marketing Checkout auf Transactions: app/Services/Paddle/PaddleCheckoutService.php
  - Gift‑Voucher Checkout: Customer anlegen/finden + Transactions: app/Services/GiftVouchers/
    GiftVoucherCheckoutService.php
  - Tests aktualisiert: tests/Feature/Tenant/EventAddonCheckoutTest.php, tests/Unit/PaddleCheckoutServiceTest.php,
tests/Unit/GiftVoucherCheckoutServiceTest.php
This commit is contained in:
Codex Agent
2025-12-29 18:04:28 +01:00
parent 795e37ee12
commit 5f521d055f
26 changed files with 783 additions and 102 deletions

View File

@@ -2,6 +2,10 @@
namespace Tests\Feature;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Queue\Events\JobFailed;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Event;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Tests\TestCase;
@@ -55,4 +59,156 @@ class SentryReportingTest extends TestCase
$this->assertSame(0, $fake->captured, 'Sentry should ignore 4xx errors');
}
public function test_reports_scheduled_task_failures_to_sentry(): void
{
$fake = new class
{
public int $captured = 0;
public function captureException(mixed $exception = null): void
{
$this->captured++;
}
};
$this->app->instance('sentry', $fake);
Artisan::call('schedule:list', [
'--json' => true,
'--no-interaction' => true,
]);
$schedule = $this->app->make(Schedule::class);
$task = collect($schedule->events())
->first(fn ($event) => str_contains((string) $event->command, 'storage:monitor'));
$this->assertNotNull($task, 'Expected scheduled storage:monitor task');
$task->finish($this->app, 1);
$this->assertSame(1, $fake->captured, 'Sentry should receive scheduled task failures');
}
public function test_reports_queue_failures_to_sentry(): void
{
$fake = new class
{
public int $captured = 0;
public function captureException(mixed $exception = null): void
{
$this->captured++;
}
};
$this->app->instance('sentry', $fake);
$job = new class implements \Illuminate\Contracts\Queue\Job
{
public function uuid(): ?string
{
return null;
}
public function getJobId(): string
{
return 'job-id';
}
public function payload(): array
{
return [];
}
public function fire(): void {}
public function release($delay = 0): void {}
public function isReleased(): bool
{
return false;
}
public function delete(): void {}
public function isDeleted(): bool
{
return false;
}
public function isDeletedOrReleased(): bool
{
return false;
}
public function attempts(): int
{
return 1;
}
public function hasFailed(): bool
{
return false;
}
public function markAsFailed(): void {}
public function fail($e = null): void {}
public function maxTries(): ?int
{
return null;
}
public function maxExceptions(): ?int
{
return null;
}
public function timeout(): ?int
{
return null;
}
public function retryUntil(): ?int
{
return null;
}
public function getName(): string
{
return 'FakeJob';
}
public function resolveName(): string
{
return 'FakeJob';
}
public function resolveQueuedJobClass(): string
{
return 'FakeJob';
}
public function getConnectionName(): string
{
return 'redis';
}
public function getQueue(): string
{
return 'default';
}
public function getRawBody(): string
{
return '{}';
}
};
Event::dispatch(new JobFailed('redis', $job, new \RuntimeException('Queue failure')));
$this->assertSame(1, $fake->captured, 'Sentry should receive queue failures');
}
}