Skip to content

Commit 607aced

Browse files
authored
Merge pull request #11 from Iterable/feature/ITBL-1929-android-deeplink-rewriting
Feature/itbl 1929 android deeplink rewriting
2 parents 1593fcc + 304b2b5 commit 607aced

File tree

6 files changed

+359
-39
lines changed

6 files changed

+359
-39
lines changed
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
package com.iterable.iterableapi;
2+
3+
import android.app.Application;
4+
import android.test.ApplicationTestCase;
5+
6+
import java.util.concurrent.CountDownLatch;
7+
8+
/**
9+
* Created by David Truong [email protected].
10+
*/
11+
public class IterableApiDeeplinkTest extends ApplicationTestCase<Application> {
12+
13+
public IterableApiDeeplinkTest() {
14+
super(Application.class);
15+
}
16+
17+
public final String ITERABLE_BAD_UUID_REQUEST = "bad uuid";
18+
19+
@Override
20+
public void setUp() {
21+
createApplication();
22+
}
23+
24+
@Override
25+
public void tearDown() throws Exception {
26+
27+
}
28+
29+
public void testUniversalDeepLinkNoRewrite() throws Exception {
30+
final CountDownLatch signal = new CountDownLatch(1);
31+
try {
32+
final String requestString = "http://links.iterable.com/u/60402396fbd5433eb35397b47ab2fb83?_e=joneng%40iterable.com&_m=93125f33ba814b13a882358f8e0852e0";
33+
IterableHelper.IterableActionHandler clickCallback = new IterableHelper.IterableActionHandler() {
34+
@Override
35+
public void execute(String result) {
36+
assertEquals(requestString, result);
37+
signal.countDown();
38+
}
39+
};
40+
41+
IterableApi.getAndTrackDeeplink(requestString, clickCallback);
42+
signal.await();
43+
} catch (InterruptedException e) {
44+
e.printStackTrace();
45+
}
46+
}
47+
48+
public void testUniversalDeepLinkRewrite() throws Exception {
49+
final CountDownLatch signal = new CountDownLatch(1);
50+
try {
51+
final String requestString = "http://links.iterable.com/a/60402396fbd5433eb35397b47ab2fb83?_e=joneng%40iterable.com&_m=93125f33ba814b13a882358f8e0852e0";
52+
final String redirectString = "https://links.iterable.com/api/docs#!/email";
53+
IterableHelper.IterableActionHandler clickCallback = new IterableHelper.IterableActionHandler() {
54+
@Override
55+
public void execute(String result) {
56+
assertFalse(result.equalsIgnoreCase(requestString));
57+
assertEquals(redirectString, result);
58+
signal.countDown();
59+
}
60+
};
61+
62+
IterableApi.getAndTrackDeeplink(requestString, clickCallback);
63+
signal.await();
64+
} catch (InterruptedException e) {
65+
e.printStackTrace();
66+
}
67+
}
68+
69+
public void testNoURLRedirect() throws Exception {
70+
final CountDownLatch signal = new CountDownLatch(1);
71+
try {
72+
final String requestString = "https://httpbin.org/redirect-to?url=http://example.com";
73+
final String redirectString = "http://example.com";
74+
IterableHelper.IterableActionHandler clickCallback = new IterableHelper.IterableActionHandler() {
75+
@Override
76+
public void execute(String result) {
77+
assertFalse(result.equalsIgnoreCase(redirectString));
78+
assertEquals(requestString, result);
79+
signal.countDown();
80+
}
81+
};
82+
83+
IterableApi.getAndTrackDeeplink(requestString, clickCallback);
84+
signal.await();
85+
} catch (InterruptedException e) {
86+
e.printStackTrace();
87+
}
88+
}
89+
90+
public void testEmptyRedirect() throws Exception {
91+
final CountDownLatch signal = new CountDownLatch(1);
92+
try {
93+
final String requestString = "";
94+
IterableHelper.IterableActionHandler clickCallback = new IterableHelper.IterableActionHandler() {
95+
@Override
96+
public void execute(String result) {
97+
assertEquals(requestString, result);
98+
signal.countDown();
99+
}
100+
};
101+
IterableApi.getAndTrackDeeplink(requestString, clickCallback);
102+
signal.await();
103+
} catch (InterruptedException e) {
104+
e.printStackTrace();
105+
}
106+
}
107+
108+
public void testNullRedirect() throws Exception {
109+
final CountDownLatch signal = new CountDownLatch(1);
110+
try {
111+
final String requestString = null;
112+
IterableHelper.IterableActionHandler clickCallback = new IterableHelper.IterableActionHandler() {
113+
@Override
114+
public void execute(String result) {
115+
assertEquals(requestString, result);
116+
signal.countDown();
117+
}
118+
};
119+
IterableApi.getAndTrackDeeplink(requestString, clickCallback);
120+
signal.await();
121+
} catch (InterruptedException e) {
122+
e.printStackTrace();
123+
}
124+
}
125+
126+
public void testMultiRedirectNoRewrite() throws Exception {
127+
final CountDownLatch signal = new CountDownLatch(1);
128+
try {
129+
final String requestString = "https://httpbin.org/redirect/3";
130+
final String redirectString = "https://httpbin.org/redirect/3";
131+
IterableHelper.IterableActionHandler clickCallback = new IterableHelper.IterableActionHandler() {
132+
@Override
133+
public void execute(String result) {
134+
assertEquals(redirectString, result);
135+
signal.countDown();
136+
}
137+
};
138+
IterableApi.getAndTrackDeeplink(requestString, clickCallback);
139+
signal.await();
140+
} catch (InterruptedException e) {
141+
e.printStackTrace();
142+
}
143+
}
144+
145+
//Check re-written link that is a redirected link: links.iterable -> http -> https.
146+
public void testMultiRedirectRewrite() throws Exception {
147+
final CountDownLatch signal = new CountDownLatch(1);
148+
try {
149+
final String requestString = "http://links.iterable.com/a/d89cb7bb7cfb4a56963e0e9abae0f761?_e=dt%40iterable.com&_m=f285fd5320414b3d868b4a97233774fe";
150+
final String redirectString = "http://iterable.com/product/";
151+
final String redirectFinalString = "https://iterable.com/product/";
152+
IterableHelper.IterableActionHandler clickCallback = new IterableHelper.IterableActionHandler() {
153+
@Override
154+
public void execute(String result) {
155+
assertEquals(redirectString, result);
156+
assertFalse(redirectFinalString.equalsIgnoreCase(result));
157+
signal.countDown();
158+
}
159+
};
160+
IterableApi.getAndTrackDeeplink(requestString, clickCallback);
161+
signal.await();
162+
} catch (InterruptedException e) {
163+
e.printStackTrace();
164+
}
165+
}
166+
167+
//Check 404 after Redirect
168+
public void testDNSRedirect() throws Exception {
169+
final CountDownLatch signal = new CountDownLatch(1);
170+
try {
171+
final String requestString = "http://links.iterable.com/a/f4c55a1474074acba6ddbcc4e5a9eb38?_e=dt%40iterable.com&_m=f285fd5320414b3d868b4a97233774fe";
172+
final String redirectString = "http://iterable.com/product/fakeTest";
173+
final String redirectFinalString = "https://iterable.com/product/fakeTest";
174+
IterableHelper.IterableActionHandler clickCallback = new IterableHelper.IterableActionHandler() {
175+
@Override
176+
public void execute(String result) {
177+
assertEquals(redirectString, result);
178+
assertFalse(redirectFinalString.equalsIgnoreCase(result));
179+
signal.countDown();
180+
}
181+
};
182+
IterableApi.getAndTrackDeeplink(requestString, clickCallback);
183+
signal.await();
184+
} catch (InterruptedException e) {
185+
e.printStackTrace();
186+
}
187+
}
188+
189+
//Check 404
190+
public void testDNS() throws Exception {
191+
final CountDownLatch signal = new CountDownLatch(1);
192+
try {
193+
final String userId = "xxx";
194+
final String requestString = "http://links.iterable.com/a/"+userId+"?_e=email&_m=123";
195+
final String badUuid = ITERABLE_BAD_UUID_REQUEST + " " + userId;
196+
IterableHelper.IterableActionHandler clickCallback = new IterableHelper.IterableActionHandler() {
197+
@Override
198+
public void execute(String result) {
199+
assertFalse(requestString.equalsIgnoreCase(result));
200+
assertEquals(badUuid, result);
201+
signal.countDown();
202+
}
203+
};
204+
IterableApi.getAndTrackDeeplink(requestString, clickCallback);
205+
signal.await();
206+
} catch (InterruptedException e) {
207+
e.printStackTrace();
208+
}
209+
}
210+
211+
//Check 400
212+
public void testDNS400() throws Exception {
213+
final CountDownLatch signal = new CountDownLatch(1);
214+
try {
215+
final String requestString = "http://links.iterable.com/a/a";
216+
IterableHelper.IterableActionHandler clickCallback = new IterableHelper.IterableActionHandler() {
217+
@Override
218+
public void execute(String result) {
219+
assertFalse(requestString.equalsIgnoreCase(result));
220+
signal.countDown();
221+
}
222+
};
223+
IterableApi.getAndTrackDeeplink(requestString, clickCallback);
224+
signal.await();
225+
} catch (InterruptedException e) {
226+
e.printStackTrace();
227+
}
228+
}
229+
230+
}
Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,106 @@
11
package com.iterable.iterableapi;
22

3+
import android.annotation.TargetApi;
34
import android.app.Application;
4-
import android.content.pm.ApplicationInfo;
5+
import android.app.NotificationManager;
6+
import android.app.Service;
7+
import android.content.Context;
8+
import android.os.AsyncTask;
9+
import android.os.Build;
510
import android.os.Bundle;
611
import android.test.ApplicationTestCase;
712

13+
import java.util.concurrent.CountDownLatch;
14+
import java.util.concurrent.TimeUnit;
15+
816
/**
917
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
1018
*/
1119
public class IterableNotificationTest extends ApplicationTestCase<Application> {
1220
public IterableNotificationTest() {
1321
super(Application.class);
1422
}
15-
23+
Context appContext;
24+
NotificationManager mNotificationManager;
25+
26+
//EX: itbl_notif = "{\"itbl\":{\"templateId\":28,\"campaignId\":17,\"messageId\":\"85fbb5663ada4f40b5ae0d437e040fa6\",\"isGhostPush\":false},\"body\":\"Pushy\",\"badge\":2,\"sound\":\"me.wav\"}}";
27+
28+
String body = "my first push message";
29+
String sound = "me.wav";
30+
String itbl_ghost = "{\"templateId\":1,\"campaignId\":1,\"messageId\":\"11111111111111111111111111111111\",\"isGhostPush\":true}";
31+
String itbl1 = "{\"templateId\":1,\"campaignId\":1,\"messageId\":\"11111111111111111111111111111111\",\"isGhostPush\":false}";
32+
String itbl2 = "{\"templateId\":2,\"campaignId\":2,\"messageId\":\"22222222222222222222222222222222\",\"isGhostPush\":false}}";
33+
34+
public void setUp() throws Exception {
35+
super.setUp();
36+
37+
appContext = getContext().getApplicationContext();
38+
mNotificationManager = (NotificationManager)
39+
getContext().getSystemService(Context.NOTIFICATION_SERVICE);
40+
mNotificationManager.cancelAll();
41+
}
42+
1643
public void testEmptyBundle() throws Exception {
1744
IterableNotification iterableNotification = IterableNotification.createNotification(getContext(), new Bundle(), Application.class);
1845
assertTrue(iterableNotification.requestCode < System.currentTimeMillis());
1946
}
2047

21-
public void testGhostPushTrue() throws Exception {
22-
23-
String itbl = "{\"templateId\":25,\"campaignId\":15,\"messageId\":\"6780f5b5cd394b80ba944b5c08d7f9a2\",\"isGhostPush\":true}";
24-
48+
public void testGhostPush() throws Exception {
2549
Bundle notif1 = new Bundle();
26-
notif1.putString(IterableConstants.ITERABLE_DATA_KEY, itbl);
27-
50+
notif1.putString(IterableConstants.ITERABLE_DATA_KEY, itbl_ghost);
2851
IterableNotification iterableNotification = IterableNotification.createNotification(getContext(), notif1, Application.class);
52+
IterableNotification.postNotificationOnDevice(appContext, iterableNotification);
2953
assertTrue(iterableNotification.iterableNotificationData.getIsGhostPush());
54+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
55+
assertEquals(0, mNotificationManager.getActiveNotifications().length);
56+
}
3057
}
3158

32-
public void testGhostPushFalse() throws Exception {
3359

34-
String itbl = "{\"templateId\":25,\"campaignId\":15,\"messageId\":\"6780f5b5cd394b80ba944b5c08d7f9a2\",\"isGhostPush\":false}";
60+
public void testNotificationText() throws Exception {
61+
Bundle notif = new Bundle();
62+
notif.putString(IterableConstants.ITERABLE_DATA_KEY, itbl2);
63+
notif.putString(IterableConstants.ITERABLE_DATA_BODY, body);
64+
notif.putString(IterableConstants.ITERABLE_DATA_SOUND, sound);
65+
66+
IterableNotification iterableNotification = IterableNotification.createNotification(getContext(), notif, Application.class);
67+
IterableNotification.postNotificationOnDevice(appContext, iterableNotification);
68+
assertEquals("IterableAPI", iterableNotification.mContentTitle);
69+
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
70+
Bundle notificationExtras = mNotificationManager.getActiveNotifications()[0].getNotification().extras;
71+
assertEquals("IterableAPI", notificationExtras.get("android.title"));
72+
assertEquals(body, notificationExtras.get("android.text"));
73+
}
74+
}
3575

76+
public void testMessage() throws Exception {
3677
Bundle notif1 = new Bundle();
37-
notif1.putString(IterableConstants.ITERABLE_DATA_KEY, itbl);
78+
notif1.putString(IterableConstants.ITERABLE_DATA_KEY, itbl1);
3879

3980
IterableNotification iterableNotification = IterableNotification.createNotification(getContext(), notif1, Application.class);
81+
IterableNotification.postNotificationOnDevice(appContext, iterableNotification);
4082
assertFalse(iterableNotification.iterableNotificationData.getIsGhostPush());
41-
}
83+
assertEquals("11111111111111111111111111111111", iterableNotification.iterableNotificationData.getMessageId());
84+
assertEquals("11111111111111111111111111111111".hashCode(), iterableNotification.requestCode);
85+
assertEquals(1, iterableNotification.iterableNotificationData.getCampaignId());
86+
assertEquals(1, iterableNotification.iterableNotificationData.getTemplateId());
87+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
88+
assertEquals(1, mNotificationManager.getActiveNotifications().length);
89+
}
4290

43-
public void testMessage() throws Exception {
44-
String itbl = "{\"templateId\":25,\"campaignId\":15,\"messageId\":\"6780f5b5cd394b80ba944b5c08d7f9a2\",\"isGhostPush\":false}";
91+
Bundle notif2 = new Bundle();
92+
notif2.putString(IterableConstants.ITERABLE_DATA_KEY, itbl2);
4593

46-
Bundle notif1 = new Bundle();
47-
notif1.putString(IterableConstants.ITERABLE_DATA_KEY, itbl);
94+
IterableNotification iterableNotification2 = IterableNotification.createNotification(getContext(), notif2, Application.class);
95+
IterableNotification.postNotificationOnDevice(appContext, iterableNotification2);
96+
assertFalse(iterableNotification2.iterableNotificationData.getIsGhostPush());
97+
assertEquals("22222222222222222222222222222222", iterableNotification2.iterableNotificationData.getMessageId());
98+
assertEquals("22222222222222222222222222222222".hashCode(), iterableNotification2.requestCode);
99+
assertEquals(2, iterableNotification2.iterableNotificationData.getCampaignId());
100+
assertEquals(2, iterableNotification2.iterableNotificationData.getTemplateId());
101+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
102+
assertEquals(2, mNotificationManager.getActiveNotifications().length);
103+
}
48104

49-
IterableNotification iterableNotification = IterableNotification.createNotification(getContext(), notif1, Application.class);
50-
assertEquals("6780f5b5cd394b80ba944b5c08d7f9a2", iterableNotification.iterableNotificationData.getMessageId());
51-
assertEquals("6780f5b5cd394b80ba944b5c08d7f9a2".hashCode(), iterableNotification.requestCode);
52105
}
53106
}

iterableapi/src/main/AndroidManifest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
<application
55
android:label="@string/app_name"
6-
android:supportsRtl="true">
6+
android:supportsRtl="true"
7+
android:icon="@drawable/common_google_signin_btn_icon_dark">
78

89
</application>
910

0 commit comments

Comments
 (0)