feat(faq): implemntasi testing
- kasih return type - menyesuaikan factory - mengganti modalName - menyesuaikan seeder - menyesuaikan panggil component
This commit is contained in:
parent
c75d750de0
commit
77d91b977f
@ -27,7 +27,7 @@ public function columns(): array
|
||||
|
||||
if (auth()->user()->can('update faq')) {
|
||||
if ($row->sort_order > 1) {
|
||||
$actions .= view('components.datatables.sort-button', [
|
||||
$actions .= view('components.actions.table.sort-button', [
|
||||
'id' => $row->hash,
|
||||
'module' => 'faq',
|
||||
'direction' => 'up',
|
||||
@ -36,7 +36,7 @@ public function columns(): array
|
||||
'icon' => 'arrow-up',
|
||||
])->render();
|
||||
|
||||
$actions .= view('components.datatables.sort-button', [
|
||||
$actions .= view('components.actions.table.sort-button', [
|
||||
'id' => $row->hash,
|
||||
'module' => 'faq',
|
||||
'direction' => 'first',
|
||||
@ -47,7 +47,7 @@ public function columns(): array
|
||||
}
|
||||
|
||||
if ($row->sort_order < $maxSortOrder) {
|
||||
$actions .= view('components.datatables.sort-button', [
|
||||
$actions .= view('components.actions.table.sort-button', [
|
||||
'id' => $row->hash,
|
||||
'module' => 'faq',
|
||||
'direction' => 'down',
|
||||
@ -56,7 +56,7 @@ public function columns(): array
|
||||
'icon' => 'arrow-down',
|
||||
])->render();
|
||||
|
||||
$actions .= view('components.datatables.sort-button', [
|
||||
$actions .= view('components.actions.table.sort-button', [
|
||||
'id' => $row->hash,
|
||||
'module' => 'faq',
|
||||
'direction' => 'last',
|
||||
@ -68,7 +68,7 @@ public function columns(): array
|
||||
}
|
||||
|
||||
if (auth()->user()->can('update faq')) {
|
||||
$actions .= view('components.datatables.edit-modal', [
|
||||
$actions .= view('components.actions.table.edit-modal', [
|
||||
'id' => $row->hash,
|
||||
'method' => 'update',
|
||||
'modalTitle' => 'Ubah FAQs',
|
||||
@ -76,9 +76,8 @@ public function columns(): array
|
||||
}
|
||||
|
||||
if (auth()->user()->can('delete faq')) {
|
||||
$actions .= view('components.datatables.delete', [
|
||||
$actions .= view('components.actions.table.delete', [
|
||||
'id' => $row->hash,
|
||||
'deleteRoute' => route('studio.information.faq.delete', $row->hash),
|
||||
])->render();
|
||||
}
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
use App\Traits\WithToast;
|
||||
use App\Traits\WithUpdatedData;
|
||||
use Flux\Flux;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\Attributes\Title;
|
||||
use Livewire\Component;
|
||||
@ -26,21 +27,7 @@ class Faq extends Component
|
||||
|
||||
public string $modalTitle = '';
|
||||
|
||||
#[On('modal:open')]
|
||||
public function openModal(string $method, string $modalTitle, ?string $id = null)
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetErrorBag();
|
||||
|
||||
$this->method = $method;
|
||||
$this->modalTitle = $modalTitle;
|
||||
|
||||
if ($id) {
|
||||
$this->form->setFaq(FaqModel::byHashOrFail($id));
|
||||
}
|
||||
}
|
||||
|
||||
public function create()
|
||||
public function create(): void
|
||||
{
|
||||
$this->canOrAbort('create faq');
|
||||
|
||||
@ -53,7 +40,7 @@ public function create()
|
||||
Flux::modals()->close();
|
||||
}
|
||||
|
||||
public function update()
|
||||
public function update(): void
|
||||
{
|
||||
$this->canOrAbort('update faq');
|
||||
|
||||
@ -66,8 +53,10 @@ public function update()
|
||||
Flux::modals()->close();
|
||||
}
|
||||
|
||||
public function delete(FaqModel $faq)
|
||||
public function delete(FaqModel $faq): void
|
||||
{
|
||||
$this->canOrAbort('delete faq');
|
||||
|
||||
$this->form->faq = $faq;
|
||||
|
||||
$this->form->delete();
|
||||
@ -80,7 +69,7 @@ public function delete(FaqModel $faq)
|
||||
}
|
||||
|
||||
#[On('fn:sortOrder')]
|
||||
public function sortOrder(FaqModel $faq, string $direction)
|
||||
public function sortOrder(FaqModel $faq, string $direction): void
|
||||
{
|
||||
$this->canOrAbort('update faq');
|
||||
|
||||
@ -91,7 +80,21 @@ public function sortOrder(FaqModel $faq, string $direction)
|
||||
$this->dispatch('refreshDatatable');
|
||||
}
|
||||
|
||||
public function render()
|
||||
#[On('modal:open')]
|
||||
public function openModal(string $method, string $modalTitle, ?string $id = null): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetErrorBag();
|
||||
|
||||
$this->method = $method;
|
||||
$this->modalTitle = $modalTitle;
|
||||
|
||||
if ($id) {
|
||||
$this->form->setFaq(FaqModel::byHashOrFail($id));
|
||||
}
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
{
|
||||
return view('livewire.studio.information.faqs', [
|
||||
'pageTitle' => 'FAQs',
|
||||
|
||||
@ -2,13 +2,14 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Veelasky\LaravelHashId\Eloquent\HashableId;
|
||||
|
||||
class Faq extends Model
|
||||
{
|
||||
use HashableId, SoftDeletes;
|
||||
use HasFactory, HashableId, SoftDeletes;
|
||||
|
||||
protected $guarded = ['id'];
|
||||
|
||||
|
||||
@ -12,8 +12,8 @@ class FaqFactory extends Factory
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'question' => $this->faker->sentence(6),
|
||||
'answer' => $this->faker->paragraph(),
|
||||
'question' => 'Sample FAQ question?',
|
||||
'answer' => 'This is a sample answer for the FAQ.',
|
||||
'sort_order' => $this->faker->numberBetween(1, 50),
|
||||
];
|
||||
}
|
||||
|
||||
@ -2,13 +2,14 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Faq;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class FaqSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
DB::table('faqs')->insert([
|
||||
Faq::insert([
|
||||
[
|
||||
'question' => 'Bagaimana cara memesan parfum di toko online ini?',
|
||||
'answer' => 'Cukup pilih parfum yang kamu suka, tambahkan ke keranjang, lalu lanjutkan ke pembayaran melalui metode yang tersedia.',
|
||||
|
||||
@ -19,13 +19,14 @@
|
||||
</div>
|
||||
|
||||
@include('components.modals.confirmation', [
|
||||
'modalName' => 'confirmation-modal',
|
||||
'modalName' => 'delete-confirmation',
|
||||
'modalTitle' => 'Apakah Anda yakin?',
|
||||
'modalMessage' => 'Data yang berelasi dengan data ini juga akan ikut terhapus.',
|
||||
'buttonVariant' => 'primary',
|
||||
'buttonColor' => 'danger',
|
||||
'buttonText' => 'Ya, Hapus',
|
||||
])
|
||||
|
||||
<flux:modal name="form-modal" class="w-[95%] max-w-sm md:max-w-xl mx-auto" @close="closeModal('form-modal')">
|
||||
<div class="p-4 space-y-6">
|
||||
<flux:heading size="lg">{{ $modalTitle }}</flux:heading>
|
||||
|
||||
194
tests/Feature/Livewire/Studio/Information/FaqTest.php
Normal file
194
tests/Feature/Livewire/Studio/Information/FaqTest.php
Normal file
@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Studio\Information\Faq;
|
||||
use App\Models\Faq as FaqModel;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
// Create permissions
|
||||
Permission::create(['name' => 'create faq', 'guard_name' => 'web']);
|
||||
Permission::create(['name' => 'update faq', 'guard_name' => 'web']);
|
||||
Permission::create(['name' => 'delete faq', 'guard_name' => 'web']);
|
||||
|
||||
// Create role and assign permissions
|
||||
$role = Role::create(['name' => 'Admin', 'guard_name' => 'web']);
|
||||
$role->givePermissionTo(['create faq', 'update faq', 'delete faq']);
|
||||
|
||||
// Create admin user
|
||||
$this->adminUser = User::factory()->create();
|
||||
$this->adminUser->assignRole('Admin');
|
||||
});
|
||||
|
||||
it('renders page successfully', function () {
|
||||
Livewire::actingAs($this->adminUser)
|
||||
->test(Faq::class)
|
||||
->assertOk()
|
||||
->assertSet('method', 'create')
|
||||
->assertSet('modalTitle', '')
|
||||
->assertSee('FAQs');
|
||||
});
|
||||
|
||||
it('has title attribute', function () {
|
||||
$component = new Faq;
|
||||
$reflection = new \ReflectionClass($component);
|
||||
$attributes = $reflection->getAttributes(\Livewire\Attributes\Title::class);
|
||||
|
||||
expect($attributes)->not->toBeEmpty();
|
||||
});
|
||||
|
||||
it('opens modal for create', function () {
|
||||
Livewire::actingAs($this->adminUser)
|
||||
->test(Faq::class)
|
||||
->call('openModal', 'create', 'Tambah FAQs')
|
||||
->assertSet('method', 'create')
|
||||
->assertSet('modalTitle', 'Tambah FAQs')
|
||||
->assertSet('form.question', '')
|
||||
->assertSet('form.answer', '');
|
||||
});
|
||||
|
||||
it('opens modal for update', function () {
|
||||
$faq = FaqModel::factory()->create([
|
||||
'question' => 'Test Question',
|
||||
'answer' => 'Test Answer',
|
||||
]);
|
||||
|
||||
Livewire::actingAs($this->adminUser)
|
||||
->test(Faq::class)
|
||||
->call('openModal', 'update', 'Ubah FAQs', $faq->hash)
|
||||
->assertSet('method', 'update')
|
||||
->assertSet('modalTitle', 'Ubah FAQs')
|
||||
->assertSet('form.question', 'Test Question')
|
||||
->assertSet('form.answer', 'Test Answer');
|
||||
});
|
||||
|
||||
it('creates faq successfully', function () {
|
||||
Livewire::actingAs($this->adminUser)
|
||||
->test(Faq::class)
|
||||
->set('form.question', 'What is Laravel?')
|
||||
->set('form.answer', 'Laravel is a PHP framework.')
|
||||
->call('create')
|
||||
->assertDispatched('refreshDatatable');
|
||||
|
||||
$this->assertDatabaseHas('faqs', [
|
||||
'question' => 'What is Laravel?',
|
||||
'answer' => 'Laravel is a PHP framework.',
|
||||
'sort_order' => 1,
|
||||
]);
|
||||
});
|
||||
|
||||
it('requires permission to create faq', function () {
|
||||
$userWithoutPermission = User::factory()->create();
|
||||
|
||||
Livewire::actingAs($userWithoutPermission)
|
||||
->test(Faq::class)
|
||||
->set('form.question', 'Test Question')
|
||||
->set('form.answer', 'Test Answer')
|
||||
->call('create')
|
||||
->assertForbidden();
|
||||
});
|
||||
|
||||
it('updates faq successfully', function () {
|
||||
$faq = FaqModel::factory()->create([
|
||||
'question' => 'Old Question',
|
||||
'answer' => 'Old Answer',
|
||||
]);
|
||||
|
||||
Livewire::actingAs($this->adminUser)
|
||||
->test(Faq::class)
|
||||
->call('openModal', 'update', 'Ubah FAQs', $faq->hash)
|
||||
->set('form.question', 'Updated Question')
|
||||
->set('form.answer', 'Updated Answer')
|
||||
->call('update')
|
||||
->assertDispatched('refreshDatatable');
|
||||
|
||||
$this->assertDatabaseHas('faqs', [
|
||||
'id' => $faq->id,
|
||||
'question' => 'Updated Question',
|
||||
'answer' => 'Updated Answer',
|
||||
]);
|
||||
});
|
||||
|
||||
it('requires permission to update faq', function () {
|
||||
$faq = FaqModel::factory()->create();
|
||||
$userWithoutPermission = User::factory()->create();
|
||||
|
||||
Livewire::actingAs($userWithoutPermission)
|
||||
->test(Faq::class)
|
||||
->call('openModal', 'update', 'Ubah FAQs', $faq->hash)
|
||||
->set('form.question', 'Updated Question')
|
||||
->set('form.answer', 'Updated Answer')
|
||||
->call('update')
|
||||
->assertForbidden();
|
||||
});
|
||||
|
||||
it('deletes faq successfully', function () {
|
||||
$faq = FaqModel::factory()->create();
|
||||
|
||||
Livewire::actingAs($this->adminUser)
|
||||
->test(Faq::class)
|
||||
->call('delete', $faq)
|
||||
->assertDispatched('refreshDatatable');
|
||||
|
||||
expect($faq->trashed())->toBeTrue();
|
||||
});
|
||||
|
||||
it('sorts order up', function () {
|
||||
$faq1 = FaqModel::factory()->create(['sort_order' => 1]);
|
||||
$faq2 = FaqModel::factory()->create(['sort_order' => 2]);
|
||||
|
||||
Livewire::actingAs($this->adminUser)
|
||||
->test(Faq::class)
|
||||
->call('sortOrder', $faq2, 'up')
|
||||
->assertDispatched('refreshDatatable');
|
||||
|
||||
expect($faq1->fresh()->sort_order)->toBe(2);
|
||||
expect($faq2->fresh()->sort_order)->toBe(1);
|
||||
});
|
||||
|
||||
it('sorts order down', function () {
|
||||
$faq1 = FaqModel::factory()->create(['sort_order' => 1]);
|
||||
$faq2 = FaqModel::factory()->create(['sort_order' => 2]);
|
||||
|
||||
Livewire::actingAs($this->adminUser)
|
||||
->test(Faq::class)
|
||||
->call('sortOrder', $faq1, 'down')
|
||||
->assertDispatched('refreshDatatable');
|
||||
|
||||
expect($faq1->fresh()->sort_order)->toBe(2);
|
||||
expect($faq2->fresh()->sort_order)->toBe(1);
|
||||
});
|
||||
|
||||
it('requires permission to sort order', function () {
|
||||
$faq = FaqModel::factory()->create();
|
||||
$userWithoutPermission = User::factory()->create();
|
||||
|
||||
Livewire::actingAs($userWithoutPermission)
|
||||
->test(Faq::class)
|
||||
->call('sortOrder', $faq, 'up')
|
||||
->assertForbidden();
|
||||
});
|
||||
|
||||
it('displays validation errors', function () {
|
||||
Livewire::actingAs($this->adminUser)
|
||||
->test(Faq::class)
|
||||
->set('form.question', '') // Empty question
|
||||
->set('form.answer', '') // Empty answer
|
||||
->call('create')
|
||||
->assertHasErrors(['form.question', 'form.answer']);
|
||||
});
|
||||
|
||||
it('opens modal correctly', function () {
|
||||
$faq = FaqModel::factory()->create();
|
||||
|
||||
Livewire::actingAs($this->adminUser)
|
||||
->test(Faq::class)
|
||||
->call('openModal', 'create', 'Tambah FAQs')
|
||||
->assertSet('method', 'create')
|
||||
->assertSet('modalTitle', 'Tambah FAQs');
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user