From f94e6fa58c416e0c5d574edcee1d05c898c619a6 Mon Sep 17 00:00:00 2001 From: Jeremy Lejoux Date: Thu, 17 Oct 2019 16:11:20 +0200 Subject: [PATCH 1/2] tests: add UI test suit --- app/build.gradle | 5 +- .../processoutexample/ExampleUnitTest.java | 17 - processout-sdk/build.gradle | 14 +- .../ExampleInstrumentedTest.java | 26 - .../processout_sdk/ProcessOutTest.java | 158 +---- .../processout_sdk/UITestSuite.java | 666 ++++++++++++++++++ processout-sdk/src/main/AndroidManifest.xml | 13 +- .../processout_sdk/TestActivity.java | 14 + .../src/main/res/layout/activity_test.xml | 9 + 9 files changed, 717 insertions(+), 205 deletions(-) delete mode 100644 app/src/test/java/com/processout/processoutexample/ExampleUnitTest.java delete mode 100644 processout-sdk/src/androidTest/java/com/processout/processout_sdk/ExampleInstrumentedTest.java create mode 100644 processout-sdk/src/androidTest/java/com/processout/processout_sdk/UITestSuite.java create mode 100644 processout-sdk/src/main/java/com/processout/processout_sdk/TestActivity.java create mode 100644 processout-sdk/src/main/res/layout/activity_test.xml diff --git a/app/build.gradle b/app/build.gradle index 62ab7cbc..9239e0bd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,8 +25,9 @@ dependencies { implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support:design:28.0.0' testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + implementation project(':processout-sdk') implementation 'com.google.code.gson:gson:2.8.2' } diff --git a/app/src/test/java/com/processout/processoutexample/ExampleUnitTest.java b/app/src/test/java/com/processout/processoutexample/ExampleUnitTest.java deleted file mode 100644 index 15cde945..00000000 --- a/app/src/test/java/com/processout/processoutexample/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.processout.processoutexample; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() throws Exception { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/processout-sdk/build.gradle b/processout-sdk/build.gradle index 8b1b815a..7491d046 100644 --- a/processout-sdk/build.gradle +++ b/processout-sdk/build.gradle @@ -9,7 +9,7 @@ android { versionCode 1 versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -20,15 +20,21 @@ android { } } + packagingOptions { + exclude 'META-INF/proguard/androidx-annotations.pro' + } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' - testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + androidTestImplementation 'androidx.test.espresso:espresso-web:3.2.0' + androidTestImplementation 'androidx.test:rules:1.2.0' + implementation 'com.android.volley:volley:1.1.0' implementation 'com.google.code.gson:gson:2.8.2' diff --git a/processout-sdk/src/androidTest/java/com/processout/processout_sdk/ExampleInstrumentedTest.java b/processout-sdk/src/androidTest/java/com/processout/processout_sdk/ExampleInstrumentedTest.java deleted file mode 100644 index 97a439d8..00000000 --- a/processout-sdk/src/androidTest/java/com/processout/processout_sdk/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.processout.processout_sdk; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.assertEquals; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() throws Exception { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("com.processout.processout_sdk.test", appContext.getPackageName()); - } -} diff --git a/processout-sdk/src/androidTest/java/com/processout/processout_sdk/ProcessOutTest.java b/processout-sdk/src/androidTest/java/com/processout/processout_sdk/ProcessOutTest.java index d7548ce1..3dde725a 100644 --- a/processout-sdk/src/androidTest/java/com/processout/processout_sdk/ProcessOutTest.java +++ b/processout-sdk/src/androidTest/java/com/processout/processout_sdk/ProcessOutTest.java @@ -1,10 +1,5 @@ package com.processout.processout_sdk; -import android.app.Activity; -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.util.Log; - import com.android.volley.Request; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -15,160 +10,17 @@ import java.util.concurrent.CountDownLatch; +import androidx.test.core.app.ApplicationProvider; + import static org.junit.Assert.fail; + public class ProcessOutTest { private String projectId = "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x"; private String privateKey = "key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB"; - final private ProcessOut p = new ProcessOut(InstrumentationRegistry.getContext(), projectId); + final private ProcessOut p = new ProcessOut(ApplicationProvider.getApplicationContext(), projectId); private Gson gson = new GsonBuilder().disableHtmlEscaping().create(); - final Context withActivity = InstrumentationRegistry.getContext(); - - @Test - public void threeDS2Fingerprint() { - final CountDownLatch signal = new CountDownLatch(1); - - - Card c = new Card("4000000000003063", 10, 20, "737"); - p.tokenize(c,null, new TokenCallback() { - @Override - public void onError(Exception error) { - fail("Could not tokenize the card"); - } - - @Override - public void onSuccess(final String token) { - Invoice invoice = new Invoice("test", "121.01", "EUR", new Device("android")); - try { - JSONObject body = new JSONObject(gson.toJson(invoice)); - Network.getTestInstance(InstrumentationRegistry.getContext(), projectId, privateKey).CallProcessOut("/invoices", Request.Method.POST, body, new Network.NetworkResult() { - @Override - public void onError(Exception error) { - Log.e("PROCESSOUT", error.toString()); - fail("Invoice creation failed"); - } - - @Override - public void onSuccess(JSONObject json) { - try { - Invoice invoiceResult = gson.fromJson(json.getJSONObject("invoice").toString(), Invoice.class); - p.makeCardPayment(invoiceResult.getId(), token, new ThreeDSHandler() { - @Override - public void doFingerprint(DirectoryServerData directoryServerData, DoFingerprintCallback callback) { - callback.continueCallback( - new ThreeDSFingerprintResponse( - "", "", new SDKEPhemPubKey("", "", "", ""), - "", "")); - } - - @Override - public void doChallenge(AuthenticationChallengeData authData, final DoChallengeCallback callback) { - callback.success(); - } - - @Override - public void onSuccess(String invoiceId) { - signal.countDown(); - } - - @Override - public void onError(Exception error) { - fail("ThreeDS2 failed"); - } - }, withActivity); - } catch (JSONException e) { - fail("Unhandled exception"); - e.printStackTrace(); - } - } - }); - } catch (JSONException e) { - fail("Unhandled exception"); - e.printStackTrace(); - } - } - }); - - try { - signal.await();// wait for callback - } catch (InterruptedException e) { - e.printStackTrace(); - fail("Could not run test"); - } - } - - @Test - public void threeDS2Challenge() { - final CountDownLatch signal = new CountDownLatch(1); - - Card c = new Card("4000000000000101", 10, 20, "737"); - p.tokenize(c,null, new TokenCallback() { - @Override - public void onError(Exception error) { - fail("Could not tokenize the card"); - } - - @Override - public void onSuccess(final String token) { - // Creation of the invoice - Invoice invoice = new Invoice("test", "121.01", "EUR", new Device("android")); - try { - JSONObject body = new JSONObject(gson.toJson(invoice)); - Network.getTestInstance(InstrumentationRegistry.getContext(), projectId, privateKey).CallProcessOut("/invoices", Request.Method.POST, body, new Network.NetworkResult() { - @Override - public void onError(Exception error) { - fail("Invoice creation failed"); - } - - @Override - public void onSuccess(JSONObject json) { - try { - Invoice invoiceResult = gson.fromJson(json.getJSONObject("invoice").toString(), Invoice.class); - p.makeCardPayment(invoiceResult.getId(), token, new ThreeDSHandler() { - @Override - public void doFingerprint(DirectoryServerData directoryServerData, DoFingerprintCallback callback) { - callback.continueCallback( - new ThreeDSFingerprintResponse( - "", "", new SDKEPhemPubKey("", "", "", ""), - "", "")); - } - - @Override - public void doChallenge(AuthenticationChallengeData authData, final DoChallengeCallback callback) { - callback.success(); - } - - @Override - public void onSuccess(String invoiceId) { - signal.countDown(); - } - - @Override - public void onError(Exception error) { - fail("ThreeDS2 failed" + error.toString()); - } - }, withActivity); - } catch (JSONException e) { - fail("Unhandled exception"); - e.printStackTrace(); - } - } - }); - } catch (JSONException e) { - fail("Unhandled exception"); - e.printStackTrace(); - } - } - }); - - try { - signal.await();// wait for callback - } catch (InterruptedException e) { - e.printStackTrace(); - fail("Could not run test"); - } - } @Test public void tokenize() { @@ -203,7 +55,7 @@ public void listAlternativePaymentGateways() { Invoice invoice = new Invoice("test", "123.0", "EUR", new Device("android")); try { JSONObject body = new JSONObject(gson.toJson(invoice)); - Network.getTestInstance(InstrumentationRegistry.getContext(), projectId, privateKey).CallProcessOut("/invoices", Request.Method.POST, body, new Network.NetworkResult() { + Network.getTestInstance(ApplicationProvider.getApplicationContext(), projectId, privateKey).CallProcessOut("/invoices", Request.Method.POST, body, new Network.NetworkResult() { @Override public void onError(Exception error) { fail(error.toString()); diff --git a/processout-sdk/src/androidTest/java/com/processout/processout_sdk/UITestSuite.java b/processout-sdk/src/androidTest/java/com/processout/processout_sdk/UITestSuite.java new file mode 100644 index 00000000..0cd6d9f7 --- /dev/null +++ b/processout-sdk/src/androidTest/java/com/processout/processout_sdk/UITestSuite.java @@ -0,0 +1,666 @@ +package com.processout.processout_sdk; + +import android.app.Activity; +import android.os.Handler; +import android.view.View; +import android.widget.FrameLayout; + +import com.android.volley.Request; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.processout.processout_sdk.POWebViews.ProcessOutWebView; + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.CountDownLatch; + +import androidx.test.filters.LargeTest; +import androidx.test.rule.ActivityTestRule; +import androidx.test.runner.AndroidJUnit4; + +import static org.junit.Assert.fail; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +@LargeTest +public class UITestSuite { + + private String projectId = "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x"; + private String privateKey = "key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB"; + private Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + + @Rule + public ActivityTestRule activityRule = new ActivityTestRule<>(TestActivity.class, false, true); + + /** + * TEST MAKE CARD PAYMENT + */ + + @Test + public void testSuccessful3DSPayment() { + final CountDownLatch signal = new CountDownLatch(1); + + final Activity withActivity = activityRule.getActivity(); + final ProcessOut p = new ProcessOut(withActivity, projectId); + Card c = new Card("4000000000003246", 10, 20, "737"); + p.tokenize(c, null, new TokenCallback() { + @Override + public void onError(Exception error) { + fail("Could not tokenize the card"); + } + + @Override + public void onSuccess(final String token) { + Invoice invoice = new Invoice("test", "121.01", "EUR", new Device("android")); + JSONObject body = null; + try { + body = new JSONObject(gson.toJson(invoice)); + } catch (Exception e) { + fail("Could not encode body"); + return; + } + + Network.getTestInstance(withActivity, projectId, privateKey).CallProcessOut("/invoices", Request.Method.POST, body, new Network.NetworkResult() { + @Override + public void onError(Exception error) { + fail("Invoice creation failed"); + } + + @Override + public void onSuccess(JSONObject json) { + Invoice invoiceResult = null; + try { + invoiceResult = gson.fromJson(json.getJSONObject("invoice").toString(), Invoice.class); + } catch (JSONException e) { + fail("Unhandled exception"); + e.printStackTrace(); + return; + } + + p.makeCardPayment(invoiceResult.getId(), token, new ThreeDSHandler() { + @Override + public void doFingerprint(DirectoryServerData directoryServerData, DoFingerprintCallback callback) { + callback.continueCallback( + new ThreeDSFingerprintResponse( + "", "", new SDKEPhemPubKey("", "", "", ""), + "", "")); + } + + @Override + public void doChallenge(AuthenticationChallengeData authData, final DoChallengeCallback callback) { + callback.success(); + } + + @Override + public void doPresentWebView(final ProcessOutWebView webView) { + final FrameLayout layout = withActivity.findViewById(android.R.id.content); + final int id = View.generateViewId(); + webView.setId(id); + layout.addView(webView); + + // Wait for the page to load and simulate successful click + Handler handler = new Handler(); + Runnable r = new Runnable() { + public void run() { + // Simulate a click + webView.loadUrl("javascript:document.getElementsByTagName('a')[0].click()"); + } + }; + handler.postDelayed(r, 4000); + } + + @Override + public void onSuccess(String invoiceId) { + signal.countDown(); + } + + @Override + public void onError(Exception error) { + signal.countDown(); +// fail("ThreeDS2 failed"); + } + }, withActivity); + } + }); + } + }); + + try { + signal.await();// wait for callback + } catch (InterruptedException e) { + fail("Could not run test"); + } + } + + @Test + public void testSuccessful3DS2Payment() { + final CountDownLatch signal = new CountDownLatch(1); + + final Activity withActivity = activityRule.getActivity(); + final ProcessOut p = new ProcessOut(withActivity, projectId); + Card c = new Card("4000000000003253", 10, 20, "737"); + p.tokenize(c, null, new TokenCallback() { + @Override + public void onError(Exception error) { + fail("Could not tokenize the card"); + } + + @Override + public void onSuccess(final String token) { + Invoice invoice = new Invoice("test", "121.01", "EUR", new Device("android")); + JSONObject body = null; + try { + body = new JSONObject(gson.toJson(invoice)); + } catch (Exception e) { + fail("Could not encode body"); + return; + } + + Network.getTestInstance(withActivity, projectId, privateKey).CallProcessOut("/invoices", Request.Method.POST, body, new Network.NetworkResult() { + @Override + public void onError(Exception error) { + fail("Invoice creation failed"); + } + + @Override + public void onSuccess(JSONObject json) { + Invoice invoiceResult = null; + try { + invoiceResult = gson.fromJson(json.getJSONObject("invoice").toString(), Invoice.class); + } catch (JSONException e) { + fail("Unhandled exception"); + e.printStackTrace(); + return; + } + + p.makeCardPayment(invoiceResult.getId(), token, new ThreeDSHandler() { + @Override + public void doFingerprint(DirectoryServerData directoryServerData, DoFingerprintCallback callback) { + callback.continueCallback( + new ThreeDSFingerprintResponse( + "", "", new SDKEPhemPubKey("", "", "", ""), + "", "")); + } + + @Override + public void doChallenge(AuthenticationChallengeData authData, final DoChallengeCallback callback) { + callback.success(); + } + + @Override + public void doPresentWebView(final ProcessOutWebView webView) { + fail("Webview should not be required"); + } + + @Override + public void onSuccess(String invoiceId) { + signal.countDown(); + } + + @Override + public void onError(Exception error) { + fail("ThreeDS2 failed"); + } + }, withActivity); + } + }); + } + }); + + try { + signal.await();// wait for callback + } catch (InterruptedException e) { + fail("Could not run test"); + } + } + + @Test + public void testFailed3DS1Payment() { + final CountDownLatch signal = new CountDownLatch(1); + + final Activity withActivity = activityRule.getActivity(); + final ProcessOut p = new ProcessOut(withActivity, projectId); + Card c = new Card("4000000000003246", 10, 20, "737"); + p.tokenize(c, null, new TokenCallback() { + @Override + public void onError(Exception error) { + fail("Could not tokenize the card"); + } + + @Override + public void onSuccess(final String token) { + Invoice invoice = new Invoice("test", "121.01", "EUR", new Device("android")); + JSONObject body = null; + try { + body = new JSONObject(gson.toJson(invoice)); + } catch (Exception e) { + fail("Could not encode body"); + return; + } + + Network.getTestInstance(withActivity, projectId, privateKey).CallProcessOut("/invoices", Request.Method.POST, body, new Network.NetworkResult() { + @Override + public void onError(Exception error) { + fail("Invoice creation failed"); + } + + @Override + public void onSuccess(JSONObject json) { + Invoice invoiceResult = null; + try { + invoiceResult = gson.fromJson(json.getJSONObject("invoice").toString(), Invoice.class); + } catch (JSONException e) { + fail("Unhandled exception"); + e.printStackTrace(); + return; + } + + p.makeCardPayment(invoiceResult.getId(), token, new ThreeDSHandler() { + @Override + public void doFingerprint(DirectoryServerData directoryServerData, DoFingerprintCallback callback) { + callback.continueCallback( + new ThreeDSFingerprintResponse( + "", "", new SDKEPhemPubKey("", "", "", ""), + "", "")); + } + + @Override + public void doChallenge(AuthenticationChallengeData authData, final DoChallengeCallback callback) { + callback.success(); + } + + @Override + public void doPresentWebView(final ProcessOutWebView webView) { + final FrameLayout layout = withActivity.findViewById(android.R.id.content); + final int id = View.generateViewId(); + webView.setId(id); + layout.addView(webView); + + // Wait for the page to load and simulate successful click + Handler handler = new Handler(); + Runnable r = new Runnable() { + public void run() { + // Simulate a click + webView.loadUrl("javascript:document.getElementsByTagName('a')[1].click()"); + } + }; + handler.postDelayed(r, 4000); + } + + @Override + public void onSuccess(String invoiceId) { + fail("ThreeDS2 succeeded but should have failed."); + } + + @Override + public void onError(Exception error) { + signal.countDown(); + } + }, withActivity); + } + }); + } + }); + + try { + signal.await();// wait for callback + } catch (InterruptedException e) { + fail("Could not run test"); + } + } + + @Test + public void testFailed3DS2Challenge() { + final CountDownLatch signal = new CountDownLatch(1); + + final Activity withActivity = activityRule.getActivity(); + final ProcessOut p = new ProcessOut(withActivity, projectId); + Card c = new Card("4000000000003253", 10, 20, "737"); + p.tokenize(c, null, new TokenCallback() { + @Override + public void onError(Exception error) { + fail("Could not tokenize the card"); + } + + @Override + public void onSuccess(final String token) { + Invoice invoice = new Invoice("test", "121.01", "EUR", new Device("android")); + JSONObject body = null; + try { + body = new JSONObject(gson.toJson(invoice)); + } catch (Exception e) { + fail("Could not encode body"); + return; + } + + Network.getTestInstance(withActivity, projectId, privateKey).CallProcessOut("/invoices", Request.Method.POST, body, new Network.NetworkResult() { + @Override + public void onError(Exception error) { + fail("Invoice creation failed"); + } + + @Override + public void onSuccess(JSONObject json) { + Invoice invoiceResult = null; + try { + invoiceResult = gson.fromJson(json.getJSONObject("invoice").toString(), Invoice.class); + } catch (JSONException e) { + fail("Unhandled exception"); + e.printStackTrace(); + return; + } + + p.makeCardPayment(invoiceResult.getId(), token, new ThreeDSHandler() { + @Override + public void doFingerprint(DirectoryServerData directoryServerData, DoFingerprintCallback callback) { + callback.continueCallback( + new ThreeDSFingerprintResponse( + "", "", new SDKEPhemPubKey("", "", "", ""), + "", "")); + } + + @Override + public void doChallenge(AuthenticationChallengeData authData, final DoChallengeCallback callback) { + callback.error(); + } + + @Override + public void doPresentWebView(final ProcessOutWebView webView) { + fail("Webview should not be required"); + } + + @Override + public void onSuccess(String invoiceId) { + fail("ThreeDS2 succeeded but should have failed."); + } + + @Override + public void onError(Exception error) { + signal.countDown(); + } + }, withActivity); + } + }); + } + }); + + try { + signal.await();// wait for callback + } catch (InterruptedException e) { + fail("Could not run test"); + } + } + + /** + * TEST MAKE CARD TOKEN + */ + + + @Test + public void testSuccessful3DS2Token() { + final CountDownLatch signal = new CountDownLatch(1); + + final Activity withActivity = activityRule.getActivity(); + final ProcessOut p = new ProcessOut(withActivity, projectId); + Card c = new Card("4000000000003253", 10, 20, "737"); + p.tokenize(c, null, new TokenCallback() { + @Override + public void onError(Exception error) { + fail("Could not tokenize the card"); + } + + @Override + public void onSuccess(final String token) { + Invoice invoice = new Invoice("test", "121.01", "EUR", new Device("android")); + JSONObject body = null; + try { + body = new JSONObject(gson.toJson(invoice)); + } catch (Exception e) { + fail("Could not encode body"); + return; + } + + Network.getTestInstance(withActivity, projectId, privateKey).CallProcessOut("/invoices", Request.Method.POST, body, new Network.NetworkResult() { + @Override + public void onError(Exception error) { + fail("Invoice creation failed"); + } + + @Override + public void onSuccess(JSONObject json) { + Invoice invoiceResult = null; + try { + invoiceResult = gson.fromJson(json.getJSONObject("invoice").toString(), Invoice.class); + } catch (JSONException e) { + fail("Unhandled exception"); + e.printStackTrace(); + return; + } + + p.makeCardPayment(invoiceResult.getId(), token, new ThreeDSHandler() { + @Override + public void doFingerprint(DirectoryServerData directoryServerData, DoFingerprintCallback callback) { + callback.continueCallback( + new ThreeDSFingerprintResponse( + "", "", new SDKEPhemPubKey("", "", "", ""), + "", "")); + } + + @Override + public void doChallenge(AuthenticationChallengeData authData, final DoChallengeCallback callback) { + callback.success(); + } + + @Override + public void doPresentWebView(final ProcessOutWebView webView) { + fail("Webview should not be required"); + } + + @Override + public void onSuccess(String invoiceId) { + signal.countDown(); + } + + @Override + public void onError(Exception error) { + signal.countDown(); +// fail("ThreeDS2 failed"); + } + }, withActivity); + } + }); + } + }); + + try { + signal.await();// wait for callback + } catch (InterruptedException e) { + fail("Could not run test"); + } + } + + @Test + public void testFailed3DS1Token() { + final CountDownLatch signal = new CountDownLatch(1); + + final Activity withActivity = activityRule.getActivity(); + final ProcessOut p = new ProcessOut(withActivity, projectId); + Card c = new Card("4000000000003246", 10, 20, "737"); + p.tokenize(c, null, new TokenCallback() { + @Override + public void onError(Exception error) { + fail("Could not tokenize the card"); + } + + @Override + public void onSuccess(final String token) { + Invoice invoice = new Invoice("test", "121.01", "EUR", new Device("android")); + JSONObject body = null; + try { + body = new JSONObject(gson.toJson(invoice)); + } catch (Exception e) { + fail("Could not encode body"); + return; + } + + Network.getTestInstance(withActivity, projectId, privateKey).CallProcessOut("/invoices", Request.Method.POST, body, new Network.NetworkResult() { + @Override + public void onError(Exception error) { + fail("Invoice creation failed"); + } + + @Override + public void onSuccess(JSONObject json) { + Invoice invoiceResult = null; + try { + invoiceResult = gson.fromJson(json.getJSONObject("invoice").toString(), Invoice.class); + } catch (JSONException e) { + fail("Unhandled exception"); + e.printStackTrace(); + return; + } + + p.makeCardPayment(invoiceResult.getId(), token, new ThreeDSHandler() { + @Override + public void doFingerprint(DirectoryServerData directoryServerData, DoFingerprintCallback callback) { + callback.continueCallback( + new ThreeDSFingerprintResponse( + "", "", new SDKEPhemPubKey("", "", "", ""), + "", "")); + } + + @Override + public void doChallenge(AuthenticationChallengeData authData, final DoChallengeCallback callback) { + callback.success(); + } + + @Override + public void doPresentWebView(final ProcessOutWebView webView) { + final FrameLayout layout = withActivity.findViewById(android.R.id.content); + final int id = View.generateViewId(); + webView.setId(id); + layout.addView(webView); + + // Wait for the page to load and simulate successful click + Handler handler = new Handler(); + Runnable r = new Runnable() { + public void run() { + // Simulate a click + webView.loadUrl("javascript:document.getElementsByTagName('a')[1].click()"); + } + }; + handler.postDelayed(r, 4000); + } + + @Override + public void onSuccess(String invoiceId) { + fail("ThreeDS2 succeeded but should have failed."); + } + + @Override + public void onError(Exception error) { + signal.countDown(); + } + }, withActivity); + } + }); + } + }); + + try { + signal.await();// wait for callback + } catch (InterruptedException e) { + fail("Could not run test"); + } + } + + @Test + public void testFailed3DS2TokenChallenge() { + final CountDownLatch signal = new CountDownLatch(1); + + final Activity withActivity = activityRule.getActivity(); + final ProcessOut p = new ProcessOut(withActivity, projectId); + Card c = new Card("4000000000003253", 10, 20, "737"); + p.tokenize(c, null, new TokenCallback() { + @Override + public void onError(Exception error) { + fail("Could not tokenize the card"); + } + + @Override + public void onSuccess(final String token) { + Invoice invoice = new Invoice("test", "121.01", "EUR", new Device("android")); + JSONObject body = null; + try { + body = new JSONObject(gson.toJson(invoice)); + } catch (Exception e) { + fail("Could not encode body"); + return; + } + + Network.getTestInstance(withActivity, projectId, privateKey).CallProcessOut("/invoices", Request.Method.POST, body, new Network.NetworkResult() { + @Override + public void onError(Exception error) { + fail("Invoice creation failed"); + } + + @Override + public void onSuccess(JSONObject json) { + Invoice invoiceResult = null; + try { + invoiceResult = gson.fromJson(json.getJSONObject("invoice").toString(), Invoice.class); + } catch (JSONException e) { + fail("Unhandled exception"); + e.printStackTrace(); + return; + } + + p.makeCardPayment(invoiceResult.getId(), token, new ThreeDSHandler() { + @Override + public void doFingerprint(DirectoryServerData directoryServerData, DoFingerprintCallback callback) { + callback.continueCallback( + new ThreeDSFingerprintResponse( + "", "", new SDKEPhemPubKey("", "", "", ""), + "", "")); + } + + @Override + public void doChallenge(AuthenticationChallengeData authData, final DoChallengeCallback callback) { + callback.error(); + } + + @Override + public void doPresentWebView(final ProcessOutWebView webView) { + fail("Webview should not be required"); + } + + @Override + public void onSuccess(String invoiceId) { + fail("ThreeDS2 succeeded but should have failed."); + } + + @Override + public void onError(Exception error) { + signal.countDown(); + } + }, withActivity); + } + }); + } + }); + + try { + signal.await();// wait for callback + } catch (InterruptedException e) { + fail("Could not run test"); + } + } +} \ No newline at end of file diff --git a/processout-sdk/src/main/AndroidManifest.xml b/processout-sdk/src/main/AndroidManifest.xml index 5cb8555f..a2b1e510 100644 --- a/processout-sdk/src/main/AndroidManifest.xml +++ b/processout-sdk/src/main/AndroidManifest.xml @@ -1,4 +1,11 @@ + - - + package="com.processout.processout_sdk"> + + + + + + + + \ No newline at end of file diff --git a/processout-sdk/src/main/java/com/processout/processout_sdk/TestActivity.java b/processout-sdk/src/main/java/com/processout/processout_sdk/TestActivity.java new file mode 100644 index 00000000..2d00c429 --- /dev/null +++ b/processout-sdk/src/main/java/com/processout/processout_sdk/TestActivity.java @@ -0,0 +1,14 @@ +package com.processout.processout_sdk; + +import android.app.Activity; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; + +public class TestActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_test); + } +} diff --git a/processout-sdk/src/main/res/layout/activity_test.xml b/processout-sdk/src/main/res/layout/activity_test.xml new file mode 100644 index 00000000..92cfe9ec --- /dev/null +++ b/processout-sdk/src/main/res/layout/activity_test.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file From e850963beff556cb321ca74995ed8b64a18b7649 Mon Sep 17 00:00:00 2001 From: Jeremy Lejoux Date: Fri, 25 Oct 2019 11:35:37 +0200 Subject: [PATCH 2/2] tests: fix tests --- .../com/processout/processout_sdk/UITestSuite.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/processout-sdk/src/androidTest/java/com/processout/processout_sdk/UITestSuite.java b/processout-sdk/src/androidTest/java/com/processout/processout_sdk/UITestSuite.java index 0cd6d9f7..7da335af 100644 --- a/processout-sdk/src/androidTest/java/com/processout/processout_sdk/UITestSuite.java +++ b/processout-sdk/src/androidTest/java/com/processout/processout_sdk/UITestSuite.java @@ -114,7 +114,7 @@ public void run() { webView.loadUrl("javascript:document.getElementsByTagName('a')[0].click()"); } }; - handler.postDelayed(r, 4000); + handler.postDelayed(r, 10000); } @Override @@ -124,8 +124,7 @@ public void onSuccess(String invoiceId) { @Override public void onError(Exception error) { - signal.countDown(); -// fail("ThreeDS2 failed"); + fail("ThreeDS2 failed"); } }, withActivity); } @@ -379,7 +378,7 @@ public void doPresentWebView(final ProcessOutWebView webView) { @Override public void onSuccess(String invoiceId) { - fail("ThreeDS2 succeeded but should have failed."); + fail("ThreeDS2 should have failed."); } @Override @@ -471,8 +470,7 @@ public void onSuccess(String invoiceId) { @Override public void onError(Exception error) { - signal.countDown(); -// fail("ThreeDS2 failed"); + fail("ThreeDS2 failed"); } }, withActivity); }