feat(service): finalize snapshot + sync protection

This commit is contained in:
Thorsten Bus 2026-05-31 02:33:32 +02:00
parent 929bda2018
commit edceebb2f8
2 changed files with 105 additions and 0 deletions

View file

@ -343,6 +343,20 @@ public function finalize(Service $service): JsonResponse
'finalized_at' => now(),
]);
$resolver = app(\App\Services\ServiceImageResolver::class);
$keyVisual = $resolver->keyVisualFor($service);
$background = $resolver->backgroundFor($service);
$updates = [];
if ($keyVisual !== null && $service->key_visual_filename === null) {
$updates['key_visual_filename'] = $keyVisual;
}
if ($background !== null && $service->background_filename === null) {
$updates['background_filename'] = $background;
}
if ($updates !== []) {
$service->update($updates);
}
return response()->json([
'needs_confirmation' => false,
'success' => 'Service wurde abgeschlossen.',

View file

@ -0,0 +1,91 @@
<?php
use App\Models\Service;
use App\Models\Setting;
use App\Models\User;
use App\Services\ChurchToolsService;
use App\Services\ServiceImageResolver;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
beforeEach(function () {
Storage::fake('public');
});
test('finalize nimmt snapshot des globalen hintergrunds wenn service spalte null ist', function () {
Storage::disk('public')->put('slides/bg1.jpg', 'fake-content');
Setting::set('current_background', 'slides/bg1.jpg');
$service = Service::factory()->create([
'background_filename' => null,
'finalized_at' => null,
]);
$this->actingAs(User::factory()->create())
->postJson(route('services.finalize', $service), ['confirmed' => true])
->assertOk();
expect($service->fresh()->background_filename)->toBe('slides/bg1.jpg');
});
test('snapshot gewinnt: neuer globaler hintergrund beeinflusst abgeschlossenen service nicht', function () {
Storage::disk('public')->put('slides/bg1.jpg', 'fake-content');
Setting::set('current_background', 'slides/bg1.jpg');
$service = Service::factory()->create([
'background_filename' => null,
'finalized_at' => null,
]);
$this->actingAs(User::factory()->create())
->postJson(route('services.finalize', $service), ['confirmed' => true])
->assertOk();
Storage::disk('public')->put('slides/bg2.jpg', 'fake-content');
Setting::set('current_background', 'slides/bg2.jpg');
$resolved = app(ServiceImageResolver::class)->backgroundFor($service->fresh());
expect($resolved)->toBe('slides/bg1.jpg');
});
test('cts sync ueberschreibt key_visual_filename und moderator_name nicht', function () {
Carbon::setTestNow('2026-03-01 09:00:00');
$service = Service::factory()->create([
'cts_event_id' => '424242',
'key_visual_filename' => 'custom.jpg',
'moderator_name' => 'Hans',
'preacher_name_override' => 'Pastor X',
'background_filename' => 'bg-custom.jpg',
]);
$sync = new ChurchToolsService(
eventFetcher: fn () => [
new FakeEvent(
id: 424242,
title: 'Aktualisierter Titel',
startDate: '2026-03-08T10:00:00+00:00',
eventServices: [
new FakeEventService('Predigt', new FakePerson('Neuer', 'Prediger')),
],
),
],
songFetcher: fn () => [],
agendaFetcher: fn () => new FakeAgenda([]),
eventServiceFetcher: fn (int $eventId) => [
new FakeEventService('Predigt', new FakePerson('Neuer', 'Prediger')),
],
);
$sync->sync();
$fresh = DB::table('services')->where('cts_event_id', '424242')->first();
expect($fresh->key_visual_filename)->toBe('custom.jpg');
expect($fresh->moderator_name)->toBe('Hans');
expect($fresh->preacher_name_override)->toBe('Pastor X');
expect($fresh->background_filename)->toBe('bg-custom.jpg');
expect($fresh->title)->toBe('Aktualisierter Titel');
});