Skip to content

Commit 3b241cb

Browse files
leocleeLeonard Lee
authored andcommitted
remove case-insensitive duplicates for notification destination
1 parent 466258b commit 3b241cb

2 files changed

Lines changed: 115 additions & 5 deletions

File tree

src/main/java/org/nhindirect/stagent/mail/notifications/NotificationHelper.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2525
import java.util.ArrayList;
2626
import java.util.Collection;
2727
import java.util.Collections;
28+
import java.util.List;
29+
import java.util.TreeSet;
2830
import java.util.Arrays;
2931

3032
import javax.mail.MessagingException;
@@ -107,11 +109,23 @@ public static String getNotificationDestination(Message message)
107109

108110
try
109111
{
110-
retVal = message.getHeader(MDNStandard.Headers.DispositionNotificationTo, ",");
111-
112-
if (retVal == null || retVal.isEmpty())
113-
{
114-
retVal = message.getHeader(MDNStandard.Headers.From, ",");
112+
String[] destinations = message.getHeader(MDNStandard.Headers.DispositionNotificationTo);
113+
114+
if (destinations == null || destinations.length == 0) {
115+
destinations = message.getHeader(MDNStandard.Headers.From);
116+
}
117+
118+
if (destinations == null || destinations.length == 0) {
119+
retVal = "";
120+
} else if (destinations.length == 1) {
121+
retVal = destinations[0];
122+
} else if (destinations.length > 1) {
123+
// remove (case-insensitive) duplicates
124+
List<String> uniqueDestinations = new ArrayList<>();
125+
Collections.addAll(uniqueDestinations, destinations);
126+
TreeSet<String> seen = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
127+
uniqueDestinations.removeIf(s -> !seen.add(s));
128+
retVal = String.join(",", uniqueDestinations);
115129
}
116130
}
117131
catch (MessagingException e) {/* no-op */}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package org.nhindirect.stagent.mail.notifications;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.mockito.Mockito.when;
5+
6+
import org.junit.Test;
7+
import org.junit.runner.RunWith;
8+
import org.mockito.Mock;
9+
import org.mockito.junit.MockitoJUnitRunner;
10+
import org.nhindirect.stagent.mail.Message;
11+
12+
@RunWith(MockitoJUnitRunner.class)
13+
public class NotificationHelperTest {
14+
@Mock
15+
private Message mockMessage;
16+
private static final String DISPOSITION_NOTIFICATION_TO = "a@test.com";
17+
private static final String FROM = "b@test.com";
18+
19+
@Test
20+
public void testNoDestination() throws Exception {
21+
String destination = NotificationHelper.getNotificationDestination(mockMessage);
22+
23+
assertEquals("", destination);
24+
}
25+
26+
@Test
27+
public void testDispositionNotification() throws Exception {
28+
when(mockMessage.getHeader(MDNStandard.Headers.DispositionNotificationTo))
29+
.thenReturn(new String[] { DISPOSITION_NOTIFICATION_TO });
30+
31+
String destination = NotificationHelper.getNotificationDestination(mockMessage);
32+
33+
assertEquals(DISPOSITION_NOTIFICATION_TO, destination);
34+
}
35+
36+
@Test
37+
public void testDispositionNotificationTo() throws Exception {
38+
when(mockMessage.getHeader(MDNStandard.Headers.DispositionNotificationTo))
39+
.thenReturn(new String[] { DISPOSITION_NOTIFICATION_TO });
40+
41+
String destination = NotificationHelper.getNotificationDestination(mockMessage);
42+
43+
assertEquals(DISPOSITION_NOTIFICATION_TO, destination);
44+
}
45+
46+
@Test
47+
public void testMultipleDispositionNotificationTo() throws Exception {
48+
String anotherAddress = "anotheraddress@test.com";
49+
when(mockMessage.getHeader(MDNStandard.Headers.DispositionNotificationTo))
50+
.thenReturn(new String[] { DISPOSITION_NOTIFICATION_TO, anotherAddress });
51+
52+
String destination = NotificationHelper.getNotificationDestination(mockMessage);
53+
54+
assertEquals(DISPOSITION_NOTIFICATION_TO + "," + anotherAddress, destination);
55+
}
56+
57+
@Test
58+
public void testNullDispositionNotificationTo_FromAsFallback() throws Exception {
59+
when(mockMessage.getHeader(MDNStandard.Headers.DispositionNotificationTo)).thenReturn(null);
60+
when(mockMessage.getHeader(MDNStandard.Headers.From)).thenReturn(new String[] { FROM });
61+
62+
String destination = NotificationHelper.getNotificationDestination(mockMessage);
63+
64+
assertEquals(FROM, destination);
65+
}
66+
67+
@Test
68+
public void testEmptyDispositionNotificationTo_FromAsFallback() throws Exception {
69+
when(mockMessage.getHeader(MDNStandard.Headers.DispositionNotificationTo)).thenReturn(new String[] {});
70+
when(mockMessage.getHeader(MDNStandard.Headers.From)).thenReturn(new String[] { FROM });
71+
72+
String destination = NotificationHelper.getNotificationDestination(mockMessage);
73+
74+
assertEquals(FROM, destination);
75+
}
76+
77+
@Test
78+
public void testDispositionNotificationToDuplicatesAreRemoved() throws Exception {
79+
when(mockMessage.getHeader(MDNStandard.Headers.DispositionNotificationTo))
80+
.thenReturn(new String[] { DISPOSITION_NOTIFICATION_TO, DISPOSITION_NOTIFICATION_TO.toUpperCase() });
81+
82+
String destination = NotificationHelper.getNotificationDestination(mockMessage);
83+
84+
assertEquals(DISPOSITION_NOTIFICATION_TO, destination);
85+
}
86+
87+
@Test
88+
public void testFromDuplicatesAreRemoved() throws Exception {
89+
when(mockMessage.getHeader(MDNStandard.Headers.DispositionNotificationTo)).thenReturn(null);
90+
when(mockMessage.getHeader(MDNStandard.Headers.From)).thenReturn(new String[] { FROM, FROM.toUpperCase() });
91+
92+
String destination = NotificationHelper.getNotificationDestination(mockMessage);
93+
94+
assertEquals(FROM, destination);
95+
}
96+
}

0 commit comments

Comments
 (0)