Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package com.hyperwallet.android.transfermethod.ui;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.RootMatchers.isDialog;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;

import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
import static java.net.HttpURLConnection.HTTP_CREATED;
import static java.net.HttpURLConnection.HTTP_OK;
import static java.util.concurrent.TimeUnit.SECONDS;

import static com.hyperwallet.android.util.EspressoUtils.hasErrorText;
import static com.hyperwallet.android.util.EspressoUtils.nestedScrollTo;
import static com.hyperwallet.android.util.EspressoUtils.withHint;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.TextView;

import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.espresso.IdlingRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.rule.ActivityTestRule;

import com.hyperwallet.android.Hyperwallet;
import com.hyperwallet.android.hyperwallet_ui.R;
import com.hyperwallet.android.model.HyperwalletTransferMethod;
import com.hyperwallet.android.rule.HyperwalletExternalResourceManager;
import com.hyperwallet.android.rule.HyperwalletMockWebServer;
import com.hyperwallet.android.ui.repository.RepositoryFactory;
import com.hyperwallet.android.ui.transfermethod.AddTransferMethodActivity;
import com.hyperwallet.android.ui.util.EspressoIdlingResource;
import com.hyperwallet.android.util.TestAuthenticationProvider;

import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.concurrent.CountDownLatch;

@RunWith(AndroidJUnit4.class)
public class PayPalTest {

@ClassRule
public static HyperwalletExternalResourceManager sResourceManager = new HyperwalletExternalResourceManager();
@Rule
public HyperwalletMockWebServer mMockWebServer = new HyperwalletMockWebServer(8080);
@Rule
public ActivityTestRule<AddTransferMethodActivity> mActivityTestRule =
new ActivityTestRule<AddTransferMethodActivity>(AddTransferMethodActivity.class, true, false) {
@Override
protected Intent getActivityIntent() {
Intent intent = new Intent(ApplicationProvider.getApplicationContext(),
AddTransferMethodActivity.class);
intent.putExtra("TRANSFER_METHOD_TYPE", "PAYPAL_ACCOUNT");
intent.putExtra("TRANSFER_METHOD_COUNTRY", "US");
intent.putExtra("TRANSFER_METHOD_CURRENCY", "USD");
return intent;
}
};

@Before
public void setup() {
Hyperwallet.getInstance(new TestAuthenticationProvider());

mMockWebServer.mockResponse().withHttpResponseCode(HTTP_OK).withBody(sResourceManager
.getResourceContent("authentication_token_response.json")).mock();
mMockWebServer.mockResponse().withHttpResponseCode(HTTP_OK).withBody(sResourceManager
.getResourceContent("successful_tmc_paypal_fields_response.json")).mock();
}

@After
public void cleanup() {
RepositoryFactory.clearInstance();
}

@Before
public void registerIdlingResource() {
IdlingRegistry.getInstance().register(EspressoIdlingResource.getIdlingResource());
}

@After
public void unregisterIdlingResource() {
IdlingRegistry.getInstance().unregister(EspressoIdlingResource.getIdlingResource());
}

@Test
public void testAddTransferMethod_displaysElementsOnTmcResponse() {
mActivityTestRule.launchActivity(null);

onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.toolbar)))).check(
matches(withText(R.string.paypal_account)));

onView(withId(R.id.email)).check(matches(isDisplayed()));
onView(withId(R.id.emailLabel)).check(matches(withHint("Email")));

onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo()).check(
matches(withText(R.string.button_create_transfer_method)));
}

@Test
public void testAddTransferMethod_displaysFeeElementsOnTmcResponse() {
mActivityTestRule.launchActivity(null);

onView(withId(R.id.add_transfer_method_fee_label)).check(
matches(withText(R.string.add_transfer_method_fee_label)));
onView(withId(R.id.add_transfer_method_processing_label)).check(
matches(withText(R.string.add_transfer_method_processing_time_label)));
onView(withId(R.id.add_transfer_method_fee_value)).check(matches(withText("USD 0.25")));
onView(withId(R.id.add_transfer_method_processing_time_value)).check(matches(withText("IMMEDIATE")));
}

@Test
public void testAddTransferMethod_returnsTokenOnPaypalAccountCreation() throws InterruptedException {
mMockWebServer.mockResponse().withHttpResponseCode(HTTP_CREATED).withBody(sResourceManager
.getResourceContent("paypal_response.json")).mock();

mActivityTestRule.launchActivity(null);

final CountDownLatch gate = new CountDownLatch(1);
final BroadcastReceiver br = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
gate.countDown();

HyperwalletTransferMethod transferMethod = intent.getParcelableExtra(
"hyperwallet-local-broadcast-payload");
assertThat("Bank Account Id is incorrect", transferMethod.getField(
HyperwalletTransferMethod.TransferMethodFields.EMAIL), is("sunshine.carreiro@hyperwallet.com"));
}
};

LocalBroadcastManager.getInstance(mActivityTestRule.getActivity().getApplicationContext())
.registerReceiver(br, new IntentFilter("ACTION_HYPERWALLET_TRANSFER_METHOD_ADDED"));

onView(withId(R.id.email))
.perform(typeText("sunshine.carreiro@hyperwallet.com"))
.perform(closeSoftKeyboard());

onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click());

assertThat("Result code is incorrect",
mActivityTestRule.getActivityResult().getResultCode(), is(Activity.RESULT_OK));

gate.await(5, SECONDS);
LocalBroadcastManager.getInstance(mActivityTestRule.getActivity().getApplicationContext()).unregisterReceiver(
br);
assertThat("Action is not broadcasted", gate.getCount(), is(0L));
}

@Test
public void testAddTransferMethod_returnsErrorOnInvalidPattern() {
mActivityTestRule.launchActivity(null);
// Number input should not allow non numeric values
onView(withId(R.id.email)).perform(typeText("abc1test"));
onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click());

onView(withId(R.id.emailLabel))
.check(matches(hasErrorText("accountNumber is invalid")));
}

@Test
public void testAddTransferMethod_returnsErrorOnInvalidPresence() {
mActivityTestRule.launchActivity(null);

onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click());

onView(withId(R.id.emailLabel))
.check(matches(hasErrorText("You must provide a value for this field")));
}

@Test
public void testAddTransferMethod_displaysErrorOnInvalidEmailAddress() {
mMockWebServer.mockResponse().withHttpResponseCode(HTTP_BAD_REQUEST).withBody(sResourceManager
.getResourceContent("paypal_invalid_email_response.json")).mock();

mActivityTestRule.launchActivity(null);

onView(withId(R.id.email))
.perform(typeText("invalidEmail@gmail.com")).perform(closeSoftKeyboard());
onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click());

// check dialog content
onView(withText(R.string.error_dialog_title)).inRoot(isDialog()).check(matches(isDisplayed()));
onView(withText(containsString(
"PayPal transfer method email address should be same as profile email address.")))
.inRoot(isDialog()).check(matches(isDisplayed()));
onView(withId(android.R.id.button1)).check(matches(withText(R.string.close_button_label)));
onView(withId(android.R.id.button1)).perform(click());

// should display the add tm form
onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.toolbar)))).check(
matches(withText(R.string.paypal_account)));

// connectivity dialog should be dismissed and does not exist in ui
onView(withText(R.string.error_dialog_title)).check(doesNotExist());
}

}
2 changes: 2 additions & 0 deletions ui/src/main/res/values/ids.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@
<item name="dateOfExpiryLabel" type="id" />
<item name="cvv" type="id" />
<item name="cvvLabel" type="id" />
<item name="email" type="id"/>
<item name="emailLabel" type="id"/>
</resources>
8 changes: 8 additions & 0 deletions ui/src/test/resources/paypal_invalid_email_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"errors": [
{
"message": "PayPal transfer method email address should be same as profile email address.",
"code": "CONSTRAINT_VIOLATIONS"
}
]
}
17 changes: 17 additions & 0 deletions ui/src/test/resources/paypal_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"token": "trm-6a29ddd5-6913-479e-a60c-24dc6bf14cd4",
"type": "PAYPAL_ACCOUNT",
"status": "ACTIVATED",
"createdOn": "2019-05-08T00:25:23",
"transferMethodCountry": "US",
"transferMethodCurrency": "USD",
"email": "sunshine.carreiro@hyperwallet.com",
"links": [
{
"params": {
"rel": "self"
},
"href": "https://localhost:8181/rest/v3/users/usr-d702cfa0-7cb1-491d-8f25-9b896003e872/paypal-accounts/trm-6a29ddd5-6913-479e-a60c-24dc6bf14cd4"
}
]
}
46 changes: 46 additions & 0 deletions ui/src/test/resources/successful_tmc_paypal_fields_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"data": {
"transferMethodConfigurations": {
"nodes": [
{
"countries": [
"US"
],
"currencies": [
"USD"
],
"transferMethodType": "PAYPAL_ACCOUNT",
"profile": "INDIVIDUAL",
"processingTime": "IMMEDIATE",
"fees": {
"nodes": [
{
"transferMethodType": "PAYPAL_ACCOUNT",
"country": "US",
"currency": "USD",
"feeRateType": "FLAT",
"value": "0.25"
}
]
},
"fields": [
{
"category": "ACCOUNT",
"dataType": "TEXT",
"isRequired": true,
"label": "Email",
"name": "email",
"placeholder": "",
"regularExpression": "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$",
"validationMessage": {
"length": "",
"pattern": "accountNumber is invalid",
"empty": "You must provide a value for this field"
}
}
]
}
]
}
}
}