97 lines
3.2 KiB
PHP
97 lines
3.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\HomepageAnnouncement;
|
|
use App\Services\HomepageAnnouncementSanitizer;
|
|
use App\Services\HomepageAnnouncementService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function (): void {
|
|
app(HomepageAnnouncementService::class)->clearActiveCache();
|
|
});
|
|
|
|
function homepageAnnouncement(array $overrides = []): HomepageAnnouncement
|
|
{
|
|
return HomepageAnnouncement::query()->create(array_merge([
|
|
'title' => 'Skinbase Nova is live.',
|
|
'subtitle' => 'A new chapter for the Skinbase creative community.',
|
|
'badge_text' => 'Launch Day · 1 May 2026',
|
|
'content_html' => '<p><strong>Today, 1 May 2026, Skinbase begins a new chapter.</strong></p>',
|
|
'type' => HomepageAnnouncement::TYPE_LAUNCH,
|
|
'status' => HomepageAnnouncement::STATUS_PUBLISHED,
|
|
'is_active' => true,
|
|
'starts_at' => now()->subHour(),
|
|
'ends_at' => null,
|
|
'placement' => HomepageAnnouncement::PLACEMENT_HOMEPAGE_AFTER_FEATURED,
|
|
'priority' => 100,
|
|
'is_dismissible' => true,
|
|
'dismiss_version' => 1,
|
|
'gradient_preset' => HomepageAnnouncement::GRADIENT_NOVA_AURORA,
|
|
'theme_preset' => 'launch',
|
|
], $overrides));
|
|
}
|
|
|
|
it('returns the visible published active homepage announcement', function (): void {
|
|
$expected = homepageAnnouncement();
|
|
|
|
$active = app(HomepageAnnouncementService::class)->getActiveForHomepage();
|
|
|
|
expect($active?->id)->toBe($expected->id);
|
|
});
|
|
|
|
it('does not return a future announcement', function (): void {
|
|
homepageAnnouncement([
|
|
'starts_at' => now()->addHour(),
|
|
]);
|
|
|
|
expect(app(HomepageAnnouncementService::class)->getActiveForHomepage())->toBeNull();
|
|
});
|
|
|
|
it('does not return an expired announcement', function (): void {
|
|
homepageAnnouncement([
|
|
'starts_at' => now()->subDays(2),
|
|
'ends_at' => now()->subMinute(),
|
|
]);
|
|
|
|
expect(app(HomepageAnnouncementService::class)->getActiveForHomepage())->toBeNull();
|
|
});
|
|
|
|
it('does not return a draft announcement', function (): void {
|
|
homepageAnnouncement([
|
|
'status' => HomepageAnnouncement::STATUS_DRAFT,
|
|
]);
|
|
|
|
expect(app(HomepageAnnouncementService::class)->getActiveForHomepage())->toBeNull();
|
|
});
|
|
|
|
it('returns the highest priority visible announcement', function (): void {
|
|
$lower = homepageAnnouncement([
|
|
'priority' => 10,
|
|
'title' => 'Lower priority',
|
|
]);
|
|
|
|
$higher = homepageAnnouncement([
|
|
'priority' => 900,
|
|
'title' => 'Higher priority',
|
|
]);
|
|
|
|
$active = app(HomepageAnnouncementService::class)->getActiveForHomepage();
|
|
|
|
expect($active?->id)
|
|
->not->toBe($lower->id)
|
|
->toBe($higher->id);
|
|
});
|
|
|
|
it('sanitizes announcement html content', function (): void {
|
|
$sanitized = app(HomepageAnnouncementSanitizer::class)->sanitizeHtml('<p>Hello<script>alert(1)</script></p><a href="javascript:alert(1)" onclick="boom()">Click</a><h2 style="color:red">Title</h2>');
|
|
|
|
expect($sanitized)
|
|
->toContain('<p>Hello</p>')
|
|
->toContain('<h2>Title</h2>')
|
|
->not->toContain('<script')
|
|
->not->toContain('javascript:')
|
|
->not->toContain('onclick=');
|
|
}); |