toContain('required'); expect($rules)->toContain('string'); expect($rules)->toContain('min:12'); }); test('rules array includes regex for each charset class', function () { $rules = PasswordRuleHelper::rules(); expect(implode('|', $rules)) ->toContain('regex:/[a-z]/') ->toContain('regex:/[A-Z]/') ->toContain('regex:/[0-9]/'); }); test('messages contain min and regex keys', function () { $msgs = PasswordRuleHelper::messages(); expect($msgs)->toHaveKeys(['password.min', 'password.regex']); }); test('rules accept a strong password via Validator', function () { $v = Validator::make( ['password' => 'Str0ng!Passw0rd2026'], ['password' => PasswordRuleHelper::rules()], PasswordRuleHelper::messages(), ); expect($v->fails())->toBeFalse(); }); test('rules reject short passwords', function () { $v = Validator::make( ['password' => 'Abc123!'], ['password' => PasswordRuleHelper::rules()], ); expect($v->fails())->toBeTrue(); }); test('rules reject passwords missing uppercase', function () { $v = Validator::make( ['password' => 'all_lower_123!'], ['password' => PasswordRuleHelper::rules()], ); expect($v->fails())->toBeTrue(); }); test('rules reject passwords missing digit', function () { $v = Validator::make( ['password' => 'NoDigitsHere!'], ['password' => PasswordRuleHelper::rules()], ); expect($v->fails())->toBeTrue(); }); test('rules reject passwords missing symbol', function () { $v = Validator::make( ['password' => 'NoSymbolsHere1'], ['password' => PasswordRuleHelper::rules()], ); expect($v->fails())->toBeTrue(); });