Skip to content

Commit adb8ecb

Browse files
authored
epic/HW-51230 add support paypal ui (#9)
* HW-52538 add support to PayPal account
1 parent 9ab848e commit adb8ecb

File tree

13 files changed

+734
-141
lines changed

13 files changed

+734
-141
lines changed

ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/ListTransferMethodTest.java

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ public void testListTransferMethod_userHasMultipleTransferMethods() {
9090
mActivityTestRule.launchActivity(null);
9191

9292
// assert
93-
onView(withId(R.id.toolbar)).check(matches(isDisplayed()));
9493
onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.toolbar))))
9594
.check(matches(withText(R.string.title_activity_list_transfer_method)));
9695
onView(withId(R.id.fab)).check(matches(isDisplayed()));
@@ -146,7 +145,17 @@ public void testListTransferMethod_userHasMultipleTransferMethods() {
146145
onView(withId(R.id.list_transfer_method_item)).check(
147146
matches(atPosition(4, hasDescendant(withDrawable(R.drawable.ic_three_dots_16dp)))));
148147

149-
onView(withId(R.id.list_transfer_method_item)).check(new RecyclerViewCountAssertion(5));
148+
onView(withId(R.id.list_transfer_method_item)).check(
149+
matches(atPosition(5, hasDescendant(withText(R.string.paypal_account_font_icon)))));
150+
onView(withId(R.id.list_transfer_method_item)).check(
151+
matches(atPosition(5, hasDescendant(withText(R.string.paypal_account)))));
152+
onView(withId(R.id.list_transfer_method_item)).check(
153+
matches(atPosition(5, hasDescendant(withText("United States")))));
154+
//TODO: Try to check for non existence of transfer_method_type_description_2
155+
onView(withId(R.id.list_transfer_method_item)).check(
156+
matches(atPosition(5, hasDescendant(withDrawable(R.drawable.ic_three_dots_16dp)))));
157+
158+
onView(withId(R.id.list_transfer_method_item)).check(new RecyclerViewCountAssertion(6));
150159

151160
}
152161

@@ -337,6 +346,70 @@ public void onReceive(Context context, Intent intent) {
337346

338347
}
339348

349+
@Test
350+
public void testListTransferMethod_removePayPalAccount() throws InterruptedException {
351+
mMockWebServer.mockResponse().withHttpResponseCode(HTTP_OK).withBody(sResourceManager
352+
.getResourceContent("transfer_method_list_single_paypal_account_response.json")).mock();
353+
mMockWebServer.mockResponse().withHttpResponseCode(HTTP_OK).withBody(sResourceManager
354+
.getResourceContent("transfer_method_deactivate_success.json")).mock();
355+
mMockWebServer.mockResponse().withHttpResponseCode(HTTP_NO_CONTENT).withBody("").mock();
356+
357+
358+
final CountDownLatch gate = new CountDownLatch(1);
359+
final BroadcastReceiver br = new BroadcastReceiver() {
360+
@Override
361+
public void onReceive(Context context, Intent intent) {
362+
gate.countDown();
363+
364+
HyperwalletStatusTransition statusTransition = intent.getParcelableExtra(
365+
"hyperwallet-local-broadcast-payload");
366+
assertThat("Transition is not valid", statusTransition.getTransition(), is(DE_ACTIVATED));
367+
}
368+
};
369+
370+
// run test
371+
mActivityTestRule.launchActivity(null);
372+
LocalBroadcastManager.getInstance(mActivityTestRule.getActivity().getApplicationContext())
373+
.registerReceiver(br, new IntentFilter("ACTION_HYPERWALLET_TRANSFER_METHOD_DEACTIVATED"));
374+
375+
// assert
376+
onView(withId(R.id.toolbar)).check(matches(isDisplayed()));
377+
onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.toolbar))))
378+
.check(matches(withText(R.string.title_activity_list_transfer_method)));
379+
onView(withId(R.id.fab)).check(matches(isDisplayed()));
380+
381+
onView(withId(R.id.list_transfer_method_item)).check(
382+
matches(atPosition(0, hasDescendant(withText(R.string.paypal_account_font_icon)))));
383+
onView(withId(R.id.list_transfer_method_item)).check(
384+
matches(atPosition(0, hasDescendant(withText(R.string.paypal_account)))));
385+
onView(withId(R.id.list_transfer_method_item)).check(
386+
matches(atPosition(0, hasDescendant(withText("United States")))));
387+
onView(withId(R.id.list_transfer_method_item)).check(
388+
matches(atPosition(0, hasDescendant(withDrawable(R.drawable.ic_three_dots_16dp)))));
389+
390+
onView(allOf(instanceOf(ImageButton.class), hasSibling(withText(R.string.paypal_account)))).perform(click())
391+
.inRoot(Matchers.<Root>instanceOf(MenuItem.class));
392+
onView(withDrawable(R.drawable.ic_trash)).check(matches(isDisplayed()));
393+
onView(withText(R.string.menu_remove_account)).check(matches(isDisplayed())).perform(click());
394+
395+
// confirmation dialog is shown before deletion
396+
onView(withText(R.string.transfer_method_remove_confirmation_title)).check(matches(isDisplayed()));
397+
onView(withText(R.string.transfer_method_remove_confirmation)).check(matches(isDisplayed()));
398+
onView(withId(android.R.id.button1)).check(matches(withText(R.string.remove_button_label)));
399+
onView(withId(android.R.id.button2)).check(matches(withText(R.string.cancel_button_label)));
400+
401+
onView(withId(android.R.id.button1)).perform(click());
402+
403+
gate.await(5, SECONDS);
404+
LocalBroadcastManager.getInstance(mActivityTestRule.getActivity().getApplicationContext()).unregisterReceiver(
405+
br);
406+
assertThat("Action is not broadcasted", gate.getCount(), is(0L));
407+
408+
onView(withId(R.id.empty_transfer_method_list_layout)).check(matches(isDisplayed()));
409+
onView(withText(R.string.empty_list_transfer_method_information)).check(matches(isDisplayed()));
410+
411+
}
412+
340413
@Test
341414
public void testListTransferMethod_removeBankAccountClickCancel() throws InterruptedException {
342415
mMockWebServer.mockResponse().withHttpResponseCode(HTTP_OK).withBody(sResourceManager
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
package com.hyperwallet.android.transfermethod.ui;
2+
3+
import static androidx.test.espresso.Espresso.onView;
4+
import static androidx.test.espresso.action.ViewActions.click;
5+
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
6+
import static androidx.test.espresso.action.ViewActions.typeText;
7+
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
8+
import static androidx.test.espresso.assertion.ViewAssertions.matches;
9+
import static androidx.test.espresso.matcher.RootMatchers.isDialog;
10+
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
11+
import static androidx.test.espresso.matcher.ViewMatchers.withId;
12+
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
13+
import static androidx.test.espresso.matcher.ViewMatchers.withText;
14+
15+
import static org.hamcrest.CoreMatchers.containsString;
16+
import static org.hamcrest.MatcherAssert.assertThat;
17+
import static org.hamcrest.Matchers.allOf;
18+
import static org.hamcrest.Matchers.instanceOf;
19+
import static org.hamcrest.Matchers.is;
20+
21+
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
22+
import static java.net.HttpURLConnection.HTTP_CREATED;
23+
import static java.net.HttpURLConnection.HTTP_OK;
24+
import static java.util.concurrent.TimeUnit.SECONDS;
25+
26+
import static com.hyperwallet.android.util.EspressoUtils.hasErrorText;
27+
import static com.hyperwallet.android.util.EspressoUtils.nestedScrollTo;
28+
import static com.hyperwallet.android.util.EspressoUtils.withHint;
29+
30+
import android.app.Activity;
31+
import android.content.BroadcastReceiver;
32+
import android.content.Context;
33+
import android.content.Intent;
34+
import android.content.IntentFilter;
35+
import android.widget.TextView;
36+
37+
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
38+
import androidx.test.core.app.ApplicationProvider;
39+
import androidx.test.espresso.IdlingRegistry;
40+
import androidx.test.ext.junit.runners.AndroidJUnit4;
41+
import androidx.test.rule.ActivityTestRule;
42+
43+
import com.hyperwallet.android.Hyperwallet;
44+
import com.hyperwallet.android.hyperwallet_ui.R;
45+
import com.hyperwallet.android.model.HyperwalletTransferMethod;
46+
import com.hyperwallet.android.rule.HyperwalletExternalResourceManager;
47+
import com.hyperwallet.android.rule.HyperwalletMockWebServer;
48+
import com.hyperwallet.android.ui.repository.RepositoryFactory;
49+
import com.hyperwallet.android.ui.transfermethod.AddTransferMethodActivity;
50+
import com.hyperwallet.android.ui.util.EspressoIdlingResource;
51+
import com.hyperwallet.android.util.TestAuthenticationProvider;
52+
53+
import org.junit.After;
54+
import org.junit.Before;
55+
import org.junit.ClassRule;
56+
import org.junit.Rule;
57+
import org.junit.Test;
58+
import org.junit.runner.RunWith;
59+
60+
import java.util.concurrent.CountDownLatch;
61+
62+
@RunWith(AndroidJUnit4.class)
63+
public class PayPalTest {
64+
65+
@ClassRule
66+
public static HyperwalletExternalResourceManager sResourceManager = new HyperwalletExternalResourceManager();
67+
@Rule
68+
public HyperwalletMockWebServer mMockWebServer = new HyperwalletMockWebServer(8080);
69+
@Rule
70+
public ActivityTestRule<AddTransferMethodActivity> mActivityTestRule =
71+
new ActivityTestRule<AddTransferMethodActivity>(AddTransferMethodActivity.class, true, false) {
72+
@Override
73+
protected Intent getActivityIntent() {
74+
Intent intent = new Intent(ApplicationProvider.getApplicationContext(),
75+
AddTransferMethodActivity.class);
76+
intent.putExtra("TRANSFER_METHOD_TYPE", "PAYPAL_ACCOUNT");
77+
intent.putExtra("TRANSFER_METHOD_COUNTRY", "US");
78+
intent.putExtra("TRANSFER_METHOD_CURRENCY", "USD");
79+
return intent;
80+
}
81+
};
82+
83+
@Before
84+
public void setup() {
85+
Hyperwallet.getInstance(new TestAuthenticationProvider());
86+
87+
mMockWebServer.mockResponse().withHttpResponseCode(HTTP_OK).withBody(sResourceManager
88+
.getResourceContent("authentication_token_response.json")).mock();
89+
mMockWebServer.mockResponse().withHttpResponseCode(HTTP_OK).withBody(sResourceManager
90+
.getResourceContent("successful_tmc_paypal_fields_response.json")).mock();
91+
}
92+
93+
@After
94+
public void cleanup() {
95+
RepositoryFactory.clearInstance();
96+
}
97+
98+
@Before
99+
public void registerIdlingResource() {
100+
IdlingRegistry.getInstance().register(EspressoIdlingResource.getIdlingResource());
101+
}
102+
103+
@After
104+
public void unregisterIdlingResource() {
105+
IdlingRegistry.getInstance().unregister(EspressoIdlingResource.getIdlingResource());
106+
}
107+
108+
@Test
109+
public void testAddTransferMethod_displaysElementsOnTmcResponse() {
110+
mActivityTestRule.launchActivity(null);
111+
112+
onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.toolbar)))).check(
113+
matches(withText(R.string.paypal_account)));
114+
115+
onView(withId(R.id.email)).check(matches(isDisplayed()));
116+
onView(withId(R.id.emailLabel)).check(matches(withHint("Email")));
117+
118+
onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo()).check(
119+
matches(withText(R.string.button_create_transfer_method)));
120+
}
121+
122+
@Test
123+
public void testAddTransferMethod_displaysFeeElementsOnTmcResponse() {
124+
mActivityTestRule.launchActivity(null);
125+
126+
onView(withId(R.id.add_transfer_method_fee_label)).check(
127+
matches(withText(R.string.add_transfer_method_fee_label)));
128+
onView(withId(R.id.add_transfer_method_processing_label)).check(
129+
matches(withText(R.string.add_transfer_method_processing_time_label)));
130+
onView(withId(R.id.add_transfer_method_fee_value)).check(matches(withText("USD 0.25")));
131+
onView(withId(R.id.add_transfer_method_processing_time_value)).check(matches(withText("IMMEDIATE")));
132+
}
133+
134+
@Test
135+
public void testAddTransferMethod_returnsTokenOnPaypalAccountCreation() throws InterruptedException {
136+
mMockWebServer.mockResponse().withHttpResponseCode(HTTP_CREATED).withBody(sResourceManager
137+
.getResourceContent("paypal_response.json")).mock();
138+
139+
mActivityTestRule.launchActivity(null);
140+
141+
final CountDownLatch gate = new CountDownLatch(1);
142+
final BroadcastReceiver br = new BroadcastReceiver() {
143+
@Override
144+
public void onReceive(Context context, Intent intent) {
145+
gate.countDown();
146+
147+
HyperwalletTransferMethod transferMethod = intent.getParcelableExtra(
148+
"hyperwallet-local-broadcast-payload");
149+
assertThat("Bank Account Id is incorrect", transferMethod.getField(
150+
HyperwalletTransferMethod.TransferMethodFields.EMAIL), is("sunshine.carreiro@hyperwallet.com"));
151+
}
152+
};
153+
154+
LocalBroadcastManager.getInstance(mActivityTestRule.getActivity().getApplicationContext())
155+
.registerReceiver(br, new IntentFilter("ACTION_HYPERWALLET_TRANSFER_METHOD_ADDED"));
156+
157+
onView(withId(R.id.email))
158+
.perform(typeText("sunshine.carreiro@hyperwallet.com"))
159+
.perform(closeSoftKeyboard());
160+
161+
onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click());
162+
163+
assertThat("Result code is incorrect",
164+
mActivityTestRule.getActivityResult().getResultCode(), is(Activity.RESULT_OK));
165+
166+
gate.await(5, SECONDS);
167+
LocalBroadcastManager.getInstance(mActivityTestRule.getActivity().getApplicationContext()).unregisterReceiver(
168+
br);
169+
assertThat("Action is not broadcasted", gate.getCount(), is(0L));
170+
}
171+
172+
@Test
173+
public void testAddTransferMethod_returnsErrorOnInvalidPattern() {
174+
mActivityTestRule.launchActivity(null);
175+
// Number input should not allow non numeric values
176+
onView(withId(R.id.email)).perform(typeText("abc1test"));
177+
onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click());
178+
179+
onView(withId(R.id.emailLabel))
180+
.check(matches(hasErrorText("accountNumber is invalid")));
181+
}
182+
183+
@Test
184+
public void testAddTransferMethod_returnsErrorOnInvalidPresence() {
185+
mActivityTestRule.launchActivity(null);
186+
187+
onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click());
188+
189+
onView(withId(R.id.emailLabel))
190+
.check(matches(hasErrorText("You must provide a value for this field")));
191+
}
192+
193+
@Test
194+
public void testAddTransferMethod_displaysErrorOnInvalidEmailAddress() {
195+
mMockWebServer.mockResponse().withHttpResponseCode(HTTP_BAD_REQUEST).withBody(sResourceManager
196+
.getResourceContent("paypal_invalid_email_response.json")).mock();
197+
198+
mActivityTestRule.launchActivity(null);
199+
200+
onView(withId(R.id.email))
201+
.perform(typeText("invalidEmail@gmail.com")).perform(closeSoftKeyboard());
202+
onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click());
203+
204+
// check dialog content
205+
onView(withText(R.string.error_dialog_title)).inRoot(isDialog()).check(matches(isDisplayed()));
206+
onView(withText(containsString(
207+
"PayPal transfer method email address should be same as profile email address.")))
208+
.inRoot(isDialog()).check(matches(isDisplayed()));
209+
onView(withId(android.R.id.button1)).check(matches(withText(R.string.close_button_label)));
210+
onView(withId(android.R.id.button1)).perform(click());
211+
212+
// should display the add tm form
213+
onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.toolbar)))).check(
214+
matches(withText(R.string.paypal_account)));
215+
216+
// connectivity dialog should be dismissed and does not exist in ui
217+
onView(withText(R.string.error_dialog_title)).check(doesNotExist());
218+
}
219+
220+
}

0 commit comments

Comments
 (0)