# Testing Guidelines - Feature Tests Dokumentasi ini merangkum aturan dan pola standard dalam pembuatan feature test di proyek ini. Semua test baru (misal: module Order) **harus** mengikuti struktur ini untuk menjaga konsistensi. ## 1. Teknologi & Lokasi - **Framework**: [Pest PHP](https://pestphp.com/) - **Lokasi**: `tests/Feature/Admin/Master/` (atau folder yang relevan sesuai grouping menu). - **Penamaan File**: `[Name]Test.php` (Contoh: `OrderTest.php`). ## 2. Struktur Dasar (Describe Blocks) Setiap file test harus dibagi menjadi minimal 3 blok `describe`: ### A. Authorization Digunakan untuk mengetes akses dasar (apakah sudah login dan apakah punya izin minimal untuk melihat index). ```php describe('Order Module - Authorization', function () { it('redirects to login when accessing order index unauthenticated', function () { get(route('order.index'))->assertRedirect(route('login')); }); it('returns 403 when user has no permission to view orders', function () { actingAs(createUnauthorizedUser()) ->get(route('order.index')) ->assertStatus(403); }); }); ``` ### B. Authorized Actions Blok utama untuk mengetes fitur CRUD dan fitur spesifik lainnya. Gunakan `beforeEach` untuk setup user dengan permissions lengkap. ```php describe('Order Module - Authorized Actions', function () { beforeEach(function () { $user = createAuthorizedUser([ 'View:Order', 'Create:Order', 'Edit:Order', 'Delete:Order', 'DeleteAny:Order', 'ToggleStatus:Order', // Jika ada status ]); actingAs($user); }); // Test cases go here... }); ``` ### C. Unauthorized Actions Mengetes restriksi akses untuk user yang sudah login tapi tidak punya permission spesifik untuk aksi tertentu. ```php describe('Order Module - Unauthorized Actions', function () { beforeEach(function () { actingAs(createUnauthorizedUser()); }); it('cannot store an order without permission', function () { postJson(route('order.store'), [])->assertStatus(403); }); // ... dst untuk update, delete, toggleStatus }); ``` ## 3. Pola Testing Fitur Standard ### Page Visits (Inertia) Gunakan `assertInertia` untuk mengecek komponen dan ketersediaan data (props). ```php it('can access order index page', function () { get(route('order.index')) ->assertOk() ->assertInertia(fn ($page) => $page ->component('admin/transaction/order/index') // path component ->has('orders') // mengecek prop data ); }); ``` ### Store / Update - Gunakan `postJson` atau `patchJson`. - Cek redirect, session success, dan keberadaan data di database. ```php it('can store a new order', function () { $data = [ /* dummy data */ ]; postJson(route('order.store'), $data) ->assertRedirect() ->assertSessionHas('success'); assertDatabaseHas('orders', ['field' => 'value']); }); ``` ### Validation Tes skenario input kosong atau salah format untuk memastikan `Request` bekerja. ```php it('validates order creation', function () { postJson(route('order.store'), []) ->assertStatus(422) ->assertJsonValidationErrors(['required_field']); }); ``` ### Delete & Bulk Delete - Pastikan menggunakan `assertSoftDeleted` jika model menggunakan SoftDeletes. - Untuk bulk, kirim array `ids`. ```php it('can delete orders in bulk', function () { $ids = Order::factory()->count(3)->create()->pluck('id')->toArray(); deleteJson(route('order.bulkDestroy'), ['ids' => $ids]) ->assertRedirect() ->assertSessionHas('success'); foreach ($ids as $id) { assertSoftDeleted('orders', ['id' => $id]); } }); ``` ### Toggle Status Cek perubahan nilai di database setelah request. ```php it('can toggle order status', function () { $order = Order::factory()->create(['is_active' => true]); patchJson(route('order.toggleStatus', $order))->assertRedirect(); expect($order->fresh()->is_active)->toBeFalse(); }); ``` ## 4. Fitur Spesifik Module (Aturan Tambahan) Jika module memiliki fitur unik (seperti `Order` yang mungkin punya stok atau perhitungan subtotal), tambahkan test case khusus namun tetap ikuti style yang sama: - **Relasi**: Jika menyimpan data ke tabel relasi (seperti `OrderItems`), gunakan `assertDatabaseHas` untuk tabel tersebut. - **File Upload**: Gunakan `Storage::fake()` dan `UploadedFile::fake()`. - **Logic Bisnis**: Jika ada logic otomatis (misal: stok berkurang), cek kondisi database sebelum dan sesudah aksi. ## 5. Helper Functions (Tersedia di `tests/Pest.php`) - `createAuthorizedUser(array $permissions)`: Membuat user dan memberikan permissions. - `createUnauthorizedUser()`: Membuat user tanpa permissions tambahan.