Skip to content

Commit

Permalink
added translation support to validations
Browse files Browse the repository at this point in the history
  • Loading branch information
BroonDev committed Aug 27, 2024
1 parent 0689f65 commit 216edd1
Show file tree
Hide file tree
Showing 14 changed files with 341 additions and 45 deletions.
32 changes: 27 additions & 5 deletions lib/src/validations/range_validation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,33 @@ extension RangeValidation on SimpleValidationBuilder<num> {
/// ruleFor((user) => user.age, key: 'age')
/// .range(18, 65);
/// ```
SimpleValidationBuilder<num> range(num min, num max, {String message = r'Must be between $min and $max', String code = 'range_error'}) {
return must(
(value) => value >= min && value <= max,
message.replaceAll(r'$min', min.toString()).replaceAll('$max', max.toString()),
code,
///
/// String format args:
/// - **{PropertyName}**: The name of the property.
/// - **{From}**: The minimum value of the range.
/// - **{To}**: The maximum value of the range.
/// - **{PropertyValue}**: The value of the property.
///
SimpleValidationBuilder<num> range(num min, num max,
{String? message, String? code}) {
return use(
(value, entity) {
if (value >= min && value <= max) return null;

final currentCode = code ?? Language.code.range;
final currentMessage = LucidValidation.global.languageManager.translate(
currentCode,
parameters: {
'PropertyName': key,
'From': '$min',
'To': '$max',
'PropertyValue': '$value',
},
defaultMessage: message,
);

return ValidationError(message: currentMessage, code: currentCode);
},
);
}
}
25 changes: 19 additions & 6 deletions lib/src/validations/valid_cep_validation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,24 @@ extension ValidCEPValidation on SimpleValidationBuilder<String> {
/// ruleFor((user) => user.cep, key: 'cep')
/// .validCEP();
/// ```
SimpleValidationBuilder<String> validCEP({String message = 'Invalid CEP', String code = 'invalid_cep'}) {
return must(
(value) => RegExp(r'^\d{5}-?\d{3}$').hasMatch(value),
message,
code,
);
///
/// String format args:
/// - **{PropertyName}**: The name of the property.
///
SimpleValidationBuilder<String> validCEP({String? message, String? code}) {
return use((value, entity) {
if (RegExp(r'^\d{5}-?\d{3}$').hasMatch(value)) return null;

final currentCode = code ?? Language.code.validCEP;
final currentMessage = LucidValidation.global.languageManager.translate(
currentCode,
parameters: {
'PropertyName': key,
},
defaultMessage: message,
);

return ValidationError(message: currentMessage, code: currentCode);
});
}
}
25 changes: 19 additions & 6 deletions lib/src/validations/valid_cnpj_validation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,25 @@ extension ValidCnpjValidation on SimpleValidationBuilder<String> {
/// ruleFor((user) => user.cnpj, key: 'cnpj')
/// .validCNPJ();
/// ```
SimpleValidationBuilder<String> validCNPJ({String message = 'Invalid CNPJ', String code = 'invalid_cnpj'}) {
return must(
(value) => _validateCNPJ(value),
message,
code,
);
///
/// String format args:
/// - **{PropertyName}**: The name of the property.
///
SimpleValidationBuilder<String> validCNPJ({String? message, String? code}) {
return use((value, entity) {
if (_validateCNPJ(value)) return null;

final currentCode = code ?? Language.code.validCNPJ;
final currentMessage = LucidValidation.global.languageManager.translate(
currentCode,
parameters: {
'PropertyName': key,
},
defaultMessage: message,
);

return ValidationError(message: currentMessage, code: currentCode);
});
}

bool _validateCNPJ(String cnpj) {
Expand Down
25 changes: 19 additions & 6 deletions lib/src/validations/valid_cpf_validation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,25 @@ extension ValidCPFValidation on SimpleValidationBuilder<String> {
/// ruleFor((user) => user.cpf, key: 'cpf')
/// .validCPF();
/// ```
SimpleValidationBuilder<String> validCPF({String message = 'Invalid CPF', String code = 'invalid_cpf'}) {
return must(
(value) => _validateCPF(value),
message,
code,
);
///
/// String format args:
/// - **{PropertyName}**: The name of the property.
///
SimpleValidationBuilder<String> validCPF({String? message, String? code}) {
return use((value, entity) {
if (_validateCPF(value)) return null;

final currentCode = code ?? Language.code.validCPF;
final currentMessage = LucidValidation.global.languageManager.translate(
currentCode,
parameters: {
'PropertyName': key,
},
defaultMessage: message,
);

return ValidationError(message: currentMessage, code: currentCode);
});
}

bool _validateCPF(String cpf) {
Expand Down
30 changes: 23 additions & 7 deletions lib/src/validations/valid_creditcard_validation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,34 @@ extension ValidCreditCardValidation on SimpleValidationBuilder<String> {
/// ruleFor((user) => user.creditCard, key: 'creditCard')
/// .validCreditCard();
/// ```
SimpleValidationBuilder<String> validCreditCard({String message = 'Invalid credit card number', String code = 'invalid_credit_card'}) {
return must(
(value) => _validateCreditCard(value),
message,
code,
);
///
/// String format args:
/// - **{PropertyName}**: The name of the property.
///
SimpleValidationBuilder<String> validCreditCard(
{String? message, String? code}) {
return use((value, entity) {
if (_validateCreditCard(value)) return null;

final currentCode = code ?? Language.code.validCreditCard;
final currentMessage = LucidValidation.global.languageManager.translate(
currentCode,
parameters: {
'PropertyName': key,
},
defaultMessage: message,
);

return ValidationError(message: currentMessage, code: currentCode);
});
}

bool _validateCreditCard(String number) {
// Remove non-numeric characters
number = number.replaceAll(RegExp(r'[^0-9]'), '');
if (number.isEmpty || number.length < 13 || number.length > 19) return false;
if (number.isEmpty || number.length < 13 || number.length > 19) {
return false;
}

int sum = 0;
bool alternate = false;
Expand Down
27 changes: 21 additions & 6 deletions lib/src/validations/valid_email_validation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,26 @@ extension ValidEmailValidation on SimpleValidationBuilder<String> {
/// ruleFor((user) => user.email, key: 'email')
/// .validEmail();
/// ```
SimpleValidationBuilder<String> validEmail({String message = 'Invalid email address', String code = 'invalid_email'}) {
return must(
(value) => RegExp(r'^[\w\.-]+@[a-zA-Z\d\.-]+\.[a-zA-Z]{2,}$').hasMatch(value),
message,
code,
);
///
/// String format args:
/// - **{PropertyName}**: The name of the property.
///
SimpleValidationBuilder<String> validEmail({String? message, String? code}) {
return use((value, entity) {
if (RegExp(r'^[\w\.-]+@[a-zA-Z\d\.-]+\.[a-zA-Z]{2,}$').hasMatch(value)) {
return null;
}

final currentCode = code ?? Language.code.validEmail;
final currentMessage = LucidValidation.global.languageManager.translate(
currentCode,
parameters: {
'PropertyName': key,
},
defaultMessage: message,
);

return ValidationError(message: currentMessage, code: currentCode);
});
}
}
21 changes: 16 additions & 5 deletions test/lucid_validation_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import 'package:test/test.dart';
import 'mocks/mocks.dart';

void main() {
test('when validating [UserEntityMock] should return a list of error messages for the email field', () {
test(
'when validating [UserEntityMock] should return a list of error messages for the email field',
() {
final validator = UserValidator();
final userEntity = UserModel()
..age = 18
Expand All @@ -20,7 +22,9 @@ void main() {
expect(errors[1].message, 'Invalid email address');
});

test('when validating [UserModel] should return a list of error messages for the password field', () {
test(
'when validating [UserModel] should return a list of error messages for the password field',
() {
final validator = UserValidator();
final userEntity = UserModel()
..age = 18
Expand All @@ -41,7 +45,9 @@ void main() {
expect(errors[5].message, 'Must contain at least one special character');
});

test('when validating [UserModel] should return a list of error messages for the age field', () {
test(
'when validating [UserModel] should return a list of error messages for the age field',
() {
final validator = UserValidator();
final userEntity = UserModel()
..age = 15
Expand All @@ -57,7 +63,9 @@ void main() {
expect(errors.first.message, 'Minimum age is 18 years');
});

test('when validating [UserModel] should return a list of error messages for the phone field', () {
test(
'when validating [UserModel] should return a list of error messages for the phone field',
() {
final validator = UserValidator();

final userEntity = UserModel()
Expand All @@ -74,7 +82,9 @@ void main() {
expect(errors.first.message, 'Phone invalid format');
});

test('when validating [UserModel] should return a list of error messages for all fields', () {
test(
'when validating [UserModel] should return a list of error messages for all fields',
() {
final validator = UserValidator();
final userEntity = UserModel()..age = 15;

Expand Down Expand Up @@ -114,6 +124,7 @@ void main() {
country: 'Brazil',
postcode: '12345-678',
),
cnpj: '12345678901234',
);

final validator = CustomerValidator();
Expand Down
35 changes: 31 additions & 4 deletions test/mocks/mocks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class UserModel {
String? description;
int age = 0;
String phone = '';
String cpf = '';
}

class UserValidator extends LucidValidator<UserModel> {
Expand All @@ -24,6 +25,10 @@ class UserValidator extends LucidValidator<UserModel> {

ruleFor((user) => user.phone, key: 'phone') //
.customValidPhone('Phone invalid format');

ruleFor((user) => user.cpf, key: 'cpf') //
.notEmpty()
.validCPF();
}
}

Expand All @@ -37,7 +42,8 @@ extension CustomValidPhoneValidator on LucidValidationBuilder<String, dynamic> {
}
}

extension CustomValidPasswordValidator on LucidValidationBuilder<String, dynamic> {
extension CustomValidPasswordValidator
on LucidValidationBuilder<String, dynamic> {
LucidValidationBuilder<String, dynamic> customValidPassword() {
return notEmpty() //
.minLength(5, message: 'Must be at least 8 characters long')
Expand Down Expand Up @@ -80,10 +86,13 @@ class CredentialsRegisterValidator extends LucidValidator<CredentialsRegister> {

ruleFor((credentials) => credentials.password, key: 'password') //
.customValidPassword()
.equalTo((entity) => entity.confirmPassword, message: 'Must be equal to confirmPassword');
.equalTo((entity) => entity.confirmPassword,
message: 'Must be equal to confirmPassword');

ruleFor((credentials) => credentials.confirmPassword, key: 'confirmPassword') //
.equalTo((entity) => entity.password, message: 'Must be equal to password');
ruleFor((credentials) => credentials.confirmPassword,
key: 'confirmPassword') //
.equalTo((entity) => entity.password,
message: 'Must be equal to password');
}
}

Expand All @@ -110,10 +119,12 @@ class AddressValidator extends LucidValidator<Address> {
class Customer {
String name;
Address address;
String cnpj;

Customer({
required this.name,
required this.address,
required this.cnpj,
});
}

Expand All @@ -126,6 +137,22 @@ class CustomerValidator extends LucidValidator<Customer> {

ruleFor((customer) => customer.address, key: 'address') //
.setValidator(addressValidator);

ruleFor((customer) => customer.cnpj, key: 'cnpj') //
.notEmpty()
.validCNPJ();
}
}

class CreditCardModel {
String number = '';
}

class CreditCardValidator extends LucidValidator<CreditCardModel> {
CreditCardValidator() {
ruleFor((card) => card.number, key: 'number') //
.notEmpty()
.validCreditCard();
}
}

Expand Down
26 changes: 26 additions & 0 deletions test/src/validations/range_validation_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:lucid_validation/lucid_validation.dart';
import 'package:test/test.dart';

import '../../mocks/mocks.dart';

void main() {
test('range validation ...', () {
final validator = TestLucidValidator<UserModel>();

validator
.ruleFor((e) => e.age, key: 'age') //
.range(18, 60);

var user = UserModel()..age = 17;

final result = validator.validate(user);

expect(result.isValid, false);

expect(result.errors.length, 1);

final error = result.errors.first;

expect(error.message, "'age' must be between 18 and 60. You entered 17.");
});
}
Loading

0 comments on commit 216edd1

Please sign in to comment.