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>
113 lines
3.7 KiB
PHP
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();
|
|
}
|
|
}
|