presseportale/tests/Feature/PressReleaseReclassifyTest.php
Kevin Adametz e77d9e7d09 feat: API-Zugang endet mit der Buchung, optionales Ablaufdatum für API-Tokens
Bisher blieb ein einmal erstellter Token gültig, auch wenn Abo bzw. Buchung
längst beendet waren. EnsureApiAccessIsBooked prüft jetzt bei jeder Anfrage
(v1 und /service/…-Altpfade), ob das Konto API-Zugang hat
(ApiAccessEligibilityService::hasApiAccess), sonst 403. Die Tokens bleiben
erhalten und funktionieren nach erneuter Buchung wieder.

Kunden können beim Erstellen optional ein Ablaufdatum setzen (bis 5 Jahre);
die Token-Liste zeigt „Gültig bis“ und einen Hinweis, wenn der Zugang
pausiert ist. sanctum:prune-expired räumt abgelaufene Tokens nach 30 Tagen
täglich ab. API-Doku (public/api/v1.yml) ergänzt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 11:41:24 +00:00

122 lines
4.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
use App\Enums\PressReleaseClassification;
use App\Enums\PressReleaseStatus;
use App\Jobs\ClassifyPressRelease;
use App\Jobs\ScorePressRelease;
use App\Models\Category;
use App\Models\Company;
use App\Models\PressRelease;
use App\Models\User;
use App\Services\PressRelease\PressReleaseService;
use Illuminate\Support\Facades\Queue;
use Tests\TestCase;
test('reclassifyIfClassified dispatches a non-routing job for an already classified press release', function () {
Queue::fake();
$pressRelease = PressRelease::factory()->create([
'classification' => PressReleaseClassification::Green->value,
'status' => PressReleaseStatus::Published->value,
]);
app(PressReleaseService::class)->reclassifyIfClassified($pressRelease);
Queue::assertPushedOn('classification', ClassifyPressRelease::class, function (ClassifyPressRelease $job) use ($pressRelease) {
return $job->pressReleaseId === $pressRelease->id && $job->route === false;
});
});
test('reclassifyIfClassified does nothing for a never-classified press release', function () {
Queue::fake();
$pressRelease = PressRelease::factory()->create(['classification' => null]);
app(PressReleaseService::class)->reclassifyIfClassified($pressRelease);
Queue::assertNotPushed(ClassifyPressRelease::class);
});
test('reprocessAfterContentChange reclassifies and rescores on the fresh model state', function () {
Queue::fake();
$pressRelease = PressRelease::factory()->create([
'classification' => PressReleaseClassification::Green->value,
'content_score' => 80,
'status' => PressReleaseStatus::Published->value,
]);
app(PressReleaseService::class)->reprocessAfterContentChange($pressRelease);
Queue::assertPushedOn('classification', ClassifyPressRelease::class);
Queue::assertPushedOn('classification', ScorePressRelease::class);
});
test('reprocessAfterContentChange does nothing for an unclassified, unscored press release', function () {
Queue::fake();
$pressRelease = PressRelease::factory()->create([
'classification' => null,
'content_score' => null,
]);
app(PressReleaseService::class)->reprocessAfterContentChange($pressRelease);
Queue::assertNotPushed(ClassifyPressRelease::class);
});
test('api update of a classified press release re-classifies when the content changes', function () {
/** @var TestCase $this */
Queue::fake();
$user = User::factory()->create();
$company = Company::factory()->presseecho()->create();
$category = Category::factory()->withTranslations()->create();
$user->companies()->attach($company->id, ['role' => 'owner']);
$pressRelease = PressRelease::factory()->create([
'user_id' => $user->id,
'company_id' => $company->id,
'category_id' => $category->id,
'portal' => $company->portal->value,
'status' => PressReleaseStatus::Draft->value,
'classification' => PressReleaseClassification::Green->value,
]);
apiActingAs($user, ['press-releases:write']);
$this->patchJson("/api/v1/press-releases/{$pressRelease->id}", [
'text' => 'Komplett neuer Inhalt, der erneut geprüft werden muss.',
])->assertOk();
Queue::assertPushed(ClassifyPressRelease::class, fn (ClassifyPressRelease $job) => $job->route === false);
});
test('api update does not re-classify when content is unchanged', function () {
/** @var TestCase $this */
Queue::fake();
$user = User::factory()->create();
$company = Company::factory()->presseecho()->create();
$category = Category::factory()->withTranslations()->create();
$user->companies()->attach($company->id, ['role' => 'owner']);
$pressRelease = PressRelease::factory()->create([
'user_id' => $user->id,
'company_id' => $company->id,
'category_id' => $category->id,
'portal' => $company->portal->value,
'status' => PressReleaseStatus::Draft->value,
'classification' => PressReleaseClassification::Green->value,
'keywords' => 'alt',
]);
apiActingAs($user, ['press-releases:write']);
// Nur Keywords ändern – kein Titel/Text → keine Neuklassifikation.
$this->patchJson("/api/v1/press-releases/{$pressRelease->id}", [
'keywords' => 'neu',
])->assertOk();
Queue::assertNotPushed(ClassifyPressRelease::class);
});