* feat: recreate public frontend with Heritage Editorial identity Replace placeholder visual system with EB Garamond/olive tokens, brand assets, editorial home narrative, São Paulo settings, real testimonials, and regenerated visual baselines. Co-authored-by: Cursor <cursoragent@cursor.com> * docs: archive recreate-public-frontend and sync Heritage Editorial specs Merge delta requirements into main OpenSpec capabilities and move the completed change into the dated archive. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
232 lines
8.2 KiB
PHP
232 lines
8.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature\Marketing;
|
|
|
|
use App\Filament\Pages\ManageSiteSettings;
|
|
use App\Models\SiteSetting;
|
|
use App\Models\User;
|
|
use Database\Seeders\ContentSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Livewire\Livewire;
|
|
use Tests\TestCase;
|
|
|
|
class SiteSettingsTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_admin_can_save_site_settings(): void
|
|
{
|
|
$admin = User::factory()->admin()->create();
|
|
SiteSetting::instance();
|
|
|
|
$this->actingAs($admin);
|
|
|
|
Livewire::test(ManageSiteSettings::class)
|
|
->set('data.brand_name', 'Amare Atualizada')
|
|
->set('data.hero_title', 'Novo título')
|
|
->set('data.hero_subtitle', 'Novo subtítulo')
|
|
->set('data.hero_cta_label', 'Fale conosco')
|
|
->set('data.email', 'novo@amare.local')
|
|
->set('data.phone', '(85) 98888-8888')
|
|
->set('data.default_meta_title', 'Meta title')
|
|
->set('data.default_meta_description', 'Meta description')
|
|
->set('data.analytics_enabled', false)
|
|
->call('save')
|
|
->assertHasNoFormErrors();
|
|
|
|
$this->assertDatabaseHas('site_settings', [
|
|
'brand_name' => 'Amare Atualizada',
|
|
'hero_title' => 'Novo título',
|
|
]);
|
|
}
|
|
|
|
public function test_assistant_cannot_access_site_settings(): void
|
|
{
|
|
$assistant = User::factory()->assistant()->create();
|
|
SiteSetting::instance();
|
|
|
|
$this->actingAs($assistant);
|
|
|
|
Livewire::test(ManageSiteSettings::class)
|
|
->assertForbidden();
|
|
}
|
|
|
|
public function test_admin_can_upload_default_og_image_with_alt_text(): void
|
|
{
|
|
Storage::fake('public');
|
|
|
|
$admin = User::factory()->admin()->create();
|
|
SiteSetting::instance();
|
|
|
|
$this->actingAs($admin);
|
|
|
|
Livewire::test(ManageSiteSettings::class)
|
|
->set('data.default_og_image_path', [
|
|
UploadedFile::fake()->image('og-image.jpg', 1200, 800),
|
|
])
|
|
->set('data.default_og_image_alt', 'Casal celebrando com a equipe Amare')
|
|
->call('save')
|
|
->assertHasNoFormErrors();
|
|
|
|
$settings = SiteSetting::instance()->refresh();
|
|
|
|
$this->assertSame('Casal celebrando com a equipe Amare', $settings->default_og_image_alt);
|
|
$this->assertNotNull($settings->default_og_image_path);
|
|
Storage::disk('public')->assertExists($settings->default_og_image_path);
|
|
}
|
|
|
|
public function test_default_og_image_requires_alt_text(): void
|
|
{
|
|
Storage::fake('public');
|
|
|
|
$admin = User::factory()->admin()->create();
|
|
SiteSetting::instance();
|
|
|
|
$this->actingAs($admin);
|
|
|
|
Livewire::test(ManageSiteSettings::class)
|
|
->set('data.default_og_image_path', [
|
|
UploadedFile::fake()->image('og-image.jpg', 800, 600),
|
|
])
|
|
->set('data.default_og_image_alt', null)
|
|
->call('save')
|
|
->assertHasFormErrors(['default_og_image_alt' => 'required']);
|
|
}
|
|
|
|
public function test_default_og_image_alt_is_optional_without_an_image(): void
|
|
{
|
|
$admin = User::factory()->admin()->create();
|
|
SiteSetting::instance();
|
|
|
|
$this->actingAs($admin);
|
|
|
|
Livewire::test(ManageSiteSettings::class)
|
|
->set('data.default_og_image_path', null)
|
|
->set('data.default_og_image_alt', null)
|
|
->call('save')
|
|
->assertHasNoFormErrors();
|
|
}
|
|
|
|
public function test_content_seeder_includes_default_og_image_alt_text(): void
|
|
{
|
|
Storage::fake('public');
|
|
|
|
$this->seed(ContentSeeder::class);
|
|
|
|
$settings = SiteSetting::query()->sole();
|
|
|
|
$this->assertSame(
|
|
'Identidade visual da Amare Assessoria de Eventos',
|
|
$settings->default_og_image_alt,
|
|
);
|
|
$this->assertSame('content/og/og-default.jpg', $settings->default_og_image_path);
|
|
Storage::disk('public')->assertExists('content/og/og-default.jpg');
|
|
}
|
|
|
|
public function test_content_seeder_uses_sao_paulo_and_editorial_fields(): void
|
|
{
|
|
Storage::fake('public');
|
|
|
|
$this->seed(ContentSeeder::class);
|
|
|
|
$settings = SiteSetting::query()->sole();
|
|
|
|
$this->assertStringContainsStringIgnoringCase('São Paulo', (string) $settings->city);
|
|
$this->assertStringNotContainsStringIgnoringCase('Fortaleza', (string) $settings->city);
|
|
$this->assertNotEmpty($settings->manifesto_title);
|
|
$this->assertNotEmpty($settings->manifesto_lead);
|
|
$this->assertNotEmpty($settings->manifesto_body);
|
|
$this->assertIsArray($settings->method_steps);
|
|
$this->assertCount(4, $settings->method_steps);
|
|
$this->assertIsArray($settings->principles);
|
|
$this->assertGreaterThanOrEqual(1, count($settings->principles));
|
|
$this->assertNotEmpty($settings->hero_note);
|
|
$this->assertNotEmpty($settings->hero_secondary_cta_label);
|
|
}
|
|
|
|
public function test_admin_can_save_editorial_site_settings_fields(): void
|
|
{
|
|
$admin = User::factory()->admin()->create();
|
|
SiteSetting::instance();
|
|
|
|
$this->actingAs($admin);
|
|
|
|
Livewire::test(ManageSiteSettings::class)
|
|
->set('data.hero_secondary_cta_label', 'Conheça nosso olhar')
|
|
->set('data.hero_note', 'Planejamento cuidadoso do primeiro encontro ao último detalhe.')
|
|
->set('data.manifesto_title', 'Sofisticação que também se traduz em organização.')
|
|
->set('data.manifesto_lead', 'Um evento memorável não nasce apenas de uma boa estética.')
|
|
->set('data.manifesto_body', 'A Amare combina sensibilidade e precisão.')
|
|
->set('data.method_intro', 'Clareza em cada etapa.')
|
|
->set('data.method_steps', [
|
|
['title' => 'Escuta', 'body' => 'Entendimento do contexto.'],
|
|
['title' => 'Direção', 'body' => 'Definição de escopo.'],
|
|
['title' => 'Produção', 'body' => 'Coordenação de cronograma.'],
|
|
['title' => 'Execução', 'body' => 'Presença atenta no evento.'],
|
|
])
|
|
->set('data.principles', [
|
|
'Personalização sem complicação desnecessária',
|
|
'Comunicação clara e decisões bem orientadas',
|
|
'Atenção à experiência de clientes e convidados',
|
|
'Execução responsável do início ao fim',
|
|
])
|
|
->set('data.city', 'São Paulo - SP')
|
|
->call('save')
|
|
->assertHasNoFormErrors();
|
|
|
|
$settings = SiteSetting::instance()->refresh();
|
|
|
|
$this->assertSame('Conheça nosso olhar', $settings->hero_secondary_cta_label);
|
|
$this->assertSame('São Paulo - SP', $settings->city);
|
|
$this->assertCount(4, $settings->method_steps);
|
|
$this->assertSame('Escuta', $settings->method_steps[0]['title']);
|
|
$this->assertCount(4, $settings->principles);
|
|
}
|
|
|
|
public function test_logo_upload_requires_alt_text(): void
|
|
{
|
|
Storage::fake('public');
|
|
|
|
$admin = User::factory()->admin()->create();
|
|
SiteSetting::instance();
|
|
|
|
$this->actingAs($admin);
|
|
|
|
Livewire::test(ManageSiteSettings::class)
|
|
->set('data.logo_path', [
|
|
UploadedFile::fake()->image('logo.png', 400, 400),
|
|
])
|
|
->set('data.logo_alt', null)
|
|
->call('save')
|
|
->assertHasFormErrors(['logo_alt' => 'required']);
|
|
}
|
|
|
|
public function test_admin_can_upload_logo_with_alt_text(): void
|
|
{
|
|
Storage::fake('public');
|
|
|
|
$admin = User::factory()->admin()->create();
|
|
SiteSetting::instance();
|
|
|
|
$this->actingAs($admin);
|
|
|
|
Livewire::test(ManageSiteSettings::class)
|
|
->set('data.logo_path', [
|
|
UploadedFile::fake()->image('logo.png', 400, 400),
|
|
])
|
|
->set('data.logo_alt', 'Amare Assessoria')
|
|
->call('save')
|
|
->assertHasNoFormErrors();
|
|
|
|
$settings = SiteSetting::instance()->refresh();
|
|
|
|
$this->assertSame('Amare Assessoria', $settings->logo_alt);
|
|
$this->assertNotNull($settings->logo_path);
|
|
Storage::disk('public')->assertExists($settings->logo_path);
|
|
}
|
|
}
|