Allow heading tags (h1-h6) in ContentSanitizer so news editor headings render

This commit is contained in:
2026-06-04 07:52:57 +02:00
parent 0b33a1b074
commit 15870ddb1f
191 changed files with 15453 additions and 1786 deletions

View File

@@ -0,0 +1,147 @@
<?php
declare(strict_types=1);
use App\Models\Artwork;
use App\Models\EnhanceJob;
use App\Models\User;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\Storage;
use Inertia\Testing\AssertableInertia;
beforeEach(function (): void {
config()->set('enhance.disk', 'public');
Storage::fake('public');
});
it('redirects guests away from enhance pages', function (): void {
$this->get(route('enhance.index'))->assertRedirect(route('login'));
$this->get(route('enhance.create'))->assertRedirect(route('login'));
});
it('prevents a user from viewing another users enhance job', function (): void {
$owner = User::factory()->create();
$intruder = User::factory()->create();
$job = EnhanceJob::query()->create([
'user_id' => $owner->id,
'status' => EnhanceJob::STATUS_COMPLETED,
'engine' => EnhanceJob::ENGINE_STUB,
'mode' => 'standard',
'scale' => 2,
]);
$this->actingAs($intruder)
->get(route('enhance.show', ['enhanceJob' => $job]))
->assertForbidden();
});
it('shows the selected artwork source on the create page for the owner', function (): void {
$owner = User::factory()->create();
$artwork = Artwork::factory()->for($owner)->create();
$this->actingAs($owner)
->get(route('enhance.create', ['artwork' => $artwork->id]))
->assertOk()
->assertInertia(fn (AssertableInertia $page) => $page
->component('Enhance/Create')
->where('selectedArtwork.id', $artwork->id)
->where('selectedArtwork.title', $artwork->title)
->where('selectedArtwork.store_url', route('artworks.enhance.store', ['artwork' => $artwork->id]))
);
});
it('returns a validation error when an artwork source is unavailable', function (): void {
$owner = User::factory()->create();
$artwork = Artwork::factory()->for($owner)->create([
'file_path' => 'uploads/artworks/missing.jpg',
'hash' => null,
'file_ext' => null,
'mime_type' => 'image/jpeg',
]);
$this->from(route('enhance.create', ['artwork' => $artwork->id]))
->actingAs($owner)
->post(route('artworks.enhance.store', ['artwork' => $artwork->id]), [
'scale' => 2,
'mode' => 'standard',
])
->assertRedirect(route('enhance.create', ['artwork' => $artwork->id]))
->assertSessionHasErrors([
'source' => 'Artwork source file is unavailable for enhance.',
]);
expect(EnhanceJob::query()->count())->toBe(0);
});
it('allows an owner to delete a completed job and its files', function (): void {
$owner = User::factory()->create();
Storage::disk('public')->put('enhance/sources/1/source.png', UploadedFile::fake()->image('source.png')->get());
Storage::disk('public')->put('enhance/outputs/1/output.webp', UploadedFile::fake()->image('output.webp')->get());
Storage::disk('public')->put('enhance/previews/1/preview.webp', UploadedFile::fake()->image('preview.webp')->get());
$job = EnhanceJob::query()->create([
'user_id' => $owner->id,
'status' => EnhanceJob::STATUS_COMPLETED,
'engine' => EnhanceJob::ENGINE_STUB,
'mode' => 'standard',
'scale' => 2,
'source_disk' => 'public',
'source_path' => 'enhance/sources/1/source.png',
'output_disk' => 'public',
'output_path' => 'enhance/outputs/1/output.webp',
'preview_disk' => 'public',
'preview_path' => 'enhance/previews/1/preview.webp',
]);
$this->actingAs($owner)
->delete(route('enhance.destroy', ['enhanceJob' => $job]))
->assertRedirect(route('enhance.index'));
$deletedJob = EnhanceJob::withTrashed()->find($job->id);
expect($deletedJob)->not->toBeNull();
expect($deletedJob->trashed())->toBeTrue();
Storage::disk('public')->assertMissing('enhance/sources/1/source.png');
Storage::disk('public')->assertMissing('enhance/outputs/1/output.webp');
Storage::disk('public')->assertMissing('enhance/previews/1/preview.webp');
});
it('allows an owner to retry a failed job without deleting the source', function (): void {
Queue::fake();
$owner = User::factory()->create();
$source = UploadedFile::fake()->image('source.png', 300, 300);
Storage::disk('public')->put('enhance/sources/1/source.png', $source->get());
Storage::disk('public')->put('enhance/outputs/1/output.webp', UploadedFile::fake()->image('output.webp')->get());
Storage::disk('public')->put('enhance/previews/1/preview.webp', UploadedFile::fake()->image('preview.webp')->get());
$job = EnhanceJob::query()->create([
'user_id' => $owner->id,
'status' => EnhanceJob::STATUS_FAILED,
'engine' => EnhanceJob::ENGINE_STUB,
'mode' => 'standard',
'scale' => 2,
'source_disk' => 'public',
'source_path' => 'enhance/sources/1/source.png',
'output_disk' => 'public',
'output_path' => 'enhance/outputs/1/output.webp',
'preview_disk' => 'public',
'preview_path' => 'enhance/previews/1/preview.webp',
'error_message' => 'Example failure',
]);
$this->actingAs($owner)
->post(route('enhance.retry', ['enhanceJob' => $job]))
->assertRedirect(route('enhance.show', ['enhanceJob' => $job]));
$job->refresh();
expect($job->status)->toBe(EnhanceJob::STATUS_QUEUED);
expect($job->output_path)->toBeNull();
expect($job->preview_path)->toBeNull();
Storage::disk('public')->assertExists('enhance/sources/1/source.png');
Storage::disk('public')->assertMissing('enhance/outputs/1/output.webp');
Storage::disk('public')->assertMissing('enhance/previews/1/preview.webp');
});