156 lines
5.5 KiB
PHP
156 lines
5.5 KiB
PHP
<?php
|
|
|
|
use App\Enums\Portal;
|
|
use App\Models\Category;
|
|
use App\Models\PressRelease;
|
|
use App\Models\User;
|
|
use Database\Seeders\RolesAndPermissionsSeeder;
|
|
use Livewire\Volt\Volt as LivewireVolt;
|
|
use Tests\TestCase;
|
|
|
|
beforeEach(function (): void {
|
|
/** @var TestCase $this */
|
|
$this->seed(RolesAndPermissionsSeeder::class);
|
|
|
|
$admin = User::factory()->create(['is_active' => true]);
|
|
$admin->assignRole('admin');
|
|
$this->actingAs($admin);
|
|
});
|
|
|
|
test('admin can render category create page', function () {
|
|
/** @var TestCase $this */
|
|
$this->get(route('admin.categories.create'))
|
|
->assertSuccessful()
|
|
->assertSee('Kategorie anlegen');
|
|
});
|
|
|
|
test('admin can create a new category with both translations', function () {
|
|
LivewireVolt::test('admin.categories.create')
|
|
->set('portal', Portal::Both->value)
|
|
->set('nameDe', 'Künstliche Intelligenz')
|
|
->set('nameEn', 'Artificial Intelligence')
|
|
->set('descriptionDe', 'Themen rund um KI.')
|
|
->set('descriptionEn', 'Topics around AI.')
|
|
->call('save')
|
|
->assertHasNoErrors()
|
|
->assertRedirect(route('admin.categories.index'));
|
|
|
|
$category = Category::query()->latest('id')->firstOrFail();
|
|
|
|
expect($category->portal)->toBe(Portal::Both);
|
|
expect($category->is_active)->toBeTrue();
|
|
expect($category->translations()->count())->toBe(2);
|
|
|
|
$de = $category->translations->firstWhere('locale', 'de');
|
|
$en = $category->translations->firstWhere('locale', 'en');
|
|
|
|
expect($de->name)->toBe('Künstliche Intelligenz');
|
|
expect($de->slug)->toBe('kunstliche-intelligenz');
|
|
expect($en->slug)->toBe('artificial-intelligence');
|
|
});
|
|
|
|
test('category create requires both names', function () {
|
|
LivewireVolt::test('admin.categories.create')
|
|
->set('nameDe', '')
|
|
->set('nameEn', '')
|
|
->call('save')
|
|
->assertHasErrors(['nameDe', 'nameEn']);
|
|
});
|
|
|
|
test('category create generates unique slug per locale on collision', function () {
|
|
$existing = Category::factory()->create(['portal' => Portal::Both->value]);
|
|
$existing->translations()->createMany([
|
|
['locale' => 'de', 'name' => 'Wirtschaft', 'slug' => 'wirtschaft'],
|
|
['locale' => 'en', 'name' => 'Business', 'slug' => 'business'],
|
|
]);
|
|
|
|
LivewireVolt::test('admin.categories.create')
|
|
->set('nameDe', 'Wirtschaft')
|
|
->set('nameEn', 'Business')
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
$newCategory = Category::query()->latest('id')->firstOrFail();
|
|
$de = $newCategory->translations->firstWhere('locale', 'de');
|
|
$en = $newCategory->translations->firstWhere('locale', 'en');
|
|
|
|
expect($de->slug)->toBe('wirtschaft-2');
|
|
expect($en->slug)->toBe('business-2');
|
|
});
|
|
|
|
test('admin can edit an existing category and rename slugs in place', function () {
|
|
$category = Category::factory()->create(['portal' => Portal::Both->value]);
|
|
$category->translations()->createMany([
|
|
['locale' => 'de', 'name' => 'Alter Name', 'slug' => 'alter-name'],
|
|
['locale' => 'en', 'name' => 'Old Name', 'slug' => 'old-name'],
|
|
]);
|
|
|
|
LivewireVolt::test('admin.categories.edit', ['id' => $category->id])
|
|
->set('nameDe', 'Neuer Name')
|
|
->set('slugDe', 'neuer-name')
|
|
->set('nameEn', 'New Name')
|
|
->set('slugEn', 'new-name')
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
$category->refresh()->load('translations');
|
|
$de = $category->translations->firstWhere('locale', 'de');
|
|
$en = $category->translations->firstWhere('locale', 'en');
|
|
|
|
expect($de->slug)->toBe('neuer-name');
|
|
expect($en->slug)->toBe('new-name');
|
|
});
|
|
|
|
test('category edit refuses parent assignment that would create a hierarchy loop', function () {
|
|
$parent = Category::factory()->create();
|
|
$parent->translations()->createMany([
|
|
['locale' => 'de', 'name' => 'Parent', 'slug' => 'parent'],
|
|
['locale' => 'en', 'name' => 'Parent', 'slug' => 'parent-en'],
|
|
]);
|
|
|
|
$child = Category::factory()->create(['parent_id' => $parent->id]);
|
|
$child->translations()->createMany([
|
|
['locale' => 'de', 'name' => 'Child', 'slug' => 'child'],
|
|
['locale' => 'en', 'name' => 'Child', 'slug' => 'child-en'],
|
|
]);
|
|
|
|
LivewireVolt::test('admin.categories.edit', ['id' => $parent->id])
|
|
->set('nameDe', 'Parent')
|
|
->set('slugDe', 'parent')
|
|
->set('nameEn', 'Parent')
|
|
->set('slugEn', 'parent-en')
|
|
->set('parentId', $child->id)
|
|
->call('save')
|
|
->assertHasErrors(['parentId']);
|
|
});
|
|
|
|
test('category cannot be deleted while it has press releases', function () {
|
|
$category = Category::factory()->create();
|
|
$category->translations()->createMany([
|
|
['locale' => 'de', 'name' => 'Used', 'slug' => 'used'],
|
|
['locale' => 'en', 'name' => 'Used', 'slug' => 'used-en'],
|
|
]);
|
|
|
|
PressRelease::factory()->create([
|
|
'category_id' => $category->id,
|
|
]);
|
|
|
|
LivewireVolt::test('admin.categories.edit', ['id' => $category->id])
|
|
->call('deleteCategory');
|
|
|
|
expect(Category::query()->find($category->id))->not->toBeNull();
|
|
});
|
|
|
|
test('category can be deleted when empty', function () {
|
|
$category = Category::factory()->create();
|
|
$category->translations()->createMany([
|
|
['locale' => 'de', 'name' => 'Empty', 'slug' => 'empty'],
|
|
['locale' => 'en', 'name' => 'Empty', 'slug' => 'empty-en'],
|
|
]);
|
|
|
|
LivewireVolt::test('admin.categories.edit', ['id' => $category->id])
|
|
->call('deleteCategory')
|
|
->assertRedirect(route('admin.categories.index'));
|
|
|
|
expect(Category::query()->find($category->id))->toBeNull();
|
|
});
|