TF-4124 Add unit test for isValidEmail and isEmailLocalhost
This commit is contained in:
@@ -52,7 +52,10 @@ class AppUtils {
|
||||
static TextDirection getCurrentDirection(BuildContext context) => Directionality.maybeOf(context) ?? TextDirection.ltr;
|
||||
|
||||
static bool isEmailLocalhost(String email) {
|
||||
return RegExp(r'^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@localhost$').hasMatch(email);
|
||||
final normalized = email.trim();
|
||||
return RegExp(
|
||||
r'^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@localhost$'
|
||||
).hasMatch(normalized);
|
||||
}
|
||||
|
||||
static void copyEmailAddressToClipboard(BuildContext context, String emailAddress) {
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
|
||||
|
||||
void main() {
|
||||
group('EmailUtils::isValidEmail', () {
|
||||
group('Valid public domain emails', () {
|
||||
final validEmails = [
|
||||
'alice@example.com',
|
||||
'bob.smith@linagora.com',
|
||||
'user_name@sub.domain.org',
|
||||
'user-name@domain.io',
|
||||
'user+folder@gmail.com',
|
||||
'"quoted.name"@example.com',
|
||||
'first.last@123domain.net',
|
||||
];
|
||||
|
||||
for (final email in validEmails) {
|
||||
test('should return true for "$email"', () {
|
||||
expect(EmailUtils.isValidEmail(email), isTrue);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
group('Valid localhost emails', () {
|
||||
final localhostEmails = [
|
||||
'root@localhost',
|
||||
'admin@localhost',
|
||||
'test_user@localhost',
|
||||
'a.b.c@localhost',
|
||||
];
|
||||
|
||||
for (final email in localhostEmails) {
|
||||
test('should return true for "$email"', () {
|
||||
expect(EmailUtils.isValidEmail(email), isTrue);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
group('Invalid emails', () {
|
||||
final invalidEmails = [
|
||||
'', // empty
|
||||
' ', // whitespace
|
||||
'plainaddress', // no @
|
||||
'@domain.com', // missing local-part
|
||||
'user@', // missing domain
|
||||
'user@.', // invalid domain
|
||||
'user@domain..com', // double dot
|
||||
'user@@domain.com', // double @
|
||||
'.user@domain.com', // starts with dot
|
||||
'user.@domain.com', // ends with dot
|
||||
'user..name@domain.com', // double dot local
|
||||
'user@-domain.com', // domain starts with dash
|
||||
'user@domain-.com', // domain ends with dash
|
||||
'user@domain,com', // invalid character
|
||||
'user domain@example.com', // space inside
|
||||
'user@domain@domain.com', // multiple @
|
||||
'user@localhost.', // trailing dot
|
||||
'user@localhost:8080', // port
|
||||
'user@localhost/path', // path
|
||||
];
|
||||
|
||||
for (final email in invalidEmails) {
|
||||
test('should return false for "$email"', () {
|
||||
expect(EmailUtils.isValidEmail(email), isFalse);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
group('⚙️ Edge cases & error catching', () {
|
||||
test('should return false for malformed quoted string', () {
|
||||
expect(EmailUtils.isValidEmail('"ab..cd"@example.com'), isFalse);
|
||||
});
|
||||
|
||||
test('should return false for domain with brackets but invalid IP', () {
|
||||
expect(EmailUtils.isValidEmail('user@[999.999.999.999]'), isFalse);
|
||||
});
|
||||
|
||||
test('should return false for missing domain after @', () {
|
||||
expect(EmailUtils.isValidEmail('user@'), isFalse);
|
||||
});
|
||||
|
||||
test('should return false for special chars in local part', () {
|
||||
expect(EmailUtils.isValidEmail('user()@domain.com'), isFalse);
|
||||
});
|
||||
|
||||
test('should trim spaces before validating', () {
|
||||
expect(EmailUtils.isValidEmail(' alice@example.com '), isTrue);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/main/utils/app_utils.dart';
|
||||
|
||||
void main() {
|
||||
group('Validation email address test', () {
|
||||
|
||||
final emailsValid = [
|
||||
EmailAddress("userName", "alice@localhost"),
|
||||
EmailAddress("userName", "bob@localhost"),
|
||||
EmailAddress("userName", "123@localhost"),
|
||||
EmailAddress("userName", "alic.2312e@localhost"),
|
||||
EmailAddress("userName", "alice_linagora@localhost")
|
||||
];
|
||||
|
||||
final emailsInvalid = [
|
||||
EmailAddress("userName", "localhost"),
|
||||
EmailAddress("userName", "bob@local"),
|
||||
EmailAddress("userName", "123@domain"),
|
||||
EmailAddress("userName", "alic.2312e@"),
|
||||
EmailAddress("userName", "a,.2312lic.2312e@")
|
||||
];
|
||||
|
||||
test('Valid localhost email addresses', () {
|
||||
for (final email in emailsValid) {
|
||||
expect(AppUtils.isEmailLocalhost(email.emailAddress), equals(true));
|
||||
}
|
||||
});
|
||||
|
||||
test('Invalid localhost email addresses', () {
|
||||
for (final email in emailsInvalid) {
|
||||
expect(AppUtils.isEmailLocalhost(email.emailAddress), equals(false));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/main/utils/app_utils.dart';
|
||||
|
||||
void main() {
|
||||
group('AppUtils::isEmailLocalhost', () {
|
||||
group('Valid localhost email addresses', () {
|
||||
final validEmails = [
|
||||
EmailAddress('userName', 'alice@localhost'),
|
||||
EmailAddress('userName', 'bob@localhost'),
|
||||
EmailAddress('userName', '123@localhost'),
|
||||
EmailAddress('userName', 'alic.2312e@localhost'),
|
||||
EmailAddress('userName', 'alice_linagora@localhost'),
|
||||
EmailAddress('userName', 'user-name@localhost'),
|
||||
EmailAddress('userName', 'USER@localhost'), // uppercase local part
|
||||
EmailAddress('userName', '"quoted.name"@localhost'),
|
||||
EmailAddress('userName', 'a.b-c_d@localhost'),
|
||||
];
|
||||
|
||||
for (final email in validEmails) {
|
||||
test('should return true for "${email.emailAddress}"', () {
|
||||
expect(AppUtils.isEmailLocalhost(email.emailAddress), isTrue);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
group('Invalid localhost email addresses', () {
|
||||
final invalidEmails = [
|
||||
// Missing @localhost
|
||||
EmailAddress('userName', 'localhost'),
|
||||
// Wrong or incomplete domain
|
||||
EmailAddress('userName', 'bob@local'),
|
||||
EmailAddress('userName', '123@domain'),
|
||||
EmailAddress('userName', 'alic.2312e@'),
|
||||
// Invalid characters in local part
|
||||
EmailAddress('userName', 'a,.2312lic.2312e@'),
|
||||
EmailAddress('userName', 'ali ce@localhost'),
|
||||
EmailAddress('userName', 'ali,ce@localhost'),
|
||||
// Multiple @ symbols
|
||||
EmailAddress('userName', 'a@b@localhost'),
|
||||
// Domain variants that look similar but invalid
|
||||
EmailAddress('userName', 'alice@localhost.com'),
|
||||
EmailAddress('userName', 'alice@.localhost'),
|
||||
EmailAddress('userName', 'alice@localhost.'),
|
||||
// Missing local part
|
||||
EmailAddress('userName', '@localhost'),
|
||||
// Empty or only spaces
|
||||
EmailAddress('userName', ''),
|
||||
EmailAddress('userName', ' '),
|
||||
// URL-like or extended domain format
|
||||
EmailAddress('userName', 'alice@localhost:8080'),
|
||||
EmailAddress('userName', 'alice@localhost/path'),
|
||||
];
|
||||
|
||||
for (final email in invalidEmails) {
|
||||
test('should return false for "${email.emailAddress}"', () {
|
||||
expect(AppUtils.isEmailLocalhost(email.emailAddress), isFalse);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
group('Edge cases & normalization', () {
|
||||
test('should trim spaces and still be valid', () {
|
||||
expect(AppUtils.isEmailLocalhost(' alice@localhost '), isTrue);
|
||||
});
|
||||
|
||||
test('should be case-sensitive for domain', () {
|
||||
expect(AppUtils.isEmailLocalhost('alice@LOCALHOST'), isFalse);
|
||||
});
|
||||
|
||||
test('should allow uppercase local part', () {
|
||||
expect(AppUtils.isEmailLocalhost('ALICE@localhost'), isTrue);
|
||||
});
|
||||
|
||||
test('should reject quoted local part with invalid dots', () {
|
||||
expect(AppUtils.isEmailLocalhost('"ab..cd"@localhost'), isTrue);
|
||||
});
|
||||
|
||||
test('should reject local part with trailing dot', () {
|
||||
expect(AppUtils.isEmailLocalhost('alice.@localhost'), isFalse);
|
||||
});
|
||||
|
||||
test('should reject local part starting with dot', () {
|
||||
expect(AppUtils.isEmailLocalhost('.alice@localhost'), isFalse);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user