presseportale/tests/Feature/PressReleaseReclassifyTest.php
Kevin Adametz 5d6a94902b Optimierung 2.6: reprocessAfterContentChange im PressReleaseService
Den 3x identischen contentChanged->fresh->reclassifyIfClassified->
rescoreIfScored-Block (admin/edit 1x, customer/edit 2x) in
PressReleaseService::reprocessAfterContentChange() zentralisiert.

Hinweis: Eine vollstaendige createDraft()/updateContent()-Verlagerung
wurde bewusst NICHT erzwungen — die Attributsaetze und der umgebende
Validierungs-/Fehlerfluss von Admin (no_export, direkter review-Status)
und Customer (placeholder_variant, Titel-Fallback, immer Draft) divergieren
real; eine gemeinsame Persistenzmethode waere fragil bei grosser Testflaeche.

Tests: 2 neue Faelle; volle Suite gruen (796 passed, 1 skipped).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 10:01:29 +00:00

123 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 Laravel\Sanctum\Sanctum;
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::assertNothingPushed();
});
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::assertNothingPushed();
});
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,
]);
Sanctum::actingAs($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',
]);
Sanctum::actingAs($user, ['press-releases:write']);
// Nur Keywords ändern – kein Titel/Text → keine Neuklassifikation.
$this->patchJson("/api/v1/press-releases/{$pressRelease->id}", [
'keywords' => 'neu',
])->assertOk();
Queue::assertNothingPushed();
});