forceRootUrl('https://'.$portalDomain); }); test('returns playlist with video-display config', function () { $version = DisplayVersion::factory()->create(['type' => 'video-display']); DisplayVersionItem::factory()->create([ 'display_version_id' => $version->id, 'item_type' => 'video', 'content' => ['filename' => 'test.mp4', 'title' => 'Test', 'position' => 30], ]); DisplayVersionItem::factory()->create([ 'display_version_id' => $version->id, 'item_type' => 'footer', 'content' => ['headline' => 'Hello', 'subline' => 'World', 'url' => null], ]); $display = Display::factory()->create(); $display->versions()->attach($version->id, ['sort_order' => 0]); $response = $this->getJson("/api/display/{$display->id}/config"); $response->assertSuccessful(); $response->assertJsonStructure(['playlist', 'updated_at']); $response->assertJsonPath('playlist.0.type', 'video-display'); $response->assertJsonPath('playlist.0.videoPlaylist.0.src', 'assets/test.mp4'); $response->assertJsonPath('playlist.0.footerContent.0.headline', 'Hello'); }); test('returns playlist with b2in config', function () { $version = DisplayVersion::factory()->create([ 'type' => 'b2in', 'settings' => ['theme' => 'dark', 'footer_name' => 'Marcel'], ]); DisplayVersionItem::factory()->create([ 'display_version_id' => $version->id, 'item_type' => 'media', 'content' => [ 'category' => 'immobilien', 'media_type' => 'image', 'media_url' => '../assets/test.jpg', 'headline' => 'Headline', 'subline' => 'Subline', 'duration_seconds' => 10, ], ]); $display = Display::factory()->create(); $display->versions()->attach($version->id, ['sort_order' => 0]); $response = $this->getJson("/api/display/{$display->id}/config"); $response->assertSuccessful(); $response->assertJsonPath('playlist.0.type', 'b2in'); $response->assertJsonPath('playlist.0.settings.theme', 'dark'); $response->assertJsonPath('playlist.0.items.0.category', 'immobilien'); }); test('returns playlist with offers config', function () { $version = DisplayVersion::factory()->create([ 'type' => 'offers', 'settings' => ['loop' => true], ]); DisplayVersionItem::factory()->create([ 'display_version_id' => $version->id, 'item_type' => 'slide', 'content' => [ 'type' => 'product-hero', 'duration' => 10000, 'image_url' => '../assets/goya1.jpg', 'badge_text' => 'Einzelstück', 'eyebrow' => 'Hersteller: Sudbrock', 'title' => 'GOYA Sideboard', 'subline' => '', 'price' => '489 €', 'original_price' => 'statt 4.744 €', 'tag_text' => '', 'bullets' => [], 'disclaimer' => '', 'qr_url' => 'https://cabinet-bielefeld.de', 'qr_title' => 'Reservieren', 'contact' => "0521 98620100\nTel. oder WhatsApp", 'show_brand_text' => false, 'brand_tagline' => '', ], ]); $display = Display::factory()->create(); $display->versions()->attach($version->id, ['sort_order' => 0]); $response = $this->getJson("/api/display/{$display->id}/config"); $response->assertSuccessful(); $response->assertJsonPath('playlist.0.type', 'offers'); $response->assertJsonPath('playlist.0.slides.0.type', 'product-hero'); $response->assertJsonPath('playlist.0.slides.0.title', 'GOYA Sideboard'); $response->assertJsonPath('playlist.0.slides.0.price', '489 €'); $response->assertJsonPath('playlist.0.slides.0.qr_url', 'https://cabinet-bielefeld.de'); }); test('returns playlist with multiple versions in order', function () { $videoVersion = DisplayVersion::factory()->create(['type' => 'video-display', 'name' => 'Videos']); DisplayVersionItem::factory()->create([ 'display_version_id' => $videoVersion->id, 'item_type' => 'video', 'content' => ['filename' => 'test.mp4', 'title' => 'Test', 'position' => 25], ]); $b2inVersion = DisplayVersion::factory()->create(['type' => 'b2in', 'name' => 'B2in']); DisplayVersionItem::factory()->create([ 'display_version_id' => $b2inVersion->id, 'item_type' => 'media', 'content' => ['category' => 'immobilien', 'media_type' => 'image', 'media_url' => 'test.jpg', 'headline' => 'H', 'subline' => 'S', 'duration_seconds' => 5], ]); $display = Display::factory()->create(); $display->versions()->attach([ $videoVersion->id => ['sort_order' => 0], $b2inVersion->id => ['sort_order' => 1], ]); $response = $this->getJson("/api/display/{$display->id}/config"); $response->assertSuccessful(); $response->assertJsonCount(2, 'playlist'); $response->assertJsonPath('playlist.0.type', 'video-display'); $response->assertJsonPath('playlist.1.type', 'b2in'); }); test('returns 404 for inactive display', function () { $version = DisplayVersion::factory()->create(); $display = Display::factory()->create(['is_active' => false]); $display->versions()->attach($version->id, ['sort_order' => 0]); $response = $this->getJson("/api/display/{$display->id}/config"); $response->assertNotFound(); }); test('returns 404 for display without versions', function () { $display = Display::factory()->create(); $response = $this->getJson("/api/display/{$display->id}/config"); $response->assertNotFound(); }); test('check endpoint returns only updated_at', function () { $version = DisplayVersion::factory()->create(); $display = Display::factory()->create(); $display->versions()->attach($version->id, ['sort_order' => 0]); $response = $this->getJson("/api/display/{$display->id}/check"); $response->assertSuccessful(); $response->assertJsonStructure(['updated_at']); }); test('existing display config api still works', function () { $response = $this->getJson('/api/display/config'); $response->assertSuccessful(); $response->assertJsonStructure(['videoPlaylist', 'footerContent']); });