147 lines
4.7 KiB
PHP
147 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Complaints;
|
|
|
|
use App\Filament\Pages\Transactions\Complaints as ComplaintsPage;
|
|
use App\Models\User;
|
|
use App\Services\ComplaintService;
|
|
use Illuminate\Auth\Access\AuthorizationException;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Livewire\Livewire;
|
|
use Tests\Support\InsForgeFake;
|
|
use Tests\TestCase;
|
|
|
|
class ComplaintTest extends TestCase
|
|
{
|
|
private const CUSTOMER_ID = 'cccccccc-0000-0000-0000-000000000001';
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
InsForgeFake::reset();
|
|
InsForgeFake::fakeRest();
|
|
|
|
InsForgeFake::seed('customers', [
|
|
'id' => self::CUSTOMER_ID,
|
|
'customer_code' => 'CUST-0001',
|
|
'name' => 'Andi',
|
|
]);
|
|
}
|
|
|
|
private function actor(string $role, string $suffix = '0001'): User
|
|
{
|
|
$user = new User;
|
|
|
|
$user->forceFill([
|
|
'id' => "eeee7777-0000-0000-0000-{$role}{$suffix}",
|
|
'name' => ucfirst($role),
|
|
'email' => "{$role}@beraspro.test",
|
|
'role' => $role,
|
|
'is_active' => true,
|
|
]);
|
|
|
|
return $user;
|
|
}
|
|
|
|
private function seedComplaint(array $overrides = []): array
|
|
{
|
|
$row = array_merge([
|
|
'id' => 'bbbb8888-0000-0000-0000-000000000001',
|
|
'complaint_number' => 'CMP-20260825-0001',
|
|
'customer_id' => self::CUSTOMER_ID,
|
|
'complaint_date' => '2026-08-25',
|
|
'category' => 'product',
|
|
'description' => 'Beras hitam',
|
|
'status' => ComplaintService::STATUS_OPEN,
|
|
'priority' => 'high',
|
|
'created_by' => $this->actor('operator')->id,
|
|
'customers' => ['code' => 'CUST-0001', 'name' => 'Andi'],
|
|
], $overrides);
|
|
|
|
InsForgeFake::seed('complaints', $row);
|
|
|
|
return $row;
|
|
}
|
|
|
|
public function test_create_generates_number_and_log(): void
|
|
{
|
|
$result = app(ComplaintService::class)->createComplaint([
|
|
'customer_id' => self::CUSTOMER_ID,
|
|
'description' => 'Kemasan rusak',
|
|
'category' => 'product',
|
|
'priority' => 'low',
|
|
], $this->actor('operator'));
|
|
|
|
$this->assertSame('CMP-'.now()->format('Ymd').'-0001', $result['complaint_number']);
|
|
|
|
$stored = array_values(InsForgeFake::$store['complaints'])[0];
|
|
$this->assertSame(ComplaintService::STATUS_OPEN, $stored['status']);
|
|
|
|
$log = end(InsForgeFake::$store['activity_logs']);
|
|
$this->assertSame('complaint_created', $log['action']);
|
|
}
|
|
|
|
public function test_creator_can_resolve_own_complaint(): void
|
|
{
|
|
$creator = $this->actor('operator');
|
|
$complaint = $this->seedComplaint(['created_by' => $creator->id]);
|
|
|
|
app(ComplaintService::class)->resolve($complaint['id'], 'ganti produk baru', $creator);
|
|
|
|
$stored = InsForgeFake::$store['complaints'][$complaint['id']];
|
|
$this->assertSame(ComplaintService::STATUS_RESOLVED, $stored['status']);
|
|
$this->assertSame('ganti produk baru', $stored['resolution']);
|
|
$this->assertNotNull($stored['resolved_at']);
|
|
}
|
|
|
|
public function test_other_operator_cannot_resolve(): void
|
|
{
|
|
$complaint = $this->seedComplaint();
|
|
|
|
$this->expectException(AuthorizationException::class);
|
|
app(ComplaintService::class)->resolve($complaint['id'], 'coba tutup', $this->actor('operator', '9999'));
|
|
}
|
|
|
|
public function test_admin_can_resolve_any_complaint(): void
|
|
{
|
|
$complaint = $this->seedComplaint();
|
|
|
|
app(ComplaintService::class)->resolve($complaint['id'], 'direfund', $this->actor('admin'));
|
|
|
|
$this->assertSame(ComplaintService::STATUS_RESOLVED, InsForgeFake::$store['complaints'][$complaint['id']]['status']);
|
|
}
|
|
|
|
public function test_already_resolved_cannot_be_resolved_again(): void
|
|
{
|
|
$complaint = $this->seedComplaint(['status' => ComplaintService::STATUS_RESOLVED, 'resolution' => 'ok']);
|
|
|
|
$this->expectException(ValidationException::class);
|
|
app(ComplaintService::class)->resolve($complaint['id'], 'lagi', $this->actor('admin'));
|
|
}
|
|
|
|
public function test_page_renders_and_shows_complaint(): void
|
|
{
|
|
$this->actingAs($this->actor('operator'));
|
|
|
|
$this->seedComplaint();
|
|
|
|
Livewire::test(ComplaintsPage::class)
|
|
->assertSuccessful()
|
|
->assertSee('CMP-20260825-0001')
|
|
->assertSee('Beras hitam');
|
|
}
|
|
|
|
public function test_close_action_hidden_for_non_owner_operator(): void
|
|
{
|
|
$user = $this->actor('operator', '9999');
|
|
$this->actingAs($user);
|
|
|
|
$complaint = $this->seedComplaint();
|
|
|
|
Livewire::test(ComplaintsPage::class)
|
|
->assertSuccessful()
|
|
->assertDontSeeHtml('wire:key="writable-actions-tutup"');
|
|
}
|
|
}
|