Canonical upsert for five authorized couples so staging/prod can load depoimentos without DatabaseSeeder/ContentSeeder. Co-authored-by: Cursor <cursoragent@cursor.com>
277 lines
11 KiB
PHP
277 lines
11 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature\Marketing;
|
|
|
|
use App\Filament\Resources\Testimonials\Pages\ListTestimonials;
|
|
use App\Models\SiteSetting;
|
|
use App\Models\Testimonial;
|
|
use App\Models\User;
|
|
use Database\Seeders\ContentSeeder;
|
|
use Database\Seeders\TestimonialsSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Livewire\Livewire;
|
|
use Tests\TestCase;
|
|
|
|
class TestimonialsTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
/**
|
|
* @var list<array{
|
|
* quote: string,
|
|
* author_name: string,
|
|
* context: string,
|
|
* sort_order: int,
|
|
* is_featured: bool,
|
|
* published_at: string
|
|
* }>
|
|
*/
|
|
private const EXPECTED_TESTIMONIALS = [
|
|
[
|
|
'quote' => "Mi, quero agradecer você e a sua equipe por todo empenho, atenção, vocês são abençoadas.\n\nEra nítida sua preocupação em garantir que todos os detalhes planejados desta comemoração, fossem atendidos.\n\nQue você possa transformar o grande dia das noivinhas sempre com essa sua leveza!!!\n\nMuito obrigada!",
|
|
'author_name' => 'Jeniffer e Maick',
|
|
'context' => 'Casamento · 06/12/2025',
|
|
'sort_order' => 1,
|
|
'is_featured' => true,
|
|
'published_at' => '2026-08-05 00:00:00',
|
|
],
|
|
[
|
|
'quote' => "Mi, eu não tenho palavras pra agradecer você e tudo que você fez por mim e por nós na realização desse sonho. Eu tô ainda extasiada com tudo que aconteceu hoje; mas tenho certeza que sem a sua ajuda, muita coisa não aconteceria.\n\nObrigada por tudo !",
|
|
'author_name' => 'Quesia e Jhonata',
|
|
'context' => 'Casamento · 21/12/2025',
|
|
'sort_order' => 2,
|
|
'is_featured' => true,
|
|
'published_at' => '2026-08-05 00:00:00',
|
|
],
|
|
[
|
|
'quote' => 'Que equipe!! Que equipe maravilhosa!! Obrigado pelo empenho de fazer tudo como eu queria!! Obrigado por se esforçar tanto e vir de tão longe pra realizar meu sonho!! Incríveis!!',
|
|
'author_name' => 'Milena e Weslley',
|
|
'context' => 'Casamento · 13/02/2026',
|
|
'sort_order' => 3,
|
|
'is_featured' => false,
|
|
'published_at' => '2026-08-05 00:00:00',
|
|
],
|
|
[
|
|
'quote' => "Gostaríamos de agradecer por todo o acompanhamento e dedicação durante a realização do nosso casamento. Foi um dia muito especial e inesquecível para nós.\n\nDesde o início, conseguimos conduzir tudo aquilo que estávamos planejando, dentro dos horários que estipulamos, o que foi ótimo, e no grande dia sua equipe nos recebeu e tratou com muito carinho, atenção e cuidado, o que fez toda a diferença para vivermos esse momento com mais tranquilidade.\n\nTambém adoramos as sugestões e ideias para as fotos, que deixaram os registros ainda mais bonitos e espontâneos, porque não iríamos lembrar de quais poses fazer na hora.\n\nObrigada por fazer parte de um momento tão importante das nossas vidas. Desejamos muito sucesso e que muitos outros casais possam viver dias especiais através do trabalho da AMARE.",
|
|
'author_name' => 'Raquel e Pedro',
|
|
'context' => 'Casamento · 09/05/2026',
|
|
'sort_order' => 4,
|
|
'is_featured' => false,
|
|
'published_at' => '2026-08-05 00:00:00',
|
|
],
|
|
[
|
|
'quote' => "Miiii, meu amor… você e sua equipe foram impecáveis.\n\nSuperou todas as nossas expectativas. Somos eternamente gratos por fazer nosso dia acontecer muito melhor do que imaginávamos.\n\nSempre muito atenciosa e paciente.\n\nAdoramos te conhecer e estamos muito felizes em termos escolhido você para assessorar nosso dia.",
|
|
'author_name' => 'Victoria e Pedro',
|
|
'context' => 'Casamento · 24/06/2026',
|
|
'sort_order' => 5,
|
|
'is_featured' => false,
|
|
'published_at' => '2026-08-05 00:00:00',
|
|
],
|
|
];
|
|
|
|
public function test_published_scope_excludes_unpublished_testimonials(): void
|
|
{
|
|
Testimonial::factory()->create(['published_at' => null]);
|
|
$published = Testimonial::factory()->published()->create();
|
|
|
|
$this->assertCount(1, Testimonial::query()->published()->get());
|
|
$this->assertTrue(Testimonial::query()->published()->first()?->is($published));
|
|
}
|
|
|
|
public function test_featured_testimonials_are_filterable(): void
|
|
{
|
|
Testimonial::factory()->create(['is_featured' => false]);
|
|
$featured = Testimonial::factory()->featured()->create();
|
|
|
|
$results = Testimonial::query()->where('is_featured', true)->get();
|
|
|
|
$this->assertCount(1, $results);
|
|
$this->assertTrue($results->first()?->is($featured));
|
|
}
|
|
|
|
public function test_assistant_cannot_access_testimonials_resource(): void
|
|
{
|
|
$assistant = User::factory()->assistant()->create();
|
|
|
|
$this->actingAs($assistant);
|
|
|
|
Livewire::test(ListTestimonials::class)
|
|
->assertForbidden();
|
|
}
|
|
|
|
public function test_testimonials_seeder_maps_all_five_real_couples_from_depoimentos(): void
|
|
{
|
|
$this->runTestimonialsSeeder();
|
|
|
|
$testimonials = Testimonial::query()
|
|
->orderBy('sort_order')
|
|
->get()
|
|
->map(fn (Testimonial $testimonial): array => $this->sourceOwnedState($testimonial))
|
|
->all();
|
|
|
|
$this->assertSame(self::EXPECTED_TESTIMONIALS, $testimonials);
|
|
}
|
|
|
|
public function test_content_seeder_loads_five_real_couples_from_depoimentos(): void
|
|
{
|
|
Storage::fake('public');
|
|
|
|
$this->artisan('db:seed', [
|
|
'--class' => ContentSeeder::class,
|
|
'--no-interaction' => true,
|
|
])->assertExitCode(0);
|
|
|
|
$authors = Testimonial::query()->orderBy('sort_order')->pluck('author_name')->all();
|
|
|
|
$this->assertSame([
|
|
'Jeniffer e Maick',
|
|
'Quesia e Jhonata',
|
|
'Milena e Weslley',
|
|
'Raquel e Pedro',
|
|
'Victoria e Pedro',
|
|
], $authors);
|
|
|
|
$jeniffer = Testimonial::query()->where('author_name', 'Jeniffer e Maick')->first();
|
|
|
|
$this->assertNotNull($jeniffer);
|
|
$this->assertStringContainsString('Mi, quero agradecer', (string) $jeniffer->quote);
|
|
$this->assertStringContainsString("\n\n", (string) $jeniffer->quote);
|
|
$this->assertSame('Casamento · 06/12/2025', $jeniffer->context);
|
|
}
|
|
|
|
public function test_testimonials_seeder_authoritatively_overwrites_source_owned_fields(): void
|
|
{
|
|
$testimonial = Testimonial::factory()->create([
|
|
'quote' => 'Depoimento desatualizado.',
|
|
'author_name' => 'Jeniffer e Maick',
|
|
'context' => 'Contexto desatualizado',
|
|
'sort_order' => 99,
|
|
'is_featured' => false,
|
|
'published_at' => null,
|
|
]);
|
|
|
|
$this->runTestimonialsSeeder();
|
|
|
|
$this->assertSame(
|
|
self::EXPECTED_TESTIMONIALS[0],
|
|
$this->sourceOwnedState($testimonial->refresh()),
|
|
);
|
|
}
|
|
|
|
public function test_testimonials_seeder_preserves_curated_photo_fields_for_known_author(): void
|
|
{
|
|
$testimonial = Testimonial::factory()->create([
|
|
'author_name' => 'Jeniffer e Maick',
|
|
'photo_path' => 'testimonials/jeniffer-e-maick.jpg',
|
|
'photo_alt' => 'Jeniffer e Maick durante o casamento',
|
|
]);
|
|
|
|
$this->runTestimonialsSeeder();
|
|
|
|
$testimonial->refresh();
|
|
|
|
$this->assertSame('testimonials/jeniffer-e-maick.jpg', $testimonial->photo_path);
|
|
$this->assertSame('Jeniffer e Maick durante o casamento', $testimonial->photo_alt);
|
|
}
|
|
|
|
public function test_testimonials_seeder_leaves_unrelated_testimonials_unchanged(): void
|
|
{
|
|
$unrelated = Testimonial::factory()->published()->featured()->create([
|
|
'quote' => 'Depoimento cadastrado pela equipe.',
|
|
'author_name' => 'Casal não presente na fonte',
|
|
'context' => 'Bodas · 02/08/2026',
|
|
'photo_path' => 'testimonials/casal-equipe.jpg',
|
|
'photo_alt' => 'Casal cadastrado pela equipe',
|
|
'sort_order' => 42,
|
|
]);
|
|
$originalState = $unrelated->getAttributes();
|
|
ksort($originalState);
|
|
|
|
$this->runTestimonialsSeeder();
|
|
|
|
$persisted = $unrelated->fresh();
|
|
|
|
$this->assertNotNull($persisted);
|
|
$persistedState = $persisted->getAttributes();
|
|
ksort($persistedState);
|
|
|
|
$this->assertSame($originalState, $persistedState);
|
|
}
|
|
|
|
public function test_testimonials_seeder_is_idempotent_without_duplicate_authors(): void
|
|
{
|
|
$this->runTestimonialsSeeder();
|
|
$firstRunState = Testimonial::query()
|
|
->orderBy('id')
|
|
->get()
|
|
->map(fn (Testimonial $testimonial): array => $testimonial->getAttributes())
|
|
->all();
|
|
|
|
$this->runTestimonialsSeeder();
|
|
|
|
$secondRunState = Testimonial::query()
|
|
->orderBy('id')
|
|
->get()
|
|
->map(fn (Testimonial $testimonial): array => $testimonial->getAttributes())
|
|
->all();
|
|
|
|
$this->assertCount(5, $secondRunState);
|
|
$this->assertSame($firstRunState, $secondRunState);
|
|
$this->assertSame(5, Testimonial::query()->distinct()->count('author_name'));
|
|
}
|
|
|
|
public function test_home_renders_multi_paragraph_testimonial_quotes(): void
|
|
{
|
|
SiteSetting::instance();
|
|
|
|
Testimonial::factory()->published()->featured()->create([
|
|
'quote' => "Primeiro parágrafo do depoimento.\n\nSegundo parágrafo com continuidade.",
|
|
'author_name' => 'Casal Exemplo',
|
|
'context' => 'Casamento · 01/01/2026',
|
|
]);
|
|
|
|
$response = $this->get(route('home'));
|
|
|
|
$response->assertOk();
|
|
$response->assertSee('Primeiro parágrafo do depoimento.', false);
|
|
$response->assertSee('Segundo parágrafo com continuidade.', false);
|
|
$response->assertDontSee(
|
|
'Primeiro parágrafo do depoimento. Segundo parágrafo com continuidade.',
|
|
false,
|
|
);
|
|
}
|
|
|
|
private function runTestimonialsSeeder(): void
|
|
{
|
|
$this->artisan('db:seed', [
|
|
'--class' => TestimonialsSeeder::class,
|
|
'--no-interaction' => true,
|
|
])->assertExitCode(0);
|
|
}
|
|
|
|
/**
|
|
* @return array{
|
|
* quote: string,
|
|
* author_name: string,
|
|
* context: string,
|
|
* sort_order: int,
|
|
* is_featured: bool,
|
|
* published_at: string
|
|
* }
|
|
*/
|
|
private function sourceOwnedState(Testimonial $testimonial): array
|
|
{
|
|
return [
|
|
'quote' => (string) $testimonial->quote,
|
|
'author_name' => (string) $testimonial->author_name,
|
|
'context' => (string) $testimonial->context,
|
|
'sort_order' => (int) $testimonial->sort_order,
|
|
'is_featured' => (bool) $testimonial->is_featured,
|
|
'published_at' => $testimonial->published_at?->format('Y-m-d H:i:s') ?? '',
|
|
];
|
|
}
|
|
}
|