5001, 'name' => 'Test User', 'mail' => 'test@example.com', 'pass' => md5('password123'), 'departments' => 1, 'role' => config('constants.ROLE_MEMBER'), 'status' => config('constants.STATUS_ACTIVE'), 'card' => 10, 'flag_send' => config('constants.FLAG_SEND_ENABLED'), 'first_login' => config('constants.FIRST_LOGIN_FALSE'), ]); $response = $this->post('/login', [ 'mail' => 'test@example.com', 'password' => 'wrong_password', ]); $response->assertRedirect(); $response->assertSessionHasErrors(['mail' => 'Thông tin đăng nhập không đúng. Vui lòng nhập lại']); // 2. Empty fields $response2 = $this->post('/login', [ 'mail' => '', 'password' => '', ]); $response2->assertRedirect(); $response2->assertSessionHasErrors(['mail' => 'Thông tin đăng nhập không đúng. Vui lòng nhập lại']); // 3. Invalid email format $response3 = $this->post('/login', [ 'mail' => 'invalid-email-format', 'password' => 'password123', ]); $response3->assertRedirect(); $response3->assertSessionHasErrors(['mail' => 'Thông tin đăng nhập không đúng. Vui lòng nhập lại']); // 4. Email too long $response4 = $this->post('/login', [ 'mail' => str_repeat('a', 256) . '@example.com', 'password' => 'password123', ]); $response4->assertRedirect(); $response4->assertSessionHasErrors(['mail' => 'Thông tin đăng nhập không đúng. Vui lòng nhập lại']); // 5. Password too long $response5 = $this->post('/login', [ 'mail' => 'test@example.com', 'password' => str_repeat('p', 101), ]); $response5->assertRedirect(); $response5->assertSessionHasErrors(['mail' => 'Thông tin đăng nhập không đúng. Vui lòng nhập lại']); } /** * Test Case 2: Account disabled / no access permission */ public function test_inactive_user_displays_permission_error_dialog(): void { $user = User::create([ 'msnv' => 5002, 'name' => 'Inactive User', 'mail' => 'test@example.com', 'pass' => md5('password123'), 'departments' => 1, 'role' => config('constants.ROLE_MEMBER'), 'status' => config('constants.STATUS_INACTIVE'), // 0 'card' => 10, 'flag_send' => config('constants.FLAG_SEND_ENABLED'), 'first_login' => config('constants.FIRST_LOGIN_FALSE'), ]); $response = $this->post('/login', [ 'mail' => 'test@example.com', 'password' => 'password123', ]); $response->assertRedirect(); $response->assertSessionHas('dialog_error_permission', 'Bạn không có quyền truy cập. Vui lòng liên hệ quản trị viên'); $this->assertFalse(\Illuminate\Support\Facades\Auth::check()); } /** * Test Case 3: Session expired */ public function test_session_expired_redirects_with_session_expired_flash(): void { $response = $this->get('/my-page'); // Requires auth $response->assertRedirect(route('login')); $response->assertSessionHas('session_expired', true); } /** * Test Case 4: Login success */ public function test_login_success_redirects_correctly(): void { // 1. Member redirect to My Page $member = User::create([ 'msnv' => 5003, 'name' => 'Member User', 'mail' => 'member@example.com', 'pass' => md5('password123'), 'departments' => 1, 'role' => config('constants.ROLE_MEMBER'), 'status' => config('constants.STATUS_ACTIVE'), 'card' => 10, 'flag_send' => config('constants.FLAG_SEND_ENABLED'), 'first_login' => config('constants.FIRST_LOGIN_FALSE'), ]); $response = $this->post('/login', [ 'mail' => 'member@example.com', 'password' => 'password123', ]); $response->assertRedirect(route('user.dashboard')); $this->assertTrue(\Illuminate\Support\Facades\Auth::check()); $this->assertEquals($member->id, \Illuminate\Support\Facades\Auth::user()->id); \Illuminate\Support\Facades\Auth::logout(); // 2. Admin redirect to Admin User List $admin = User::create([ 'msnv' => 5004, 'name' => 'Admin User', 'mail' => 'admin@example.com', 'pass' => md5('password123'), 'departments' => 1, 'role' => config('constants.ROLE_ADMIN'), 'status' => config('constants.STATUS_ACTIVE'), 'card' => 10, 'flag_send' => config('constants.FLAG_SEND_ENABLED'), 'first_login' => config('constants.FIRST_LOGIN_FALSE'), ]); $response2 = $this->post('/login', [ 'mail' => 'admin@example.com', 'password' => 'password123', ]); $response2->assertRedirect(route('admin.dashboard')); $this->assertTrue(\Illuminate\Support\Facades\Auth::check()); } /** * Test Case 5: First login */ public function test_first_login_redirects_to_login_page_with_first_login_dialog(): void { $user = User::create([ 'msnv' => 5005, 'name' => 'First Login User', 'mail' => 'first@example.com', 'pass' => md5('password123'), 'departments' => 1, 'role' => config('constants.ROLE_MEMBER'), 'status' => config('constants.STATUS_ACTIVE'), 'card' => 10, 'flag_send' => config('constants.FLAG_SEND_ENABLED'), 'first_login' => config('constants.FIRST_LOGIN_TRUE'), ]); $response = $this->post('/login', [ 'mail' => 'first@example.com', 'password' => 'password123', ]); $response->assertRedirect(route('login')); $response->assertSessionHas('dialog_first_login', true); $this->assertTrue(\Illuminate\Support\Facades\Auth::check()); } public function test_admin_first_login_does_not_redirect_to_change_password(): void { $admin = User::create([ 'msnv' => 5007, 'name' => 'First Login Admin', 'mail' => 'first_admin@example.com', 'pass' => md5('password123'), 'departments' => 1, 'role' => config('constants.ROLE_ADMIN'), 'status' => config('constants.STATUS_ACTIVE'), 'card' => 10, 'flag_send' => config('constants.FLAG_SEND_ENABLED'), 'first_login' => config('constants.FIRST_LOGIN_TRUE'), ]); $response = $this->post('/login', [ 'mail' => 'first_admin@example.com', 'password' => 'password123', ]); $response->assertRedirect(route('admin.dashboard')); $response->assertSessionMissing('dialog_first_login'); $this->assertTrue(\Illuminate\Support\Facades\Auth::check()); } /** * Test Case 6: Brute-force protection */ public function test_brute_force_protection_locks_after_5_failed_attempts(): void { $user = User::create([ 'msnv' => 5006, 'name' => 'Lockout User', 'mail' => 'test@example.com', 'pass' => md5('password123'), 'departments' => 1, 'role' => config('constants.ROLE_MEMBER'), 'status' => config('constants.STATUS_ACTIVE'), 'card' => 10, 'flag_send' => config('constants.FLAG_SEND_ENABLED'), 'first_login' => config('constants.FIRST_LOGIN_FALSE'), ]); // First 5 attempts fail for ($i = 0; $i < 5; $i++) { $response = $this->post('/login', [ 'mail' => 'test@example.com', 'password' => 'wrong_password', ]); $response->assertSessionHasErrors(['mail' => 'Thông tin đăng nhập không đúng. Vui lòng nhập lại']); } // 6th attempt is blocked by brute force protection $response6 = $this->post('/login', [ 'mail' => 'test@example.com', 'password' => 'wrong_password', ]); $response6->assertSessionHas('dialog_error_brute_force', 'Tài khoản của bạn tạm thời bị khóa do nhập sai mật khẩu quá 5 lần. Vui lòng thử lại sau 15 phút.'); // 7th attempt with CORRECT password is also blocked $response7 = $this->post('/login', [ 'mail' => 'test@example.com', 'password' => 'password123', ]); $response7->assertSessionHas('dialog_error_brute_force', 'Tài khoản của bạn tạm thời bị khóa do nhập sai mật khẩu quá 5 lần. Vui lòng thử lại sau 15 phút.'); $this->assertFalse(\Illuminate\Support\Facades\Auth::check()); } }