'manager']); \Illuminate\Support\Facades\Notification::fake(); $sender = User::factory()->create(); $sender->assignRole('manager'); $deptManager = User::factory()->create(['name' => 'Tech Manager']); $deptManager->assignRole('manager'); $fromDept = Department::create(['name' => 'CSKH', 'manager_id' => null]); $toDept = Department::create(['name' => 'Ky Thuat', 'manager_id' => $deptManager->id]); $channel = FeedbackChannel::create(['name' => 'Email', 'slug' => 'email-transfer']); $customer = Customer::create(['name' => 'Test Transfer', 'email' => 'transfer@test.com']); $feedback = Feedback::create([ 'customer_id' => $customer->id, 'feedback_channel_id' => $channel->id, 'title' => 'Transfer Test Ticket', 'content' => 'Test content', 'status' => 'pending', 'current_department_id' => $fromDept->id, 'assigned_to' => $sender->id, ]); $this->actingAs($sender); $transferService = app(TransferService::class); $log = $transferService->transfer( $feedback, $toDept, 'Can chuyen sang phong ky thuat de kiem tra', $sender, ); // Assert log created expect($log)->toBeInstanceOf(TicketTransferLog::class); expect($log->from_department_id)->toBe($fromDept->id); expect($log->to_department_id)->toBe($toDept->id); expect($log->sender_id)->toBe($sender->id); expect($log->reason)->toBe('Can chuyen sang phong ky thuat de kiem tra'); // Assert department updated $feedback->refresh(); expect($feedback->current_department_id)->toBe($toDept->id); expect($feedback->assignedTo->id)->toBe($deptManager->id); // Assert notification sent to target department manager \Illuminate\Support\Facades\Notification::assertSentTo( $deptManager, \App\Notifications\TicketTransferred::class, function ($notification) use ($feedback, $sender) { return $notification->feedback->id === $feedback->id && $notification->sender->id === $sender->id; } ); }); // ─── Transfer without reason should fail ──────────────────────────── test('transfer without reason throws validation error', function () { \Spatie\Permission\Models\Role::create(['name' => 'manager']); $sender = User::factory()->create(); $sender->assignRole('manager'); $fromDept = Department::create(['name' => 'CSKH']); $toDept = Department::create(['name' => 'Ky Thuat']); $channel = FeedbackChannel::create(['name' => 'Zalo', 'slug' => 'zalo-transfer']); $customer = Customer::create(['name' => 'Test', 'email' => 'fail@test.com']); $feedback = Feedback::create([ 'customer_id' => $customer->id, 'feedback_channel_id' => $channel->id, 'title' => 'Fail Transfer', 'content' => 'Test', 'status' => 'pending', 'current_department_id' => $fromDept->id, ]); $this->actingAs($sender); $transferService = app(TransferService::class); try { $transferService->transfer($feedback, $toDept, ' ', $sender); $this->fail('Expected ValidationException but none thrown.'); } catch (\Illuminate\Validation\ValidationException $e) { expect($e->errors()['reason'][0])->toContain('Vui lòng nhập lý do chuyển tiếp'); } expect(TicketTransferLog::count())->toBe(0); });