350 lines
14 KiB
PHP
350 lines
14 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature\PublicSite;
|
|
|
|
use App\Models\PortfolioCase;
|
|
use App\Models\SiteSetting;
|
|
use App\Models\Testimonial;
|
|
use App\Models\WeddingPackage;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class HomePageContentTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_published_featured_content_appears_in_order_and_drafts_are_hidden(): void
|
|
{
|
|
SiteSetting::instance();
|
|
|
|
WeddingPackage::factory()->create([
|
|
'name' => 'Modalidade Rascunho',
|
|
'published_at' => null,
|
|
]);
|
|
WeddingPackage::factory()->published()->create([
|
|
'name' => 'Modalidade B',
|
|
'sort_order' => 20,
|
|
]);
|
|
WeddingPackage::factory()->published()->create([
|
|
'name' => 'Modalidade A',
|
|
'sort_order' => 10,
|
|
]);
|
|
|
|
PortfolioCase::factory()->create([
|
|
'title' => 'Caso Rascunho',
|
|
'is_featured' => true,
|
|
'published_at' => null,
|
|
]);
|
|
PortfolioCase::factory()->published()->create([
|
|
'title' => 'Caso B',
|
|
'is_featured' => true,
|
|
'sort_order' => 20,
|
|
]);
|
|
PortfolioCase::factory()->published()->create([
|
|
'title' => 'Caso A',
|
|
'is_featured' => true,
|
|
'sort_order' => 10,
|
|
]);
|
|
|
|
Testimonial::factory()->create([
|
|
'author_name' => 'Autor Rascunho',
|
|
'published_at' => null,
|
|
]);
|
|
Testimonial::factory()->published()->create([
|
|
'author_name' => 'Autor B',
|
|
'quote' => 'Depoimento B',
|
|
'sort_order' => 20,
|
|
]);
|
|
Testimonial::factory()->published()->create([
|
|
'author_name' => 'Autor A',
|
|
'quote' => 'Depoimento A',
|
|
'sort_order' => 10,
|
|
]);
|
|
|
|
$response = $this->get(route('home'));
|
|
|
|
$response
|
|
->assertOk()
|
|
->assertSeeInOrder([
|
|
'id="hero-heading"',
|
|
'id="manifesto-heading"',
|
|
'id="vertentes-heading"',
|
|
'id="packages-heading"',
|
|
'id="corporate-heading"',
|
|
'id="portfolio-heading"',
|
|
'id="testimonials-heading"',
|
|
'id="briefing-heading"',
|
|
], false)
|
|
->assertSeeInOrder(['Modalidade A', 'Modalidade B'])
|
|
->assertSeeInOrder(['Caso A', 'Caso B'])
|
|
->assertSeeInOrder(['Autor A', 'Autor B'])
|
|
->assertDontSee('Modalidade Rascunho')
|
|
->assertDontSee('Caso Rascunho')
|
|
->assertDontSee('Autor Rascunho')
|
|
->assertSee('data-testid="home-primary-cta"', false)
|
|
->assertSee('href="'.route('briefing').'"', false);
|
|
}
|
|
|
|
public function test_all_sections_render_with_placeholders_when_no_published_content(): void
|
|
{
|
|
SiteSetting::instance()->update(['hero_image_path' => null]);
|
|
|
|
$response = $this->get(route('home'));
|
|
|
|
$response
|
|
->assertOk()
|
|
->assertSeeInOrder([
|
|
'id="hero-heading"',
|
|
'id="manifesto-heading"',
|
|
'id="vertentes-heading"',
|
|
'id="packages-heading"',
|
|
'id="corporate-heading"',
|
|
'id="portfolio-heading"',
|
|
'id="testimonials-heading"',
|
|
'id="briefing-heading"',
|
|
], false)
|
|
->assertSee('FOTO DE CASAMENTO 01')
|
|
->assertSee('Nome e data reais — aguardando autorização')
|
|
->assertSee('Conteúdo em construção');
|
|
}
|
|
|
|
public function test_hero_falls_back_to_default_copy_when_fields_are_empty(): void
|
|
{
|
|
SiteSetting::instance()->update([
|
|
'hero_title' => '',
|
|
'hero_subtitle' => '',
|
|
'hero_cta_label' => '',
|
|
'hero_image_path' => null,
|
|
]);
|
|
|
|
$response = $this->get(route('home'));
|
|
|
|
$response
|
|
->assertOk()
|
|
->assertSeeInOrder(['id="hero-heading"', 'Celebrações com propósito'], false)
|
|
->assertSeeInOrder(['data-testid="home-primary-cta"', 'Solicitar proposta'], false);
|
|
}
|
|
|
|
public function test_home_hero_uses_its_own_cms_image_instead_of_the_social_og_image(): void
|
|
{
|
|
SiteSetting::instance()->update([
|
|
'hero_image_path' => 'content/home/hero.jpg',
|
|
'hero_image_alt' => 'Celebração ao ar livre',
|
|
'default_og_image_path' => 'content/og/social.jpg',
|
|
'default_og_image_alt' => 'Imagem social',
|
|
]);
|
|
|
|
$response = $this->get(route('home'))
|
|
->assertOk()
|
|
->assertSee('content/home/hero.jpg', false)
|
|
->assertSee('alt="Celebração ao ar livre"', false);
|
|
|
|
$this->assertMatchesRegularExpression(
|
|
'/data-motion-beat="media"[^>]*>\s*<img[^>]*content\/home\/hero\.jpg/s',
|
|
$response->getContent(),
|
|
);
|
|
}
|
|
|
|
public function test_home_hero_keeps_an_intentional_typographic_fallback_without_media(): void
|
|
{
|
|
SiteSetting::instance()->update([
|
|
'hero_image_path' => null,
|
|
'hero_image_alt' => null,
|
|
]);
|
|
|
|
$this->get(route('home'))
|
|
->assertOk()
|
|
->assertSee('data-tonal-hero', false)
|
|
->assertSee('id="hero-heading"', false)
|
|
->assertSee('data-testid="home-primary-cta"', false)
|
|
->assertDontSee('data-photo-hero', false)
|
|
->assertDontSee('data-motion-beat="media"', false)
|
|
->assertDontSee('content/home/hero.jpg', false);
|
|
}
|
|
|
|
public function test_wedding_packages_render_from_database_with_guidance_block(): void
|
|
{
|
|
WeddingPackage::factory()->published()->create([
|
|
'level' => '01 / COMPLETA',
|
|
'name' => 'Essenza',
|
|
'slug' => 'essenza',
|
|
'summary' => 'Para casais que desejam contar com a Amare desde o planejamento até a realização do casamento.',
|
|
'scope_items' => ['Planejamento e organização', 'Gestão de etapas e prioridades'],
|
|
'cta_label' => 'Quero conhecer a Essenza',
|
|
'sort_order' => 1,
|
|
]);
|
|
|
|
$response = $this->get(route('home'));
|
|
|
|
$response
|
|
->assertOk()
|
|
->assertSee('Um acompanhamento para cada momento.')
|
|
->assertSee('01 / COMPLETA')
|
|
->assertSee('Essenza')
|
|
->assertSee('Para casais que desejam contar com a Amare desde o planejamento até a realização do casamento.')
|
|
->assertSee('Planejamento e organização')
|
|
->assertSee('Gestão de etapas e prioridades')
|
|
->assertSee('Quero conhecer a Essenza')
|
|
->assertSee('href="'.route('briefing', ['servico_interesse' => 'Essenza']).'"', false)
|
|
->assertSee('href="'.route('packages.show', 'essenza').'"', false)
|
|
->assertSee('Conhecer esta modalidade')
|
|
->assertSee('Ainda não sabe qual modalidade é ideal?')
|
|
->assertSee('Conversar com a Amare')
|
|
->assertSee('Nomenclaturas exibidas conforme materiais/reunião; confirmar versão final antes da publicação.');
|
|
}
|
|
|
|
public function test_package_cta_uses_whatsapp_when_a_number_is_configured(): void
|
|
{
|
|
SiteSetting::instance()->update(['whatsapp_number' => '+55 11 98888-7777']);
|
|
|
|
WeddingPackage::factory()->published()->create([
|
|
'name' => 'Grand Jour',
|
|
'cta_label' => 'Quero conhecer a Grand Jour',
|
|
]);
|
|
|
|
$response = $this->get(route('home'));
|
|
|
|
$response
|
|
->assertOk()
|
|
->assertSee(
|
|
'https://wa.me/5511988887777?text='.rawurlencode('Olá, gostaria de conversar sobre a modalidade Grand Jour para meu casamento.'),
|
|
false,
|
|
)
|
|
->assertSee('target="_blank"', false)
|
|
->assertDontSee(route('briefing', ['servico_interesse' => 'Grand Jour']), false);
|
|
}
|
|
|
|
public function test_corporate_steps_and_placeholder_render_from_settings(): void
|
|
{
|
|
SiteSetting::instance()->update([
|
|
'corporate_steps' => [
|
|
['title' => 'Planejamento', 'body' => 'Estruturação de escopo, cronograma e prioridades.'],
|
|
['title' => 'Produção', 'body' => 'Coordenação dos elementos necessários para colocar o evento de pé.'],
|
|
['title' => 'Execução', 'body' => 'Condução e acompanhamento do evento conforme o projeto aprovado.'],
|
|
],
|
|
]);
|
|
|
|
$response = $this->get(route('home'));
|
|
|
|
$response
|
|
->assertOk()
|
|
->assertSee('Projetos corporativos tratados como experiência, não apenas operação.')
|
|
->assertSeeInOrder(['Planejamento', 'Estruturação de escopo, cronograma e prioridades.'])
|
|
->assertSeeInOrder(['Produção', 'Coordenação dos elementos necessários para colocar o evento de pé.'])
|
|
->assertSeeInOrder(['Execução', 'Condução e acompanhamento do evento conforme o projeto aprovado.'])
|
|
->assertSee('Falar sobre um evento corporativo')
|
|
->assertSee('Portfólio Corporate')
|
|
->assertSee('Conteúdo em construção')
|
|
->assertSee('Em vez de usar fotografias genéricas como se fossem cases');
|
|
}
|
|
|
|
public function test_briefing_form_renders_all_fields_and_posts_to_briefing_store(): void
|
|
{
|
|
SiteSetting::instance();
|
|
|
|
$response = $this->get(route('home'));
|
|
|
|
$response
|
|
->assertOk()
|
|
->assertSee('Conte sobre o evento que você está imaginando.')
|
|
->assertSee('method="POST"', false)
|
|
->assertSee('action="'.route('briefing.store').'"', false)
|
|
->assertSee('name="empresa"', false)
|
|
->assertSee('id="briefing-nome"', false)
|
|
->assertSee('id="briefing-email"', false)
|
|
->assertSee('id="briefing-telefone"', false)
|
|
->assertSee('id="briefing-tipo_evento"', false)
|
|
->assertSee('id="briefing-data_periodo"', false)
|
|
->assertSee('id="briefing-cidade"', false)
|
|
->assertSee('id="briefing-convidados"', false)
|
|
->assertSee('id="briefing-servico_interesse"', false)
|
|
->assertSee('id="briefing-mensagem"', false)
|
|
->assertSee('id="briefing-privacidade"', false)
|
|
->assertSee('Enviar briefing')
|
|
->assertSee('href="'.route('privacy').'"', false);
|
|
}
|
|
|
|
public function test_blank_quote_testimonials_are_skipped_and_padded_with_placeholders(): void
|
|
{
|
|
Testimonial::factory()->published()->create([
|
|
'author_name' => 'Autor Mantido',
|
|
'quote' => 'Experiência impecável do início ao fim.',
|
|
]);
|
|
Testimonial::factory()->published()->create([
|
|
'author_name' => 'Autor Oculto',
|
|
'quote' => ' ',
|
|
]);
|
|
|
|
$response = $this->get(route('home'));
|
|
|
|
$response
|
|
->assertOk()
|
|
->assertSee('Autor Mantido')
|
|
->assertSee('Experiência impecável do início ao fim.')
|
|
->assertDontSee('Autor Oculto')
|
|
->assertSee('Nome e data reais — aguardando autorização');
|
|
|
|
$this->assertSame(3, preg_match_all('/<figure\b/i', $response->getContent()));
|
|
}
|
|
|
|
public function test_testimonials_render_up_to_three_cards_without_a_carousel(): void
|
|
{
|
|
foreach ([10, 20, 30, 40] as $index => $sortOrder) {
|
|
Testimonial::factory()->published()->create([
|
|
'author_name' => 'Autora '.($index + 1),
|
|
'quote' => 'Relato '.($index + 1).'.',
|
|
'sort_order' => $sortOrder,
|
|
]);
|
|
}
|
|
|
|
$response = $this->get(route('home'));
|
|
|
|
$response
|
|
->assertOk()
|
|
->assertSeeInOrder(['Relato 1.', 'Relato 2.', 'Relato 3.'])
|
|
->assertDontSee('Relato 4.');
|
|
|
|
$this->assertSame(3, preg_match_all('/<figure\b/i', $response->getContent()));
|
|
$this->assertStringNotContainsString('data-carousel', $response->getContent());
|
|
$this->assertStringNotContainsString('aria-roledescription="carousel"', $response->getContent());
|
|
}
|
|
|
|
public function test_testimonials_section_renders_placeholders_when_every_published_quote_is_blank(): void
|
|
{
|
|
Testimonial::factory()->published()->create([
|
|
'author_name' => 'Relato vazio',
|
|
'quote' => ' ',
|
|
]);
|
|
|
|
$this->get(route('home'))
|
|
->assertOk()
|
|
->assertSee('id="testimonials-heading"', false)
|
|
->assertSee('Depoimento real aprovado pela cliente entra aqui.')
|
|
->assertDontSee('Relato vazio');
|
|
}
|
|
|
|
public function test_home_removes_ornamental_folios_and_counter_css(): void
|
|
{
|
|
SiteSetting::instance();
|
|
|
|
WeddingPackage::factory()->published()->create();
|
|
PortfolioCase::factory()->published()->create(['is_featured' => true]);
|
|
Testimonial::factory()->published()->create(['quote' => 'Relato publicado.']);
|
|
|
|
$html = $this->get(route('home'))->assertOk()->getContent();
|
|
|
|
$this->assertStringNotContainsString('data-home-folio', (string) $html);
|
|
$this->assertStringNotContainsString('home-folio', (string) $html);
|
|
$this->assertSame(1, preg_match_all('/<h1\b/i', (string) $html));
|
|
|
|
$css = (string) file_get_contents(resource_path('css/app.css'));
|
|
|
|
$this->assertStringNotContainsString('counter-reset: home-chapter', $css);
|
|
$this->assertStringNotContainsString('counter-increment: home-chapter', $css);
|
|
$this->assertStringNotContainsString('counter(home-chapter', $css);
|
|
$this->assertFileDoesNotExist(resource_path('views/components/home/folio.blade.php'));
|
|
}
|
|
}
|