Skip to content

Commit b20b405

Browse files
committed
Make stripQuotes default behavior
1 parent fc49cad commit b20b405

File tree

5 files changed

+60
-19
lines changed

5 files changed

+60
-19
lines changed

CHANGELOG.md

+42-7
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,24 @@
44

55
### Breaking Changes
66

7-
- The `jmail.normalize.strip.quotes` JVM system property no longer does anything.
8-
Use `NormalizationOptionsBuilder#stripQuotes()` instead.
7+
- By default, `Email#normalized` now lowercases the email address **and** removes any extraneous quotes in the local-part of the address.
8+
To revert this behavior so that it behaves the same as v1, use the following:
9+
10+
```
11+
myEmailObject.normalized(
12+
NormalizationOptions.builder()
13+
.keepQuotes()
14+
.adjustCase(CaseOption.NO_CHANGE)
15+
.build());
16+
```
17+
18+
19+
- The `jmail.normalize.strip.quotes` JVM system property no longer does anything. Quotes are stripped by default now.
20+
If you need to disable quote stripping, use `NormalizationOptionsBuilder#keepQuotes()`.
921

1022

1123
- Removed `Email#normalized(boolean)` method which allowed for a normalized email with stripped quotes.
12-
Use `myEmail.normalized(NormalizationOptions.builder().stripQuotes().build())` instead.
24+
Quotes are stripped by default now. If you need to disable quote stripping, use `NormalizationOptionsBuilder#keepQuotes()`.
1325

1426

1527
- `FailureReason` was switched from an enum to a class in order to support custom failure reasons, so you cannot
@@ -18,12 +30,14 @@
1830

1931
- `FailureReason.MISSING_TOP_LEVEL_DOMAIN` was changed to `FailureReason.MISSING_FINAL_DOMAIN_PART`.
2032
`MISSING_TOP_LEVEL_DOMAIN` was previously used for email addresses that failed validation because
21-
they ended the email address with a comment. This `FailureReason` was potentially misleading, for example
22-
enabling `requireTopLevelDomain()` on your `EmailValidator`.
33+
they ended the email address with a comment. This `FailureReason` was potentially misleading, for example if you
34+
enabled `requireTopLevelDomain()` on your `EmailValidator`. Note that the `MISSING_TOP_LEVEL_DOMAIN` failure reason
35+
is now used properly: if you use the rule `requireTopLevelDomain()`, any address that is missing the TLD will give
36+
that failure reason.
2337

2438

2539
- Email addresses that fail validation due to additional rules added to the `EmailValidator` (such as
26-
`disallowIpDomain()` or `requireValidMXRecord()`) no longer returns a generic `FailureReason.FAILED_CUSTOM_VALIDATION`
40+
`disallowIpDomain()` or `requireValidMXRecord()`) no longer return a generic `FailureReason.FAILED_CUSTOM_VALIDATION`
2741
in the `EmailValidationResult`. Instead, it returns a more specific `FailureReason` depending on the rule.
2842

2943
### FailureReason Improvements
@@ -33,7 +47,17 @@
3347
The `FailureReason` returned in the `EmailValidationResult` is useful to understand why a specific
3448
email address failed validation. In v2.0.0, the `FailureReason` returned for email addresses that failed
3549
one of the additional validation rules added to your `EmailValidator` (such as `disallowIpDomain()` or
36-
`requireValidMXRecord()`) now return more specific and useful reasons.
50+
`requireValidMXRecord()`) now return more specific and useful reasons (such as `CONTAINS_IP_DOMAIN` or
51+
`INVALID_MX_RECORD`).
52+
53+
```
54+
EmailValidator validator = JMail.strictValidator()
55+
.requireOnlyTopLevelDomains(TopLevelDomain.DOT_COM);
56+
57+
EmailValidationResult result = validator.validate("[email protected]");
58+
59+
assertEquals(FailureReason.INVALID_TOP_LEVEL_DOMAIN, result.getFailureReason());
60+
```
3761

3862
#### Option to provide FailureReason for custom rules
3963

@@ -43,6 +67,17 @@ to your `EmailValidator`. Use the new `withRule(Predicate<Email>, FailureReason)
4367
of your custom rules. If no failure reason is supplied, then the rule will default to the
4468
`FailureReason.FAILED_CUSTOM_VALIDATION` reason.
4569

70+
```
71+
FailureReason nonGmailFailure = new FailureReason("NON_GMAIL_ADDRESS");
72+
73+
EmailValidator validator = JMail.strictValidator()
74+
.withRule(e -> e.domain.startsWith("gmail"), nonGmailFailure);
75+
76+
EmailValidationResult result = validator.validate("[email protected]");
77+
78+
assertEquals(nonGmailFailure, result.getFailureReason());
79+
```
80+
4681
### Email Address Normalization Improvements
4782

4883
#### New Normalization Methods

src/main/java/com/sanctionco/jmail/normalization/NormalizationOptionsBuilder.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
public class NormalizationOptionsBuilder {
1111
CaseOption caseOption = CaseOption.LOWERCASE;
12-
boolean stripQuotes = false;
12+
boolean stripQuotes = true;
1313
boolean removeDots = false;
1414
boolean removeSubAddress = false;
1515
String subAddressSeparator = "+";
@@ -20,14 +20,14 @@ public class NormalizationOptionsBuilder {
2020
}
2121

2222
/**
23-
* <p>Strip all unnecessary quotes contained in the local-part of the email address.</p>
24-
*
25-
* <p>The default normalization behavior does <strong>not</strong> strip quotes.</p>
23+
* By default, normalization strips all unnecessary quotes contained in the local-part
24+
* of the email address. This method will tell normalization to <strong>keep</strong> those
25+
* extraneous quotes.
2626
*
2727
* @return this
2828
*/
29-
public NormalizationOptionsBuilder stripQuotes() {
30-
this.stripQuotes = true;
29+
public NormalizationOptionsBuilder keepQuotes() {
30+
this.stripQuotes = false;
3131
return this;
3232
}
3333

src/test/java/com/sanctionco/jmail/EmailTest.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
class EmailTest {
2222
private static final NormalizationOptions MINIMAL_NORMALIZATION = NormalizationOptions
2323
.builder()
24+
.keepQuotes()
2425
.adjustCase(CaseOption.NO_CHANGE)
2526
.build();
2627

@@ -61,11 +62,11 @@ void ensureNormalizedIsCorrectForLongComment() {
6162
@ParameterizedTest(name = "{0}")
6263
@MethodSource("provideValidForStripQuotes")
6364
void ensureNormalizedStripsQuotes(String address, String expected) {
65+
// Strip quotes is default
6466
assertThat(Email.of(address))
6567
.isPresent().get()
6668
.returns(expected, email -> email.normalized(NormalizationOptions.builder()
6769
.adjustCase(CaseOption.NO_CHANGE)
68-
.stripQuotes()
6970
.build()));
7071

7172
// Check that nothing happens when stripQuotes is false
@@ -178,7 +179,6 @@ void ensureNormalizedStripsQuotesForAllValidAddresses(String address) {
178179
validated.normalized(MINIMAL_NORMALIZATION),
179180
email -> email.normalized(NormalizationOptions.builder()
180181
.adjustCase(CaseOption.NO_CHANGE)
181-
.stripQuotes()
182182
.build()));
183183
}
184184

@@ -212,7 +212,6 @@ void ensureNormalizedDoesNotStripQuotesIfInvalid(String address) {
212212
.isPresent().get()
213213
.returns(address, email -> email.normalized(NormalizationOptions.builder()
214214
.adjustCase(CaseOption.NO_CHANGE)
215-
.stripQuotes()
216215
.build()));
217216
}
218217

src/test/java/com/sanctionco/jmail/EmailValidatorTest.java

+7
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,13 @@ void invalidatesCorrectlyWithCustomStringFailureReason(String email) {
276276
JMail.validator().withRule(e -> e.domain().startsWith("test"), "MY_REASON"),
277277
email,
278278
failureReason);
279+
280+
EmailValidator validator = JMail.strictValidator()
281+
.requireOnlyTopLevelDomains(TopLevelDomain.DOT_COM);
282+
283+
EmailValidationResult result = validator.validate("[email protected]");
284+
285+
result.getFailureReason().equals(FailureReason.INVALID_TOP_LEVEL_DOMAIN);
279286
}
280287

281288
@ParameterizedTest(name = "{0}")

src/test/java/com/sanctionco/jmail/normalization/NormalizationOptionsBuilderTest.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class NormalizationOptionsBuilderTest {
1111
@Test
1212
void ensureDefaults() {
1313
assertThat(NormalizationOptions.builder().build())
14-
.returns(false, NormalizationOptions::shouldStripQuotes)
14+
.returns(true, NormalizationOptions::shouldStripQuotes)
1515
.returns(CaseOption.LOWERCASE, NormalizationOptions::getCaseOption)
1616
.returns(false, NormalizationOptions::shouldRemoveDots)
1717
.returns(false, NormalizationOptions::shouldRemoveSubAddress)
@@ -25,13 +25,13 @@ void ensureValuesAreProperlySet() {
2525
NormalizationOptions options = NormalizationOptions.builder()
2626
.removeDots()
2727
.removeSubAddress("-")
28-
.stripQuotes()
28+
.keepQuotes()
2929
.adjustCase(CaseOption.UPPERCASE)
3030
.performUnicodeNormalization(Normalizer.Form.NFC)
3131
.build();
3232

3333
assertThat(options)
34-
.returns(true, NormalizationOptions::shouldStripQuotes)
34+
.returns(false, NormalizationOptions::shouldStripQuotes)
3535
.returns(CaseOption.UPPERCASE, NormalizationOptions::getCaseOption)
3636
.returns(true, NormalizationOptions::shouldRemoveDots)
3737
.returns(true, NormalizationOptions::shouldRemoveSubAddress)

0 commit comments

Comments
 (0)