Add translation CRUD routes and controller
POST/DELETE for translations gated by can:update,document middleware. Locale validated against SUPPORTED_LOCALES. Default-locale deletion returns 422; duplicate-locale add returns 422. Flash messages added to en/ja lang files (other locales updated in Task 9).
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\Document;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class DocumentTranslationCrudTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_owner_can_add_a_translation(): void
|
||||
{
|
||||
$owner = User::factory()->create();
|
||||
$doc = Document::factory()->create(['default_locale' => 'en', 'created_by' => $owner->id]);
|
||||
|
||||
$response = $this->actingAs($owner)->post(
|
||||
route('documents.translations.store', $doc),
|
||||
['locale' => 'ja', 'title' => 'こんにちは', 'content' => '本文']
|
||||
);
|
||||
|
||||
$response->assertRedirect();
|
||||
$this->assertNotNull($doc->fresh()->translationFor('ja', false));
|
||||
}
|
||||
|
||||
public function test_non_owner_cannot_add_translation(): void
|
||||
{
|
||||
$owner = User::factory()->create();
|
||||
$other = User::factory()->create();
|
||||
$doc = Document::factory()->create(['default_locale' => 'en', 'created_by' => $owner->id]);
|
||||
|
||||
$response = $this->actingAs($other)->post(
|
||||
route('documents.translations.store', $doc),
|
||||
['locale' => 'ja', 'title' => 'こんにちは', 'content' => '本文']
|
||||
);
|
||||
|
||||
$response->assertForbidden();
|
||||
}
|
||||
|
||||
public function test_invalid_locale_is_rejected(): void
|
||||
{
|
||||
$owner = User::factory()->create();
|
||||
$doc = Document::factory()->create(['default_locale' => 'en', 'created_by' => $owner->id]);
|
||||
|
||||
$response = $this->actingAs($owner)->post(
|
||||
route('documents.translations.store', $doc),
|
||||
['locale' => 'xx', 'title' => 'X', 'content' => 'Y']
|
||||
);
|
||||
|
||||
$response->assertSessionHasErrors('locale');
|
||||
}
|
||||
|
||||
public function test_duplicate_locale_returns_422(): void
|
||||
{
|
||||
$owner = User::factory()->create();
|
||||
$doc = Document::factory()->create(['default_locale' => 'en', 'created_by' => $owner->id]);
|
||||
|
||||
$response = $this->actingAs($owner)->post(
|
||||
route('documents.translations.store', $doc),
|
||||
['locale' => 'en', 'title' => 'X', 'content' => 'Y']
|
||||
);
|
||||
|
||||
$response->assertStatus(422);
|
||||
}
|
||||
|
||||
public function test_owner_can_delete_non_default_translation(): void
|
||||
{
|
||||
$owner = User::factory()->create();
|
||||
$doc = Document::factory()->create(['default_locale' => 'en', 'created_by' => $owner->id]);
|
||||
app(\App\Services\DocumentService::class)->addTranslation($doc, 'ja', 'JA', 'body', $owner->id);
|
||||
|
||||
$response = $this->actingAs($owner)->delete(
|
||||
route('documents.translations.destroy', ['document' => $doc, 'locale' => 'ja'])
|
||||
);
|
||||
|
||||
$response->assertRedirect();
|
||||
$this->assertNull($doc->fresh()->translationFor('ja', false));
|
||||
}
|
||||
|
||||
public function test_default_locale_translation_cannot_be_deleted(): void
|
||||
{
|
||||
$owner = User::factory()->create();
|
||||
$doc = Document::factory()->create(['default_locale' => 'en', 'created_by' => $owner->id]);
|
||||
|
||||
$response = $this->actingAs($owner)->delete(
|
||||
route('documents.translations.destroy', ['document' => $doc, 'locale' => 'en'])
|
||||
);
|
||||
|
||||
$response->assertStatus(422);
|
||||
$this->assertNotNull($doc->fresh()->translationFor('en', false));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user