Files
landing-api/tests/Feature/Panel/TranslationAssistantTest.php
Josep Piguillem 6fc600e6a1 Add a translation assistant to the panel
Each field's original sits beside the field to write, and a translation that
fell behind shows what the original said when it was translated and what it
says now, word by word.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 10:53:31 +02:00

113 lines
3.7 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Feature\Panel;
use App\Filament\Pages\TranslationAssistant;
use App\Models\Page;
use App\Support\TextDiff;
use App\Support\TranslationFreshness;
use Database\Seeders\RolePermissionSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use PHPUnit\Framework\Attributes\Test;
use Tests\FakesPireon;
use Tests\TestCase;
class TranslationAssistantTest extends TestCase
{
use FakesPireon, RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->seed(RolePermissionSeeder::class);
}
#[Test]
public function the_list_offers_each_missing_language(): void
{
$this->actingAs($this->userWithRoles('editor'));
Page::factory()->draft()->create(['title' => ['es' => 'Solo en castellano'], 'slug' => ['es' => 'solo']]);
Livewire::test(TranslationAssistant::class)
->assertSee('Solo en castellano')
->assertSee('Traducir al English');
}
#[Test]
public function a_translation_is_written_beside_the_original(): void
{
$this->actingAs($this->userWithRoles('editor'));
$page = Page::factory()->draft()->create([
'title' => ['es' => 'Hola'],
'slug' => ['es' => 'hola'],
'excerpt' => ['es' => 'Un extracto.'],
'body' => ['es' => '<p>Cuerpo.</p>'],
'meta_title' => null,
'meta_description' => null,
]);
Livewire::withQueryParams(['type' => 'pages', 'record' => $page->id, 'locale' => 'en'])
->test(TranslationAssistant::class)
->assertSee('Un extracto.')
->fillForm(['title' => 'Hello', 'excerpt' => 'An excerpt.'])
->call('save')
->assertHasNoFormErrors();
$page->refresh();
$this->assertSame('Hello', $page->getTranslation('title', 'en'));
$this->assertSame('An excerpt.', $page->getTranslation('excerpt', 'en'));
// The original is untouched.
$this->assertSame('Hola', $page->getTranslation('title', 'es'));
}
#[Test]
public function a_translation_left_behind_shows_what_changed_in_the_original(): void
{
$this->actingAs($this->userWithRoles('editor'));
$this->travelTo('2026-09-01 10:00');
$page = Page::factory()->draft()->create([
'title' => ['es' => 'Hola', 'en' => 'Hello'],
'slug' => ['es' => 'hola', 'en' => 'hello'],
'excerpt' => ['es' => 'Hacemos webs pequeñas.', 'en' => 'We make small websites.'],
]);
$this->travelTo('2026-09-10 10:00');
$page->update(['excerpt' => ['es' => 'Hacemos webs pequeñas y rápidas.', 'en' => 'We make small websites.']]);
$stale = TranslationFreshness::staleFields($page->fresh(), 'en');
$this->assertSame(['excerpt'], array_keys($stale));
$this->assertSame('Hacemos webs pequeñas.', $stale['excerpt']['was']);
Livewire::withQueryParams(['type' => 'pages', 'record' => $page->id, 'locale' => 'en'])
->test(TranslationAssistant::class)
->assertSeeHtml('<del>pequeñas.</del> <ins>pequeñas y rápidas.</ins>');
}
#[Test]
public function the_diff_marks_words_in_and_out(): void
{
$this->assertSame('Hacemos webs <del>pequeñas.</del> <ins>rápidas.</ins>', TextDiff::html('Hacemos webs pequeñas.', 'Hacemos webs rápidas.'));
}
#[Test]
public function only_who_may_edit_it_may_translate_it(): void
{
$this->actingAs($this->userWithRoles('viewer'));
$page = Page::factory()->create();
Livewire::withQueryParams(['type' => 'pages', 'record' => $page->id, 'locale' => 'en'])
->test(TranslationAssistant::class)
->assertForbidden();
}
}