From 99684784993a46d4ca467c1a9c2cfa8ddd5d8dee Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 21 Mar 2024 13:51:50 -0300 Subject: [PATCH 01/46] Adding manager for custom tabs --- trustly-android-sdk/.DS_Store | Bin 8196 -> 8196 bytes trustly-android-sdk/.idea/gradle.xml | 1 + trustly-android-sdk/.idea/misc.xml | 2 +- .../.idea/sonarlint/issuestore/index.pb | 4 ++- .../sonarlint/securityhotspotstore/index.pb | 4 ++- .../android/sdk/util/CustomTabsManager.java | 23 ++++++++++++++++++ .../android/sdk/views/TrustlyOAuthView.java | 10 ++------ .../android/sdk/views/TrustlyView.java | 10 +++----- 8 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/CustomTabsManager.java diff --git a/trustly-android-sdk/.DS_Store b/trustly-android-sdk/.DS_Store index 7fa77fbce031536b52a99540acf46a9d52b79fef..816eea50b9c67c212b8e3de7eaa1c15e1da498c1 100644 GIT binary patch delta 75 zcmZp1XmQwZTYz!rWL=>`4aw?iV*?8v1w#`PvsxX6YD*&n9R(9(v)Wot4pC)&>!A4T foZP(p?#ZV`iBMWi> diff --git a/trustly-android-sdk/.idea/gradle.xml b/trustly-android-sdk/.idea/gradle.xml index 54ea192..7c75940 100644 --- a/trustly-android-sdk/.idea/gradle.xml +++ b/trustly-android-sdk/.idea/gradle.xml @@ -11,6 +11,7 @@ + diff --git a/trustly-android-sdk/.idea/misc.xml b/trustly-android-sdk/.idea/misc.xml index 41b1618..0ad17cb 100644 --- a/trustly-android-sdk/.idea/misc.xml +++ b/trustly-android-sdk/.idea/misc.xml @@ -1,7 +1,7 @@ - + diff --git a/trustly-android-sdk/.idea/sonarlint/issuestore/index.pb b/trustly-android-sdk/.idea/sonarlint/issuestore/index.pb index 63b08d1..b6c5084 100644 --- a/trustly-android-sdk/.idea/sonarlint/issuestore/index.pb +++ b/trustly-android-sdk/.idea/sonarlint/issuestore/index.pb @@ -57,4 +57,6 @@ O h 8src/main/java/net/trustly/android/sdk/util/UrlUtils.java,6/d/6d987e9bec5437ae839af8d5803a20c2ab2600c3 m -=src/main/java/net/trustly/android/sdk/views/TrustlyPanel.java,c/b/cbbfc9ea3915126206ecc260408e3e8c90e772d5 \ No newline at end of file +=src/main/java/net/trustly/android/sdk/views/TrustlyPanel.java,c/b/cbbfc9ea3915126206ecc260408e3e8c90e772d5 +q +Asrc/main/java/net/trustly/android/sdk/util/CustomTabsManager.java,2/e/2ec856d759c135a552ef3d4a2a878c99745fe87f \ No newline at end of file diff --git a/trustly-android-sdk/.idea/sonarlint/securityhotspotstore/index.pb b/trustly-android-sdk/.idea/sonarlint/securityhotspotstore/index.pb index 63b08d1..b6c5084 100644 --- a/trustly-android-sdk/.idea/sonarlint/securityhotspotstore/index.pb +++ b/trustly-android-sdk/.idea/sonarlint/securityhotspotstore/index.pb @@ -57,4 +57,6 @@ O h 8src/main/java/net/trustly/android/sdk/util/UrlUtils.java,6/d/6d987e9bec5437ae839af8d5803a20c2ab2600c3 m -=src/main/java/net/trustly/android/sdk/views/TrustlyPanel.java,c/b/cbbfc9ea3915126206ecc260408e3e8c90e772d5 \ No newline at end of file +=src/main/java/net/trustly/android/sdk/views/TrustlyPanel.java,c/b/cbbfc9ea3915126206ecc260408e3e8c90e772d5 +q +Asrc/main/java/net/trustly/android/sdk/util/CustomTabsManager.java,2/e/2ec856d759c135a552ef3d4a2a878c99745fe87f \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/CustomTabsManager.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/CustomTabsManager.java new file mode 100644 index 0000000..daf6a66 --- /dev/null +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/CustomTabsManager.java @@ -0,0 +1,23 @@ +package net.trustly.android.sdk.util; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; + +import androidx.browser.customtabs.CustomTabsIntent; + +public class CustomTabsManager { + + private CustomTabsManager() { + throw new IllegalStateException("Utility class cannot be instantiated"); + } + + public static void openCustomTabs(Context context, String url) { + CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); + CustomTabsIntent customTabsIntent = builder.build(); + customTabsIntent.intent.setPackage("com.android.chrome"); + customTabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + customTabsIntent.launchUrl(context, Uri.parse(url)); + } + +} \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyOAuthView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyOAuthView.java index 182f310..f292844 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyOAuthView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyOAuthView.java @@ -2,8 +2,6 @@ import android.annotation.SuppressLint; import android.content.Context; -import android.content.Intent; -import android.net.Uri; import android.util.AttributeSet; import android.view.ViewGroup; import android.webkit.WebResourceRequest; @@ -13,7 +11,7 @@ import android.widget.LinearLayout; import android.widget.RelativeLayout; -import androidx.browser.customtabs.CustomTabsIntent; +import net.trustly.android.sdk.util.CustomTabsManager; public class TrustlyOAuthView extends LinearLayout { @@ -44,11 +42,7 @@ public TrustlyOAuthView(final Context context, AttributeSet attrs, int defStyleA public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { String url = request.getUrl().toString(); if (TrustlyView.isLocalEnvironment() || ((url.contains("paywithmybank.com") || url.contains("trustly.one")) && url.contains("/oauth/login/"))) { - CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); - CustomTabsIntent customTabsIntent = builder.build(); - customTabsIntent.intent.setPackage("com.android.chrome"); - customTabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - customTabsIntent.launchUrl(view.getContext(), Uri.parse(url)); + CustomTabsManager.openCustomTabs(view.getContext(), url); } return true; } diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index ba29d42..d9e33b6 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -4,7 +4,6 @@ import android.content.Context; import android.content.SharedPreferences; import android.graphics.Color; -import android.net.Uri; import android.os.Message; import android.util.AttributeSet; import android.view.ViewGroup; @@ -16,14 +15,13 @@ import android.widget.LinearLayout; import android.widget.RelativeLayout; -import androidx.browser.customtabs.CustomTabsIntent; - import net.trustly.android.sdk.BuildConfig; import net.trustly.android.sdk.TrustlyJsInterface; -import net.trustly.android.sdk.util.CidManager; import net.trustly.android.sdk.interfaces.Trustly; import net.trustly.android.sdk.interfaces.TrustlyCallback; import net.trustly.android.sdk.interfaces.TrustlyListener; +import net.trustly.android.sdk.util.CidManager; +import net.trustly.android.sdk.util.CustomTabsManager; import net.trustly.android.sdk.util.UrlUtils; import java.util.HashMap; @@ -190,9 +188,7 @@ public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGest params.put("url", url); self.onExternalUrl.handle(self, params); } else { - CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); - CustomTabsIntent customTabsIntent = builder.build(); - customTabsIntent.launchUrl(view.getContext(), Uri.parse(url)); + CustomTabsManager.openCustomTabs(view.getContext(), url); } return false; } From 6e9de7dcfc12835afda7ebe102e498ca0089cc09 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 21 Mar 2024 14:30:53 -0300 Subject: [PATCH 02/46] Getting json and encode it --- trustly-android-sdk/build.gradle | 4 ++-- .../java/net/trustly/android/sdk/util/UrlUtils.java | 13 +++++++++++++ .../net/trustly/android/sdk/views/TrustlyView.java | 5 ++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/trustly-android-sdk/build.gradle b/trustly-android-sdk/build.gradle index 23a6631..16eee28 100644 --- a/trustly-android-sdk/build.gradle +++ b/trustly-android-sdk/build.gradle @@ -38,8 +38,8 @@ android { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation 'androidx.browser:browser:1.5.0' - implementation 'androidx.security:security-crypto:1.1.0-alpha06' + implementation 'androidx.browser:browser:1.8.0' + implementation 'com.google.code.gson:gson:2.10.1' testImplementation 'junit:junit:4.13.2' testImplementation 'org.powermock:powermock-api-mockito:1.4.12' diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java index 8af65fb..8c89ae3 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java @@ -1,8 +1,12 @@ package net.trustly.android.sdk.util; import android.net.Uri; +import android.util.Base64; + +import com.google.gson.Gson; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashSet; @@ -72,4 +76,13 @@ private static String urlEncode(String str) { } } + public static String getJsonFromParameters(Map parameters) { + return new Gson().toJson(parameters); + } + + public static String encodeStringToBase64(String value) { + byte[] encode = Base64.encode(value.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT); + return new String(encode, StandardCharsets.UTF_8); + } + } diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index d9e33b6..a5e259d 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -336,7 +336,10 @@ public Trustly establish(Map establishData) { isLocalEnvironment = true; } - webView.postUrl(url, UrlUtils.getParameterString(data).getBytes("UTF-8")); + String jsonParameters = UrlUtils.getJsonFromParameters(data); + String encodedParameters = UrlUtils.encodeStringToBase64(jsonParameters); + + CustomTabsManager.openCustomTabs(getContext(), url + "&token=" + encodedParameters); } catch (Exception e) { } return this; From 5cd53a4f1460315166d16068bcb66aa50f152ea3 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 21 Mar 2024 16:28:25 -0300 Subject: [PATCH 03/46] Adding parameters in to url and putting new method in trustly interface --- .../android/sdk/interfaces/Trustly.java | 9 +++ .../android/sdk/views/TrustlyView.java | 59 ++++++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/interfaces/Trustly.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/interfaces/Trustly.java index 2598f79..4a389f2 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/interfaces/Trustly.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/interfaces/Trustly.java @@ -53,6 +53,15 @@ public static TrustlyView create(Context context) { */ Trustly establish(Map establishData); + /** + * Establishes a new transaction. Shows the Trustly bank authentication on the ChromeCustomTabs + * + * @param establishData The map containing the establish data. Similar to the establishData object on the + * JavaScript API. + * @return this + */ + Trustly establishCustomTabs(Map establishData); + /** * Opens a hybrid application page * diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index a5e259d..a5d1fe6 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -297,6 +297,60 @@ public Trustly establish(Map establishData) { data = new HashMap<>(establishData); String url = getEndpointUrl("index", establishData); + try { + String deviceType = establishData.get("deviceType"); + + if (deviceType != null) { + deviceType = deviceType + ":android:native"; + } else { + deviceType = "mobile:android:native"; + } + + String lang = establishData.get("metadata.lang"); + if (lang != null) data.put("lang", lang); + + String integrationContext = establishData.get("metadata.integrationContext"); + if (integrationContext == null || integrationContext.isEmpty()) { + data.put("metadata.integrationContext", "InAppBrowser"); + } + data.put("metadata.sdkAndroidVersion", version); + data.put("deviceType", deviceType); + data.put("returnUrl", returnURL); + data.put("cancelUrl", cancelURL); + data.put("grp", Integer.toString(grp)); + + if (data.containsKey("paymentProviderId")) { + data.put("widgetLoaded", "true"); + } + + Map sessionCidValues = new CidManager().getOrCreateSessionCid(getContext()); + if (sessionCidValues != null) { + data.put("sessionCid", sessionCidValues.get(CidManager.SESSION_CID_PARAM)); + data.put("metadata.cid", sessionCidValues.get(CidManager.CID_PARAM)); + } + + notifyOpen(); + + if ("local".equals(data.get("env"))) { + webView.setWebContentsDebuggingEnabled(true); + isLocalEnvironment = true; + } + + webView.postUrl(url, UrlUtils.getParameterString(data).getBytes("UTF-8")); + } catch (Exception e) { + } + return this; + } + + /** + * {@inheritDoc} + */ + public Trustly establishCustomTabs(Map establishData) { + status = Status.PANEL_LOADING; + + data = new HashMap<>(establishData); + String url = getEndpointUrl("dynamic", establishData); + try { String deviceType = establishData.get("deviceType"); @@ -339,7 +393,7 @@ public Trustly establish(Map establishData) { String jsonParameters = UrlUtils.getJsonFromParameters(data); String encodedParameters = UrlUtils.encodeStringToBase64(jsonParameters); - CustomTabsManager.openCustomTabs(getContext(), url + "&token=" + encodedParameters); + CustomTabsManager.openCustomTabs(getContext(), url + "accessId=" + establishData.get("accessId") + "&token=" + encodedParameters); } catch (Exception e) { } return this; @@ -512,6 +566,9 @@ public Trustly notifyListener(String eventName, HashMap eventDet * {@inheritDoc} */ protected String getEndpointUrl(String function, Map establishData) { + if ("dynamic".equals(function)) { + return PROTOCOL + establishData.get("localUrl") + "/start/app/establish?"; + } String subDomain = establishData.get("env") != null ? establishData.get("env").toLowerCase() From 09c91eebff43167f8546d571cb91f610aec8b90a Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 23 May 2024 16:24:49 -0300 Subject: [PATCH 04/46] Formatting json with correct objects --- .../.idea/sonarlint/issuestore/index.pb | 4 ++- .../sonarlint/securityhotspotstore/index.pb | 4 ++- .../trustly/android/sdk/util/UrlUtils.java | 35 ++++++++++++++++++- .../android/sdk/views/TrustlyView.java | 1 + 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/trustly-android-sdk/.idea/sonarlint/issuestore/index.pb b/trustly-android-sdk/.idea/sonarlint/issuestore/index.pb index 1a8ca9f..252f4f0 100644 --- a/trustly-android-sdk/.idea/sonarlint/issuestore/index.pb +++ b/trustly-android-sdk/.idea/sonarlint/issuestore/index.pb @@ -12,4 +12,6 @@ Asrc/main/java/net/trustly/android/sdk/views/TrustlyOAuthView.java,7/a/7a58f7dc m =src/main/java/net/trustly/android/sdk/TrustlyJsInterface.java,2/b/2bd4abfbeee654aeab55c22942e5d3fdbce42249 L -src/main/AndroidManifest.xml,0/6/066a3db98a4a279fde40d6ddf92c417b5c93198b \ No newline at end of file +src/main/AndroidManifest.xml,0/6/066a3db98a4a279fde40d6ddf92c417b5c93198b +h +8src/main/java/net/trustly/android/sdk/util/UrlUtils.java,6/d/6d987e9bec5437ae839af8d5803a20c2ab2600c3 \ No newline at end of file diff --git a/trustly-android-sdk/.idea/sonarlint/securityhotspotstore/index.pb b/trustly-android-sdk/.idea/sonarlint/securityhotspotstore/index.pb index 1a8ca9f..252f4f0 100644 --- a/trustly-android-sdk/.idea/sonarlint/securityhotspotstore/index.pb +++ b/trustly-android-sdk/.idea/sonarlint/securityhotspotstore/index.pb @@ -12,4 +12,6 @@ Asrc/main/java/net/trustly/android/sdk/views/TrustlyOAuthView.java,7/a/7a58f7dc m =src/main/java/net/trustly/android/sdk/TrustlyJsInterface.java,2/b/2bd4abfbeee654aeab55c22942e5d3fdbce42249 L -src/main/AndroidManifest.xml,0/6/066a3db98a4a279fde40d6ddf92c417b5c93198b \ No newline at end of file +src/main/AndroidManifest.xml,0/6/066a3db98a4a279fde40d6ddf92c417b5c93198b +h +8src/main/java/net/trustly/android/sdk/util/UrlUtils.java,6/d/6d987e9bec5437ae839af8d5803a20c2ab2600c3 \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java index f5d8a50..5b6655e 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java @@ -5,6 +5,9 @@ import com.google.gson.Gson; +import org.json.JSONException; +import org.json.JSONObject; + import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Collections; @@ -81,7 +84,37 @@ private static String urlEncode(String str) { } public static String getJsonFromParameters(Map parameters) { - return new Gson().toJson(parameters); + try { + JSONObject jsonObject = build(parameters); + return jsonObject.toString().replace("\"nameValuePairs\":{", "") + .replace(" }\n},", "}") + .replace("\\/", "/"); + } catch (JSONException e) { + return new Gson().toJson(parameters); + } + } + + public static JSONObject build(Map data) throws JSONException { + JSONObject json = new JSONObject(); + for (Map.Entry e : data.entrySet()) { + String[] keys = e.getKey().split("\\."); + JSONObject current = json; + for (int i = 0; i < keys.length; ++i) { + String key = keys[i]; + try { + current = current.getJSONObject(key); + } catch (JSONException ex) { + if (i == keys.length - 1) { + current.put(key, e.getValue()); + } else { + JSONObject tmp = new JSONObject(); + current.put(key, tmp); + current = tmp; + } + } + } + } + return json; } public static String encodeStringToBase64(String value) { diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 2bb0268..7ade2ae 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -357,6 +357,7 @@ public Trustly establish(Map establishData) { */ public Trustly establishCustomTabs(Map establishData) { status = Status.PANEL_LOADING; + CidManager.generateCid(getContext()); data = new HashMap<>(establishData); String url = getEndpointUrl("dynamic", establishData); From 2e86f0973c6b3ab5757db5fc9bd61e194ba4bb02 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Mon, 27 May 2024 14:22:35 -0300 Subject: [PATCH 05/46] Changing method name --- .../src/main/java/net/trustly/android/sdk/util/UrlUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java index 5b6655e..5ec4ba5 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java @@ -85,7 +85,7 @@ private static String urlEncode(String str) { public static String getJsonFromParameters(Map parameters) { try { - JSONObject jsonObject = build(parameters); + JSONObject jsonObject = buildJsonObject(parameters); return jsonObject.toString().replace("\"nameValuePairs\":{", "") .replace(" }\n},", "}") .replace("\\/", "/"); @@ -94,7 +94,7 @@ public static String getJsonFromParameters(Map parameters) { } } - public static JSONObject build(Map data) throws JSONException { + public static JSONObject buildJsonObject(Map data) throws JSONException { JSONObject json = new JSONObject(); for (Map.Entry e : data.entrySet()) { String[] keys = e.getKey().split("\\."); From 76d003fe4c9afa8aa06ff5412eda191da1959e45 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Wed, 5 Jun 2024 16:26:09 -0300 Subject: [PATCH 06/46] Some adjustments --- trustly-android-sdk/.idea/sonarlint/issuestore/index.pb | 6 +++++- .../.idea/sonarlint/securityhotspotstore/index.pb | 6 +++++- .../java/net/trustly/android/sdk/views/TrustlyView.java | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/trustly-android-sdk/.idea/sonarlint/issuestore/index.pb b/trustly-android-sdk/.idea/sonarlint/issuestore/index.pb index 252f4f0..3ac8888 100644 --- a/trustly-android-sdk/.idea/sonarlint/issuestore/index.pb +++ b/trustly-android-sdk/.idea/sonarlint/issuestore/index.pb @@ -14,4 +14,8 @@ m L src/main/AndroidManifest.xml,0/6/066a3db98a4a279fde40d6ddf92c417b5c93198b h -8src/main/java/net/trustly/android/sdk/util/UrlUtils.java,6/d/6d987e9bec5437ae839af8d5803a20c2ab2600c3 \ No newline at end of file +8src/main/java/net/trustly/android/sdk/util/UrlUtils.java,6/d/6d987e9bec5437ae839af8d5803a20c2ab2600c3 +m +=src/main/java/net/trustly/android/sdk/interfaces/Trustly.java,7/7/77461962160d9cc83e42b7cf7549c5942bdc69fc +u +Esrc/main/java/net/trustly/android/sdk/interfaces/TrustlyCallback.java,e/6/e64e679f47e1996288e19baba939f22a40ef0f7d \ No newline at end of file diff --git a/trustly-android-sdk/.idea/sonarlint/securityhotspotstore/index.pb b/trustly-android-sdk/.idea/sonarlint/securityhotspotstore/index.pb index 252f4f0..3ac8888 100644 --- a/trustly-android-sdk/.idea/sonarlint/securityhotspotstore/index.pb +++ b/trustly-android-sdk/.idea/sonarlint/securityhotspotstore/index.pb @@ -14,4 +14,8 @@ m L src/main/AndroidManifest.xml,0/6/066a3db98a4a279fde40d6ddf92c417b5c93198b h -8src/main/java/net/trustly/android/sdk/util/UrlUtils.java,6/d/6d987e9bec5437ae839af8d5803a20c2ab2600c3 \ No newline at end of file +8src/main/java/net/trustly/android/sdk/util/UrlUtils.java,6/d/6d987e9bec5437ae839af8d5803a20c2ab2600c3 +m +=src/main/java/net/trustly/android/sdk/interfaces/Trustly.java,7/7/77461962160d9cc83e42b7cf7549c5942bdc69fc +u +Esrc/main/java/net/trustly/android/sdk/interfaces/TrustlyCallback.java,e/6/e64e679f47e1996288e19baba939f22a40ef0f7d \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 7ade2ae..368ed6f 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -572,7 +572,7 @@ public void notifyListener(String eventName, HashMap eventDetail */ protected String getEndpointUrl(String function, Map establishData) { if ("dynamic".equals(function)) { - return PROTOCOL + establishData.get("localUrl") + "/start/app/establish?"; + return "http://" + establishData.get("localUrl") + "/start/app/establish?"; } String subDomain = establishData.get("env") != null From 78b5ec5fdf73f2c7205e1e775474f70784722e90 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 1 Aug 2024 16:25:44 -0300 Subject: [PATCH 07/46] Adding data model --- trustly-android-sdk/.idea/gradle.xml | 2 +- trustly-android-sdk/.idea/misc.xml | 2 +- .../java/net/trustly/android/sdk/data/Setting.java | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java diff --git a/trustly-android-sdk/.idea/gradle.xml b/trustly-android-sdk/.idea/gradle.xml index 7c75940..aeefcea 100644 --- a/trustly-android-sdk/.idea/gradle.xml +++ b/trustly-android-sdk/.idea/gradle.xml @@ -5,7 +5,7 @@ - + diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java new file mode 100644 index 0000000..eca8a38 --- /dev/null +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java @@ -0,0 +1,13 @@ +package net.trustly.android.sdk.data; + +public class Setting { + + public LightBoxSetting lightBox; + + class LightBoxSetting { + + public String context; + + } + +} \ No newline at end of file From aa00e500e3af5184878959c9ceff5032a0c73777 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Mon, 5 Aug 2024 16:23:38 -0300 Subject: [PATCH 08/46] Adding method to API --- .../main/java/net/trustly/android/sdk/data/TrustlyAPI.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/TrustlyAPI.java diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/TrustlyAPI.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/TrustlyAPI.java new file mode 100644 index 0000000..6e94c0a --- /dev/null +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/TrustlyAPI.java @@ -0,0 +1,7 @@ +package net.trustly.android.sdk.data; + +public interface TrustlyAPI { + + public Setting getSetting(); + +} From 03974f377404cf3c7a9d29c3476514a876ff353b Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 6 Aug 2024 14:36:26 -0300 Subject: [PATCH 09/46] Class to call the API --- trustly-android-sdk/build.gradle | 10 +++--- .../trustly/android/sdk/util/APIRequests.java | 34 +++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/APIRequests.java diff --git a/trustly-android-sdk/build.gradle b/trustly-android-sdk/build.gradle index f62b29f..92a54c8 100644 --- a/trustly-android-sdk/build.gradle +++ b/trustly-android-sdk/build.gradle @@ -47,11 +47,11 @@ dependencies { testImplementation 'org.powermock:powermock-api-mockito:1.4.12' testImplementation 'org.powermock:powermock-module-junit4:2.0.5' - androidTestImplementation 'androidx.test:core:1.5.0' - androidTestImplementation 'androidx.test:runner:1.5.2' - androidTestImplementation 'androidx.test:rules:1.5.0' - androidTestImplementation 'androidx.test.ext:junit:1.1.5' - androidTestImplementation 'androidx.test.ext:truth:1.5.0' + androidTestImplementation 'androidx.test:core:1.6.1' + androidTestImplementation 'androidx.test:runner:1.6.1' + androidTestImplementation 'androidx.test:rules:1.6.1' + androidTestImplementation 'androidx.test.ext:junit:1.2.1' + androidTestImplementation 'androidx.test.ext:truth:1.6.0' androidTestImplementation 'com.google.truth:truth:1.1.3' } diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/APIRequests.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/APIRequests.java new file mode 100644 index 0000000..59c0b04 --- /dev/null +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/APIRequests.java @@ -0,0 +1,34 @@ +package net.trustly.android.sdk.util; + +import android.os.AsyncTask; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +public abstract class APIRequests extends AsyncTask { + + @Override + protected String doInBackground(String... urls) { + try { + URL url = new URL(urls[0]); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setDoOutput(true); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.connect(); + BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream())); + StringBuilder content = new StringBuilder(); + String line; + while ((line = rd.readLine()) != null) { + content.append(line).append("\n"); + } + return content.toString(); + } catch (Exception e) { + return null; + } + } + +} From 2a60817cbcb7db2125062402dfcec8bbfd056878 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 6 Aug 2024 15:12:45 -0300 Subject: [PATCH 10/46] Calling API method --- .../sdk/{util => data}/APIRequests.java | 22 +++++++++++++++---- .../android/sdk/views/TrustlyView.java | 10 +++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) rename trustly-android-sdk/src/main/java/net/trustly/android/sdk/{util => data}/APIRequests.java (65%) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/APIRequests.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.java similarity index 65% rename from trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/APIRequests.java rename to trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.java index 59c0b04..fbb208b 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/APIRequests.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.java @@ -1,4 +1,4 @@ -package net.trustly.android.sdk.util; +package net.trustly.android.sdk.data; import android.os.AsyncTask; @@ -7,7 +7,17 @@ import java.net.HttpURLConnection; import java.net.URL; -public abstract class APIRequests extends AsyncTask { +public class APIRequests extends AsyncTask { + + private final APIAsyncResponse delegate; + + public interface APIAsyncResponse { + void processFinish(String output); + } + + public APIRequests(APIAsyncResponse delegate) { + this.delegate = delegate; + } @Override protected String doInBackground(String... urls) { @@ -15,7 +25,6 @@ protected String doInBackground(String... urls) { URL url = new URL(urls[0]); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); - connection.setDoOutput(true); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); connection.connect(); @@ -27,8 +36,13 @@ protected String doInBackground(String... urls) { } return content.toString(); } catch (Exception e) { - return null; + return e.getMessage(); } } + @Override + protected void onPostExecute(String result) { + delegate.processFinish(result); + } + } diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 2da674c..af70edc 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -15,6 +15,7 @@ import android.webkit.WebViewClient; import android.widget.LinearLayout; import android.widget.RelativeLayout; +import android.widget.Toast; import androidx.annotation.RequiresApi; @@ -23,6 +24,7 @@ import net.trustly.android.sdk.interfaces.Trustly; import net.trustly.android.sdk.interfaces.TrustlyCallback; import net.trustly.android.sdk.interfaces.TrustlyListener; +import net.trustly.android.sdk.data.APIRequests; import net.trustly.android.sdk.util.CidManager; import net.trustly.android.sdk.util.CustomTabsManager; import net.trustly.android.sdk.util.UrlUtils; @@ -305,7 +307,11 @@ public Trustly establish(Map establishData) { CidManager.generateCid(getContext()); data = new HashMap<>(establishData); - String url = getEndpointUrl("index", establishData); + + new APIRequests(output -> { + data.put("CHOOSE", output); + Toast.makeText(getContext(), output, Toast.LENGTH_LONG).show(); + }).execute("https://dogapi.dog/api/v2/breeds"); try { String deviceType = establishData.get("deviceType"); @@ -346,7 +352,7 @@ public Trustly establish(Map establishData) { isLocalEnvironment = true; } - webView.postUrl(url, UrlUtils.getParameterString(data).getBytes("UTF-8")); + webView.postUrl(getEndpointUrl("index", establishData), UrlUtils.getParameterString(data).getBytes("UTF-8")); } catch (Exception e) { } return this; From 93947fc8f3230e7eb59a3042f2217e5253b09b77 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 6 Aug 2024 15:37:08 -0300 Subject: [PATCH 11/46] Show webview or cct by api parameter --- trustly-android-sdk/build.gradle | 1 + .../net/trustly/android/sdk/data/Setting.java | 9 +++- .../android/sdk/views/TrustlyView.java | 47 +++++++------------ 3 files changed, 25 insertions(+), 32 deletions(-) diff --git a/trustly-android-sdk/build.gradle b/trustly-android-sdk/build.gradle index 92a54c8..50cfb74 100644 --- a/trustly-android-sdk/build.gradle +++ b/trustly-android-sdk/build.gradle @@ -42,6 +42,7 @@ android { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'androidx.browser:browser:1.8.0' + implementation 'com.google.code.gson:gson:2.11.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.powermock:powermock-api-mockito:1.4.12' diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java index eca8a38..f633be7 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java @@ -4,10 +4,17 @@ public class Setting { public LightBoxSetting lightBox; - class LightBoxSetting { + public LightBoxSetting getLightBox() { + return lightBox; + } + + public class LightBoxSetting { public String context; + public String getContext() { + return context; + } } } \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index af70edc..12791eb 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -19,12 +19,15 @@ import androidx.annotation.RequiresApi; +import com.google.gson.Gson; + import net.trustly.android.sdk.BuildConfig; import net.trustly.android.sdk.TrustlyJsInterface; +import net.trustly.android.sdk.data.APIRequests; +import net.trustly.android.sdk.data.Setting; import net.trustly.android.sdk.interfaces.Trustly; import net.trustly.android.sdk.interfaces.TrustlyCallback; import net.trustly.android.sdk.interfaces.TrustlyListener; -import net.trustly.android.sdk.data.APIRequests; import net.trustly.android.sdk.util.CidManager; import net.trustly.android.sdk.util.CustomTabsManager; import net.trustly.android.sdk.util.UrlUtils; @@ -308,11 +311,6 @@ public Trustly establish(Map establishData) { data = new HashMap<>(establishData); - new APIRequests(output -> { - data.put("CHOOSE", output); - Toast.makeText(getContext(), output, Toast.LENGTH_LONG).show(); - }).execute("https://dogapi.dog/api/v2/breeds"); - try { String deviceType = establishData.get("deviceType"); @@ -352,36 +350,23 @@ public Trustly establish(Map establishData) { isLocalEnvironment = true; } - webView.postUrl(getEndpointUrl("index", establishData), UrlUtils.getParameterString(data).getBytes("UTF-8")); + byte[] parameters = UrlUtils.getParameterString(data).getBytes("UTF-8"); + + new APIRequests(output -> { + Setting setting = new Gson().fromJson(output, Setting.class); + Setting.LightBoxSetting lightBox = setting.getLightBox(); + if (lightBox.getContext().equals("web_view")) { + webView.postUrl(getEndpointUrl("index", establishData), parameters); + } else { + //TODO Open the Custom Tabs here + Toast.makeText(getContext(), output, Toast.LENGTH_LONG).show(); + } + }).execute("TRUSTLY_CHOOSE_API_URL"); } catch (Exception e) { } return this; } - public String getInAppBrowserLaunchURL(Map establishData) { - Map data = new HashMap<>(establishData); - String deviceType = establishData.get("deviceType"); - - if (deviceType != null) { - deviceType = deviceType + ":android:iab"; - } else { - deviceType = "mobile:android:iab"; - } - - String lang = establishData.get("metadata.lang"); - if (lang != null) data.put("lang", lang); - - data.put("metadata.sdkAndroidVersion", version); - data.put("deviceType", deviceType); - data.put("grp", Integer.toString(grp)); - - if (data.containsKey("paymentProviderId")) { - data.put("widgetLoaded", "true"); - } - - return UrlUtils.getParameterString(data); - } - /** * {@inheritDoc} */ From 217870f54ad206f80962f3c9fbd7b3de96306676 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Wed, 7 Aug 2024 14:18:58 -0300 Subject: [PATCH 12/46] Removing unused file --- .../main/java/net/trustly/android/sdk/data/TrustlyAPI.java | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/TrustlyAPI.java diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/TrustlyAPI.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/TrustlyAPI.java deleted file mode 100644 index 6e94c0a..0000000 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/TrustlyAPI.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.trustly.android.sdk.data; - -public interface TrustlyAPI { - - public Setting getSetting(); - -} From 87d53282c645991a374839ed10053e74d5b69b34 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Fri, 9 Aug 2024 16:40:23 -0300 Subject: [PATCH 13/46] Parsing return value to show the correct component --- .../net/trustly/android/sdk/data/Setting.java | 40 ++++++++++++++++--- .../android/sdk/views/TrustlyView.java | 20 ++++++---- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java index f633be7..e986f0e 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java @@ -1,20 +1,48 @@ package net.trustly.android.sdk.data; +import com.google.gson.annotations.SerializedName; + public class Setting { - public LightBoxSetting lightBox; + @SerializedName("settings") + public LightBoxSetting setting; + + public LightBoxSetting getSetting() { + return setting; + } - public LightBoxSetting getLightBox() { - return lightBox; + public void setSetting(LightBoxSetting setting) { + this.setting = setting; } public class LightBoxSetting { - public String context; + @SerializedName("lightbox") + public LightBoxContext lightbox; + + public LightBoxContext getLightbox() { + return lightbox; + } + + public void setLightbox(LightBoxContext lightbox) { + this.lightbox = lightbox; + } + + public class LightBoxContext { + + @SerializedName("context") + public String context; + + public String getContext() { + return context; + } + + public void setContext(String context) { + this.context = context; + } - public String getContext() { - return context; } + } } \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 07de83c..f3cf3a3 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -352,17 +352,23 @@ public Trustly establish(Map establishData) { byte[] parameters = UrlUtils.getParameterString(data).getBytes("UTF-8"); new APIRequests(output -> { - String url = getEndpointUrl("index", establishData); + // TODO Remove this hardcoded JSON + output = "{'settings': {'lightbox': {'context': 'in-app-browser'}}}"; Setting setting = new Gson().fromJson(output, Setting.class); - Setting.LightBoxSetting lightBox = setting.getLightBox(); - if (lightBox.getContext().equals("web_view")) { - webView.postUrl(url, parameters); - } else { + Setting.LightBoxSetting lightBox = setting.getSetting(); + Setting.LightBoxSetting.LightBoxContext lightbox = lightBox.getLightbox(); + if (lightbox.getContext().equals("in-app-browser")) { String jsonParameters = UrlUtils.getJsonFromParameters(data); String encodedParameters = UrlUtils.encodeStringToBase64(jsonParameters); - CustomTabsManager.openCustomTabsIntent(getContext(), url + "accessId=" + establishData.get("accessId") + "&token=" + encodedParameters); + CustomTabsManager.openCustomTabsIntent(getContext(), + getEndpointUrl("dynamic", establishData) + "accessId=" + + establishData.get("accessId") + "&token=" + encodedParameters + ); + } else { + webView.postUrl(getEndpointUrl("index", establishData), parameters); } - }).execute("TRUSTLY_CHOOSE_API_URL"); + // TODO Change this endpoint with the right one + }).execute("https://dogapi.dog/api/v2/breeds"); } catch (Exception e) { } return this; From 04fab25cfa891e4cac1efa3f20215ea830ab0cda Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Fri, 9 Aug 2024 17:18:34 -0300 Subject: [PATCH 14/46] Refactoring to Kotlin --- trustly-android-sdk/build.gradle | 5 ++ .../trustly/android/sdk/data/APIRequests.java | 48 ------------------- .../trustly/android/sdk/data/APIRequests.kt | 46 ++++++++++++++++++ .../net/trustly/android/sdk/data/Setting.java | 48 ------------------- .../net/trustly/android/sdk/data/Settings.kt | 13 +++++ .../android/sdk/views/TrustlyView.java | 8 ++-- 6 files changed, 67 insertions(+), 101 deletions(-) delete mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.java create mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.kt delete mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java create mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Settings.kt diff --git a/trustly-android-sdk/build.gradle b/trustly-android-sdk/build.gradle index 50cfb74..331d5f0 100644 --- a/trustly-android-sdk/build.gradle +++ b/trustly-android-sdk/build.gradle @@ -2,6 +2,7 @@ plugins { id 'maven-publish' id 'com.android.library' version '8.2.2' id 'io.github.gradle-nexus.publish-plugin' version '1.1.0' + id 'org.jetbrains.kotlin.android' version '1.7.20' } def sdkVersion = "3.2.2" @@ -37,12 +38,16 @@ android { buildFeatures { buildConfig true } + kotlinOptions { + jvmTarget = '17' + } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'androidx.browser:browser:1.8.0' implementation 'com.google.code.gson:gson:2.11.0' + implementation 'androidx.core:core-ktx:1.13.1' testImplementation 'junit:junit:4.13.2' testImplementation 'org.powermock:powermock-api-mockito:1.4.12' diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.java deleted file mode 100644 index fbb208b..0000000 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.java +++ /dev/null @@ -1,48 +0,0 @@ -package net.trustly.android.sdk.data; - -import android.os.AsyncTask; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; - -public class APIRequests extends AsyncTask { - - private final APIAsyncResponse delegate; - - public interface APIAsyncResponse { - void processFinish(String output); - } - - public APIRequests(APIAsyncResponse delegate) { - this.delegate = delegate; - } - - @Override - protected String doInBackground(String... urls) { - try { - URL url = new URL(urls[0]); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setConnectTimeout(5000); - connection.setReadTimeout(5000); - connection.connect(); - BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream())); - StringBuilder content = new StringBuilder(); - String line; - while ((line = rd.readLine()) != null) { - content.append(line).append("\n"); - } - return content.toString(); - } catch (Exception e) { - return e.getMessage(); - } - } - - @Override - protected void onPostExecute(String result) { - delegate.processFinish(result); - } - -} diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.kt new file mode 100644 index 0000000..8db5284 --- /dev/null +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.kt @@ -0,0 +1,46 @@ +package net.trustly.android.sdk.data + +import android.os.AsyncTask +import java.io.BufferedReader +import java.io.InputStreamReader +import java.net.HttpURLConnection +import java.net.URL + +@Suppress("DEPRECATION") +class APIRequests(private val delegate: APIAsyncResponse) : AsyncTask() { + + companion object { + private const val TIMEOUT = 5000 + } + + interface APIAsyncResponse { + fun processFinish(output: String?) + } + + @Deprecated("Deprecated in Java") + override fun doInBackground(vararg params: String?): String? { + try { + val connection = URL(params.first()).openConnection() as HttpURLConnection + connection.apply { + requestMethod = "GET" + connectTimeout = TIMEOUT + readTimeout = TIMEOUT + }.connect() + val rd = BufferedReader(InputStreamReader(connection.inputStream)) + val content = StringBuilder() + var line: String? + while ((rd.readLine().also { line = it }) != null) { + content.append(line).append("\n") + } + return content.toString() + } catch (e: Exception) { + return e.message + } + } + + @Deprecated("Deprecated in Java") + override fun onPostExecute(result: String?) { + delegate.processFinish(result) + } + +} diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java deleted file mode 100644 index e986f0e..0000000 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Setting.java +++ /dev/null @@ -1,48 +0,0 @@ -package net.trustly.android.sdk.data; - -import com.google.gson.annotations.SerializedName; - -public class Setting { - - @SerializedName("settings") - public LightBoxSetting setting; - - public LightBoxSetting getSetting() { - return setting; - } - - public void setSetting(LightBoxSetting setting) { - this.setting = setting; - } - - public class LightBoxSetting { - - @SerializedName("lightbox") - public LightBoxContext lightbox; - - public LightBoxContext getLightbox() { - return lightbox; - } - - public void setLightbox(LightBoxContext lightbox) { - this.lightbox = lightbox; - } - - public class LightBoxContext { - - @SerializedName("context") - public String context; - - public String getContext() { - return context; - } - - public void setContext(String context) { - this.context = context; - } - - } - - } - -} \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Settings.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Settings.kt new file mode 100644 index 0000000..30fc229 --- /dev/null +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Settings.kt @@ -0,0 +1,13 @@ +package net.trustly.android.sdk.data + +data class Settings( + val settings: LightBoxSetting +) + +data class LightBoxSetting( + val lightbox: LightBoxContext +) + +data class LightBoxContext( + val context: String +) \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index f3cf3a3..b748c45 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -23,7 +23,7 @@ import net.trustly.android.sdk.BuildConfig; import net.trustly.android.sdk.TrustlyJsInterface; import net.trustly.android.sdk.data.APIRequests; -import net.trustly.android.sdk.data.Setting; +import net.trustly.android.sdk.data.Settings; import net.trustly.android.sdk.interfaces.Trustly; import net.trustly.android.sdk.interfaces.TrustlyCallback; import net.trustly.android.sdk.interfaces.TrustlyListener; @@ -354,10 +354,8 @@ public Trustly establish(Map establishData) { new APIRequests(output -> { // TODO Remove this hardcoded JSON output = "{'settings': {'lightbox': {'context': 'in-app-browser'}}}"; - Setting setting = new Gson().fromJson(output, Setting.class); - Setting.LightBoxSetting lightBox = setting.getSetting(); - Setting.LightBoxSetting.LightBoxContext lightbox = lightBox.getLightbox(); - if (lightbox.getContext().equals("in-app-browser")) { + Settings setting = new Gson().fromJson(output, Settings.class); + if (setting.getSettings().getLightbox().getContext().equals("in-app-browser")) { String jsonParameters = UrlUtils.getJsonFromParameters(data); String encodedParameters = UrlUtils.encodeStringToBase64(jsonParameters); CustomTabsManager.openCustomTabsIntent(getContext(), From c685e2a327f26aa563343bebf0f2ca5e56bf3bdb Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Mon, 12 Aug 2024 14:48:37 -0300 Subject: [PATCH 15/46] Updating kotlin references --- trustly-android-sdk/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trustly-android-sdk/build.gradle b/trustly-android-sdk/build.gradle index 331d5f0..74d7048 100644 --- a/trustly-android-sdk/build.gradle +++ b/trustly-android-sdk/build.gradle @@ -2,7 +2,7 @@ plugins { id 'maven-publish' id 'com.android.library' version '8.2.2' id 'io.github.gradle-nexus.publish-plugin' version '1.1.0' - id 'org.jetbrains.kotlin.android' version '1.7.20' + id 'org.jetbrains.kotlin.android' version '1.8.22' } def sdkVersion = "3.2.2" @@ -39,7 +39,7 @@ android { buildConfig true } kotlinOptions { - jvmTarget = '17' + jvmTarget = '1.8' } } From 3b913852349e362c8693ebd00cdcb996f124fc07 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Mon, 12 Aug 2024 15:42:55 -0300 Subject: [PATCH 16/46] Changing from asynctask to retrofit call --- trustly-android-sdk/build.gradle | 2 + .../trustly/android/sdk/data/APIInterface.kt | 12 +++++ .../trustly/android/sdk/data/APIRequest.kt | 41 +++++++++++++++++ .../trustly/android/sdk/data/APIRequests.kt | 46 ------------------- .../android/sdk/data/RetrofitInstance.kt | 17 +++++++ .../android/sdk/views/TrustlyView.java | 16 ++----- 6 files changed, 77 insertions(+), 57 deletions(-) create mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIInterface.kt create mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt delete mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.kt create mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/RetrofitInstance.kt diff --git a/trustly-android-sdk/build.gradle b/trustly-android-sdk/build.gradle index 74d7048..98221ee 100644 --- a/trustly-android-sdk/build.gradle +++ b/trustly-android-sdk/build.gradle @@ -48,6 +48,8 @@ dependencies { implementation 'androidx.browser:browser:1.8.0' implementation 'com.google.code.gson:gson:2.11.0' implementation 'androidx.core:core-ktx:1.13.1' + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.powermock:powermock-api-mockito:1.4.12' diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIInterface.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIInterface.kt new file mode 100644 index 0000000..e127498 --- /dev/null +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIInterface.kt @@ -0,0 +1,12 @@ +package net.trustly.android.sdk.data + +import retrofit2.Call +import retrofit2.http.GET + +interface APIInterface { + + //TODO Change this one with the correct endpoint + @GET("api/v2/breeds") + fun getSettings(): Call + +} \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt new file mode 100644 index 0000000..008860f --- /dev/null +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt @@ -0,0 +1,41 @@ +package net.trustly.android.sdk.data + +import android.util.Log +import com.google.gson.Gson +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response + +class APIRequest(private val settings: (Settings) -> Unit) { + + private val apiInterface = RetrofitInstance.getInstance().create(APIInterface::class.java) + + fun getSettingsData() { + apiInterface.getSettings().enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + if (response.isSuccessful && response.body() != null) { + //TODO Uncomment this lines +// Log.d("APIRequestNew", response.body().toString()) +// settings.invoke(response.body() as Settings) + + //TODO Remove this lines used to mock information + mockSettingsResult() + } + } + + override fun onFailure(call: Call, t: Throwable) { + Log.e("APIRequestNew", t.message.toString()) + + //TODO Remove this lines used to mock information + mockSettingsResult() + } + }) + } + + private fun mockSettingsResult() { + //TODO Remove this lines used to mock information + val output = "{'settings': {'lightbox': {'context': 'in-app-browser'}}}"; + settings.invoke(Gson().fromJson(output, Settings::class.java)) + } + +} \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.kt deleted file mode 100644 index 8db5284..0000000 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequests.kt +++ /dev/null @@ -1,46 +0,0 @@ -package net.trustly.android.sdk.data - -import android.os.AsyncTask -import java.io.BufferedReader -import java.io.InputStreamReader -import java.net.HttpURLConnection -import java.net.URL - -@Suppress("DEPRECATION") -class APIRequests(private val delegate: APIAsyncResponse) : AsyncTask() { - - companion object { - private const val TIMEOUT = 5000 - } - - interface APIAsyncResponse { - fun processFinish(output: String?) - } - - @Deprecated("Deprecated in Java") - override fun doInBackground(vararg params: String?): String? { - try { - val connection = URL(params.first()).openConnection() as HttpURLConnection - connection.apply { - requestMethod = "GET" - connectTimeout = TIMEOUT - readTimeout = TIMEOUT - }.connect() - val rd = BufferedReader(InputStreamReader(connection.inputStream)) - val content = StringBuilder() - var line: String? - while ((rd.readLine().also { line = it }) != null) { - content.append(line).append("\n") - } - return content.toString() - } catch (e: Exception) { - return e.message - } - } - - @Deprecated("Deprecated in Java") - override fun onPostExecute(result: String?) { - delegate.processFinish(result) - } - -} diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/RetrofitInstance.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/RetrofitInstance.kt new file mode 100644 index 0000000..6092e19 --- /dev/null +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/RetrofitInstance.kt @@ -0,0 +1,17 @@ +package net.trustly.android.sdk.data + +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +object RetrofitInstance { + + //TODO Change this one with the correct endpoint + private const val BASE_URL = "https://dogapi.dog/" + + fun getInstance(): Retrofit { + return Retrofit.Builder().baseUrl(BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .build() + } + +} \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index b748c45..e516560 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -18,12 +18,9 @@ import androidx.annotation.RequiresApi; -import com.google.gson.Gson; - import net.trustly.android.sdk.BuildConfig; import net.trustly.android.sdk.TrustlyJsInterface; -import net.trustly.android.sdk.data.APIRequests; -import net.trustly.android.sdk.data.Settings; +import net.trustly.android.sdk.data.APIRequest; import net.trustly.android.sdk.interfaces.Trustly; import net.trustly.android.sdk.interfaces.TrustlyCallback; import net.trustly.android.sdk.interfaces.TrustlyListener; @@ -351,11 +348,8 @@ public Trustly establish(Map establishData) { byte[] parameters = UrlUtils.getParameterString(data).getBytes("UTF-8"); - new APIRequests(output -> { - // TODO Remove this hardcoded JSON - output = "{'settings': {'lightbox': {'context': 'in-app-browser'}}}"; - Settings setting = new Gson().fromJson(output, Settings.class); - if (setting.getSettings().getLightbox().getContext().equals("in-app-browser")) { + new APIRequest(settings -> { + if (settings.getSettings().getLightbox().getContext().equals("in-app-browser")) { String jsonParameters = UrlUtils.getJsonFromParameters(data); String encodedParameters = UrlUtils.encodeStringToBase64(jsonParameters); CustomTabsManager.openCustomTabsIntent(getContext(), @@ -365,8 +359,8 @@ public Trustly establish(Map establishData) { } else { webView.postUrl(getEndpointUrl("index", establishData), parameters); } - // TODO Change this endpoint with the right one - }).execute("https://dogapi.dog/api/v2/breeds"); + return null; + }).getSettingsData(); } catch (Exception e) { } return this; From 1f86697fb4887114c3b17dacc06ac310e160b40f Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Mon, 12 Aug 2024 17:40:05 -0300 Subject: [PATCH 17/46] Adding unit test for api request --- trustly-android-sdk/build.gradle | 5 +- .../data/{APIInterface.kt => APIMethod.kt} | 2 +- .../trustly/android/sdk/data/APIRequest.kt | 4 +- .../android/sdk/views/TrustlyView.java | 5 +- .../android/sdk/data/APIRequestTest.kt | 116 ++++++++++++++++++ 5 files changed, 124 insertions(+), 8 deletions(-) rename trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/{APIInterface.kt => APIMethod.kt} (89%) create mode 100644 trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt diff --git a/trustly-android-sdk/build.gradle b/trustly-android-sdk/build.gradle index 98221ee..b26ff55 100644 --- a/trustly-android-sdk/build.gradle +++ b/trustly-android-sdk/build.gradle @@ -46,14 +46,13 @@ android { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'androidx.browser:browser:1.8.0' - implementation 'com.google.code.gson:gson:2.11.0' implementation 'androidx.core:core-ktx:1.13.1' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.powermock:powermock-api-mockito:1.4.12' - testImplementation 'org.powermock:powermock-module-junit4:2.0.5' + testImplementation 'com.google.code.gson:gson:2.11.0' + testImplementation 'org.mockito:mockito-core:4.2.0' androidTestImplementation 'androidx.test:core:1.6.1' androidTestImplementation 'androidx.test:runner:1.6.1' diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIInterface.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt similarity index 89% rename from trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIInterface.kt rename to trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt index e127498..95ad80c 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIInterface.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt @@ -3,7 +3,7 @@ package net.trustly.android.sdk.data import retrofit2.Call import retrofit2.http.GET -interface APIInterface { +interface APIMethod { //TODO Change this one with the correct endpoint @GET("api/v2/breeds") diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt index 008860f..4461fd0 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt @@ -6,9 +6,7 @@ import retrofit2.Call import retrofit2.Callback import retrofit2.Response -class APIRequest(private val settings: (Settings) -> Unit) { - - private val apiInterface = RetrofitInstance.getInstance().create(APIInterface::class.java) +class APIRequest(private val apiInterface: APIMethod, private val settings: (Settings) -> Unit) { fun getSettingsData() { apiInterface.getSettings().enqueue(object : Callback { diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index e516560..a97ec4a 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -20,7 +20,9 @@ import net.trustly.android.sdk.BuildConfig; import net.trustly.android.sdk.TrustlyJsInterface; +import net.trustly.android.sdk.data.APIMethod; import net.trustly.android.sdk.data.APIRequest; +import net.trustly.android.sdk.data.RetrofitInstance; import net.trustly.android.sdk.interfaces.Trustly; import net.trustly.android.sdk.interfaces.TrustlyCallback; import net.trustly.android.sdk.interfaces.TrustlyListener; @@ -43,6 +45,7 @@ public class TrustlyView extends LinearLayout implements Trustly { static String DOMAIN = "paywithmybank.com"; static String version = BuildConfig.SDK_VERSION; private static boolean isLocalEnvironment = false; + APIMethod apiInterface = RetrofitInstance.INSTANCE.getInstance().create(APIMethod.class); enum Status { START, @@ -348,7 +351,7 @@ public Trustly establish(Map establishData) { byte[] parameters = UrlUtils.getParameterString(data).getBytes("UTF-8"); - new APIRequest(settings -> { + new APIRequest(apiInterface, settings -> { if (settings.getSettings().getLightbox().getContext().equals("in-app-browser")) { String jsonParameters = UrlUtils.getJsonFromParameters(data); String encodedParameters = UrlUtils.encodeStringToBase64(jsonParameters); diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt new file mode 100644 index 0000000..6033098 --- /dev/null +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt @@ -0,0 +1,116 @@ +package net.trustly.android.sdk.data + +import com.google.gson.Gson +import okhttp3.MediaType +import okhttp3.ResponseBody +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotEquals +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito.any +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations +import retrofit2.Call +import retrofit2.Response + +class APIRequestTest { + + @Mock + private lateinit var api: APIMethod + + @Mock + private lateinit var mockCall: Call + + private var settingsResult: Settings? = null + + @Before + fun setup() { + MockitoAnnotations.openMocks(this) + + `when`(api.getSettings()).thenReturn(mockCall) + } + + @After + fun tearDown() { + api.getSettings().cancel() + mockCall.cancel() + settingsResult = null + } + + @Test + fun testGetSettingDataWhenReturnSuccess() { + val settingsFake = getSettingsFake() + val mockResponse = Response.success(settingsFake) + mockCallbackResponse(mockResponse) + + APIRequest(api) { settingsResult = it }.getSettingsData() + + assertEquals(settingsFake, settingsResult) + } + + @Test + fun testGetSettingDataValuesWhenReturnSuccess() { + val settingsFake = getSettingsFake() + val mockResponse = Response.success(settingsFake) + mockCallbackResponse(mockResponse) + + APIRequest(api) { settingsResult = it }.getSettingsData() + + assertEquals(settingsFake, settingsResult) + assertEquals("in-app-browser", settingsResult!!.settings.lightbox.context) + } + + @Test + fun testGetSettingDataWrongValuesWhenReturnSuccess() { + val settingsFake = getSettingsFake() + val mockResponse = Response.success(settingsFake) + mockCallbackResponse(mockResponse) + + APIRequest(api) { settingsResult = it }.getSettingsData() + + assertEquals(settingsFake, settingsResult) + assertNotEquals("web-view", settingsResult!!.settings.lightbox.context) + } + + @Test + fun testGetSettingDataWhenReturnFailure() { + val mockResponse = Response.error( + 401, + ResponseBody.create(MediaType.parse("application/json"), "") + ) + mockCallbackResponse(mockResponse) + + APIRequest(api) { settingsResult = it }.getSettingsData() + + assertEquals(null, settingsResult) + } + + @Test + fun testGetSettingDataWhenReturnNetworkExceptionError() { + val mockResponse = Response.error( + 500, + ResponseBody.create(MediaType.parse("plain/text"), "API Not found") + ) + mockCallbackResponse(mockResponse) + + APIRequest(api) { settingsResult = it }.getSettingsData() + + assertEquals(null, settingsResult) + } + + private fun mockCallbackResponse(mockResponse: Response) { + `when`(mockCall.enqueue(any())).then { + val callback = it.arguments.first() as retrofit2.Callback + callback.onResponse(mockCall, mockResponse) + } + } + + private fun getSettingsFake(): Settings { + return Gson().fromJson(getSettingsJson(), Settings::class.java) + } + + private fun getSettingsJson() = "{'settings': {'lightbox': {'context': 'in-app-browser'}}}" + +} \ No newline at end of file From 4c941d3097e7bc4f21061fb3f93b089e539699b8 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 13 Aug 2024 09:40:53 -0300 Subject: [PATCH 18/46] Remove unused code --- .../trustly/android/sdk/data/APIRequest.kt | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt index 4461fd0..d1e407a 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt @@ -1,7 +1,6 @@ package net.trustly.android.sdk.data import android.util.Log -import com.google.gson.Gson import retrofit2.Call import retrofit2.Callback import retrofit2.Response @@ -12,28 +11,15 @@ class APIRequest(private val apiInterface: APIMethod, private val settings: (Set apiInterface.getSettings().enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { if (response.isSuccessful && response.body() != null) { - //TODO Uncomment this lines -// Log.d("APIRequestNew", response.body().toString()) -// settings.invoke(response.body() as Settings) - - //TODO Remove this lines used to mock information - mockSettingsResult() + Log.d("APIRequest", response.body().toString()) + settings.invoke(response.body() as Settings) } } override fun onFailure(call: Call, t: Throwable) { - Log.e("APIRequestNew", t.message.toString()) - - //TODO Remove this lines used to mock information - mockSettingsResult() + Log.e("APIRequest", t.message.toString()) } }) } - private fun mockSettingsResult() { - //TODO Remove this lines used to mock information - val output = "{'settings': {'lightbox': {'context': 'in-app-browser'}}}"; - settings.invoke(Gson().fromJson(output, Settings::class.java)) - } - } \ No newline at end of file From 888afdf90ddf600bba35c58ad43bd7676716b749 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 13 Aug 2024 09:51:50 -0300 Subject: [PATCH 19/46] Adding unit test on retrofit instance --- .../android/sdk/data/RetrofitInstanceTest.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/RetrofitInstanceTest.kt diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/RetrofitInstanceTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/RetrofitInstanceTest.kt new file mode 100644 index 0000000..28e29d7 --- /dev/null +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/RetrofitInstanceTest.kt @@ -0,0 +1,20 @@ +package net.trustly.android.sdk.data + +import org.junit.Assert.assertNotNull +import org.junit.Test + +class RetrofitInstanceTest { + + @Test + fun testRetrofitInstance() { + val instance = RetrofitInstance.getInstance() + assert(instance.baseUrl().toString() == "https://dogapi.dog/") + } + + @Test + fun testRetrofitInstanceNotNull() { + val instance = RetrofitInstance.getInstance() + assertNotNull(instance) + } + +} \ No newline at end of file From 73cfbec205fd2e0382f990da8ddf4dadb5176666 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 13 Aug 2024 09:59:14 -0300 Subject: [PATCH 20/46] Changing version --- trustly-android-sdk/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trustly-android-sdk/build.gradle b/trustly-android-sdk/build.gradle index b26ff55..79a184a 100644 --- a/trustly-android-sdk/build.gradle +++ b/trustly-android-sdk/build.gradle @@ -5,7 +5,7 @@ plugins { id 'org.jetbrains.kotlin.android' version '1.8.22' } -def sdkVersion = "3.2.2" +def sdkVersion = "3.3.0" android { publishing { From 77931e577c413106ee2ff46accbd4739b19a2339 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Mon, 19 Aug 2024 17:40:09 -0300 Subject: [PATCH 21/46] Adding query parameters --- .../net/trustly/android/sdk/data/APIMethod.kt | 7 ++++++- .../net/trustly/android/sdk/data/APIRequest.kt | 4 ++-- .../trustly/android/sdk/views/TrustlyView.java | 2 +- .../trustly/android/sdk/data/APIRequestTest.kt | 15 ++++++++------- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt index 95ad80c..f561f88 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt @@ -2,11 +2,16 @@ package net.trustly.android.sdk.data import retrofit2.Call import retrofit2.http.GET +import retrofit2.http.Query interface APIMethod { //TODO Change this one with the correct endpoint @GET("api/v2/breeds") - fun getSettings(): Call + fun getSettings( + @Query("merchantId") merchantId: String, + @Query("grp") grp: String, + @Query("metadata.flowtype") flowType: String + ): Call } \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt index d1e407a..08dead2 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt @@ -7,8 +7,8 @@ import retrofit2.Response class APIRequest(private val apiInterface: APIMethod, private val settings: (Settings) -> Unit) { - fun getSettingsData() { - apiInterface.getSettings().enqueue(object : Callback { + fun getSettingsData(merchantId: String, grp: String, flowType: String) { + apiInterface.getSettings(merchantId, grp, flowType).enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { if (response.isSuccessful && response.body() != null) { Log.d("APIRequest", response.body().toString()) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index a97ec4a..2eb8cb1 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -363,7 +363,7 @@ public Trustly establish(Map establishData) { webView.postUrl(getEndpointUrl("index", establishData), parameters); } return null; - }).getSettingsData(); + }).getSettingsData(data.get("merchantId"), data.get("grp"), data.get("metadata.flowtype")); } catch (Exception e) { } return this; diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt index 6033098..6703e61 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt @@ -10,6 +10,7 @@ import org.junit.Before import org.junit.Test import org.mockito.Mock import org.mockito.Mockito.any +import org.mockito.Mockito.anyString import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations import retrofit2.Call @@ -29,12 +30,12 @@ class APIRequestTest { fun setup() { MockitoAnnotations.openMocks(this) - `when`(api.getSettings()).thenReturn(mockCall) + `when`(api.getSettings(anyString(), anyString(), anyString())).thenReturn(mockCall) } @After fun tearDown() { - api.getSettings().cancel() + api.getSettings("110005514", "1", "web-view").cancel() mockCall.cancel() settingsResult = null } @@ -45,7 +46,7 @@ class APIRequestTest { val mockResponse = Response.success(settingsFake) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData() + APIRequest(api) { settingsResult = it }.getSettingsData("110005514", "1", "web-view") assertEquals(settingsFake, settingsResult) } @@ -56,7 +57,7 @@ class APIRequestTest { val mockResponse = Response.success(settingsFake) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData() + APIRequest(api) { settingsResult = it }.getSettingsData("110005514", "1", "web-view") assertEquals(settingsFake, settingsResult) assertEquals("in-app-browser", settingsResult!!.settings.lightbox.context) @@ -68,7 +69,7 @@ class APIRequestTest { val mockResponse = Response.success(settingsFake) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData() + APIRequest(api) { settingsResult = it }.getSettingsData("110005514", "1", "web-view") assertEquals(settingsFake, settingsResult) assertNotEquals("web-view", settingsResult!!.settings.lightbox.context) @@ -82,7 +83,7 @@ class APIRequestTest { ) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData() + APIRequest(api) { settingsResult = it }.getSettingsData("110005514", "1", "web-view") assertEquals(null, settingsResult) } @@ -95,7 +96,7 @@ class APIRequestTest { ) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData() + APIRequest(api) { settingsResult = it }.getSettingsData("110005514", "1", "web-view") assertEquals(null, settingsResult) } From 4a5182b1ce5ba13dc355b5d5c90ec00cfb005b43 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 20 Aug 2024 16:18:31 -0300 Subject: [PATCH 22/46] Unit test in util class --- trustly-android-sdk/build.gradle | 2 +- .../net/trustly/android/sdk/UrlUtilsTest.java | 203 ++++++------------ 2 files changed, 66 insertions(+), 139 deletions(-) diff --git a/trustly-android-sdk/build.gradle b/trustly-android-sdk/build.gradle index 79a184a..1d06198 100644 --- a/trustly-android-sdk/build.gradle +++ b/trustly-android-sdk/build.gradle @@ -55,7 +55,7 @@ dependencies { testImplementation 'org.mockito:mockito-core:4.2.0' androidTestImplementation 'androidx.test:core:1.6.1' - androidTestImplementation 'androidx.test:runner:1.6.1' + androidTestImplementation 'androidx.test:runner:1.6.2' androidTestImplementation 'androidx.test:rules:1.6.1' androidTestImplementation 'androidx.test.ext:junit:1.2.1' androidTestImplementation 'androidx.test.ext:truth:1.6.0' diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/UrlUtilsTest.java b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/UrlUtilsTest.java index f7e65e3..d37a9b4 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/UrlUtilsTest.java +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/UrlUtilsTest.java @@ -1,138 +1,65 @@ -// package net.trustly.android.sdk; - -// import static org.junit.Assert.assertEquals; -// import static org.junit.Assert.assertNotEquals; -// import static org.mockito.Matchers.anyString; -// import static org.powermock.api.mockito.PowerMockito.mock; -// import static org.powermock.api.mockito.PowerMockito.mockStatic; - -// import android.net.Uri; - -// import net.trustly.android.sdk.util.UrlUtils; - -// import org.junit.Test; -// import org.junit.runner.RunWith; -// import org.powermock.api.mockito.PowerMockito; -// import org.powermock.core.classloader.annotations.PowerMockIgnore; -// import org.powermock.core.classloader.annotations.PrepareForTest; -// import org.powermock.modules.junit4.PowerMockRunner; - -// import java.net.URLEncoder; -// import java.util.Collections; -// import java.util.HashMap; -// import java.util.Map; -// import java.util.Set; - -// @RunWith(PowerMockRunner.class) -// @PrepareForTest({Uri.class}) -// @PowerMockIgnore("jdk.internal.reflect.*") -// public class UrlUtilsTest { - -// @Test(expected = Exception.class) -// public void shouldThrowExceptionWhenGetQueryParameterNamesReceiveNull() { -// UrlUtils.getQueryParameterNames(null); -// } - -// @Test -// public void shouldInvalidadeReturnedValueWhenGetQueryParameterNames() throws Exception { -// mockUri(); -// Uri parse = Uri.parse("http://www.url.com/search?q=random%20word%20%A3500%20bank%20%24"); -// Set parameterNames = UrlUtils.getQueryParameterNames(parse); -// assertNotEquals(null, parameterNames); -// } - -// @Test -// public void shouldValidadeReturnedValueWhenGetQueryParameterNames() throws Exception { -// mockUri(); -// String encode = URLEncoder.encode("q=example", "UTF-8"); -// Uri parse = Uri.parse("http://www.google.com:80/help/me/book%20name+me/?" + encode); -// Set parameterNames = UrlUtils.getQueryParameterNames(parse); -// assertEquals(Collections.emptySet(), parameterNames); -// } - -// @Test(expected = Exception.class) -// public void shouldThrowExceptionWhenGetQueryParameterFromUrlReceiveNull() throws Exception { -// mockUri(); -// UrlUtils.getQueryParametersFromUrl(null); -// } - -// @Test -// public void shouldInvalidateReturnedValueWhenGetQueryParameterFromUrl() throws Exception { -// mockUri(); -// Map parameters = UrlUtils.getQueryParametersFromUrl("http://www.url.com/search?q=value"); -// assertNotEquals("http://www.url.com/search", parameters.get("url")); -// } - -// @Test -// public void shouldValidateReturnedValueWhenGetQueryParameterFromUrl() throws Exception { -// mockUri(); -// Map parameters = UrlUtils.getQueryParametersFromUrl("http://www.url.com/search?q=value"); -// assertEquals("http://www.url.com/search?q=value", parameters.get("url")); -// } - -// @Test -// public void shouldReplaceParameterRequestSignatureValueWhenGetQueryParameterFromUrl() throws Exception { -// mockUri(); -// Map parameters = UrlUtils.getQueryParametersFromUrl("http://www.url.com/search?requestSignature=1234"); -// assertEquals("http://www.url.com/search?", parameters.get("url")); -// } - -// @Test -// public void shouldValidateReturnedValueWhenGetQueryParameterFromUrlWithManyParameters() throws Exception { -// mockUri(); -// Map parameters = UrlUtils.getQueryParametersFromUrl("http://www.url.com/search?q=value&a=value2&b=value3"); -// assertEquals("http://www.url.com/search?q=value&a=value2&b=value3", parameters.get("url")); -// } - -// @Test(expected = NullPointerException.class) -// public void shouldThrowExceptionWhenGetParameterStringReceiveNull() { -// UrlUtils.getParameterString(null); -// } - -// @Test -// public void shouldInvalidateReturnedValueWhenGetParameterString() { -// Map values = new HashMap<>(); -// values.put("key1", "value1"); -// values.put("key2", "value2"); -// values.put("key3", "value3"); -// String parameter = UrlUtils.getParameterString(values); -// assertNotEquals("key1=value1,key2=value2,key3=value3", parameter); -// } - -// @Test -// public void shouldValidateReturnedValueWhenGetParameterString() { -// Map values = new HashMap<>(); -// values.put("key1", "value1"); -// values.put("key2", "value2"); -// values.put("key3", "value3"); -// String parameter = UrlUtils.getParameterString(values); -// assertEquals("key1=value1&key2=value2&key3=value3", parameter); -// } - -// @Test -// public void shouldValidateReturnedValueWhenGetParameterStringWithNullKey() { -// Map values = new HashMap<>(); -// values.put(null, "value1"); -// values.put("key2", "value2"); -// values.put("key3", "value3"); -// String parameter = UrlUtils.getParameterString(values); -// assertEquals("=value1&key2=value2&key3=value3", parameter); -// } - -// @Test -// public void shouldValidateReturnedValueWhenGetParameterStringWithNullValue() { -// Map values = new HashMap<>(); -// values.put("key1", "value1"); -// values.put("key2", null); -// values.put("key3", "value3"); -// String parameter = UrlUtils.getParameterString(values); -// assertEquals("key1=value1&key2=&key3=value3", parameter); -// } - -// private void mockUri() throws Exception { -// mockStatic(Uri.class); -// PowerMockito.when(Uri.class, "parse", anyString()) -// .thenReturn(mock(Uri.class)); -// } - -// } + package net.trustly.android.sdk; + + import static org.junit.Assert.assertEquals; + import static org.junit.Assert.assertNotEquals; + + import net.trustly.android.sdk.util.UrlUtils; + + import org.junit.Test; + + import java.util.HashMap; + import java.util.Map; + + public class UrlUtilsTest { + + @Test(expected = Exception.class) + public void shouldThrowExceptionWhenGetQueryParameterNamesReceiveNull() { + UrlUtils.getQueryParameterNames(null); + } + + @Test(expected = NullPointerException.class) + public void shouldThrowExceptionWhenGetParameterStringReceiveNull() { + UrlUtils.getParameterString(null); + } + + @Test + public void shouldInvalidateReturnedValueWhenGetParameterString() { + Map values = new HashMap<>(); + values.put("key1", "value1"); + values.put("key2", "value2"); + values.put("key3", "value3"); + String parameter = UrlUtils.getParameterString(values); + assertNotEquals("key1=value1,key2=value2,key3=value3", parameter); + } + + @Test + public void shouldValidateReturnedValueWhenGetParameterString() { + Map values = new HashMap<>(); + values.put("key1", "value1"); + values.put("key2", "value2"); + values.put("key3", "value3"); + String parameter = UrlUtils.getParameterString(values); + assertEquals("key1=value1&key2=value2&key3=value3", parameter); + } + + @Test + public void shouldValidateReturnedValueWhenGetParameterStringWithNullKey() { + Map values = new HashMap<>(); + values.put(null, "value1"); + values.put("key2", "value2"); + values.put("key3", "value3"); + String parameter = UrlUtils.getParameterString(values); + assertEquals("=value1&key2=value2&key3=value3", parameter); + } + + @Test + public void shouldValidateReturnedValueWhenGetParameterStringWithNullValue() { + Map values = new HashMap<>(); + values.put("key1", "value1"); + values.put("key2", null); + values.put("key3", "value3"); + String parameter = UrlUtils.getParameterString(values); + assertEquals("key1=value1&key2=&key3=value3", parameter); + } + + } From 1b6c447dbe216bb4c55075ad8ee47706a62e3899 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Wed, 21 Aug 2024 10:17:11 -0300 Subject: [PATCH 23/46] Return mocked data --- .../trustly/android/sdk/data/APIRequest.kt | 26 +++++++++++++++++-- .../android/sdk/views/TrustlyView.java | 3 ++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt index 08dead2..51eed19 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt @@ -1,25 +1,47 @@ package net.trustly.android.sdk.data import android.util.Log +import com.google.gson.Gson import retrofit2.Call import retrofit2.Callback import retrofit2.Response class APIRequest(private val apiInterface: APIMethod, private val settings: (Settings) -> Unit) { + //TODO Remove this method used to mock information + fun getSettingsMockData() { + apiInterface.getSettings("", "", "").enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + if (response.isSuccessful && response.body() != null) { + mockSettingsResult() + } + } + + override fun onFailure(call: Call, t: Throwable) { + mockSettingsResult() + } + }) + } + fun getSettingsData(merchantId: String, grp: String, flowType: String) { apiInterface.getSettings(merchantId, grp, flowType).enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { if (response.isSuccessful && response.body() != null) { - Log.d("APIRequest", response.body().toString()) + Log.d("APIRequestNew", response.body().toString()) settings.invoke(response.body() as Settings) } } override fun onFailure(call: Call, t: Throwable) { - Log.e("APIRequest", t.message.toString()) + Log.e("APIRequestNew", t.message.toString()) } }) } + //TODO Remove this method used to mock information + private fun mockSettingsResult() { + val output = "{'settings': {'lightbox': {'context': 'in-app-browser'}}}"; + settings.invoke(Gson().fromJson(output, Settings::class.java)) + } + } \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 2eb8cb1..60fa5ce 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -363,7 +363,8 @@ public Trustly establish(Map establishData) { webView.postUrl(getEndpointUrl("index", establishData), parameters); } return null; - }).getSettingsData(data.get("merchantId"), data.get("grp"), data.get("metadata.flowtype")); + }).getSettingsMockData(); +// }).getSettingsData(data.get("merchantId"), data.get("grp"), data.get("metadata.flowtype")); } catch (Exception e) { } return this; From bdc0fab69846e735acd17c67e9ad38d75e479a20 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Wed, 21 Aug 2024 11:02:48 -0300 Subject: [PATCH 24/46] Adding unit test for apirequest --- .../android/sdk/util/api/APIRequestManager.kt | 22 ++++++++++ .../android/sdk/util/api/APIRequestStorage.kt | 22 ++++++++++ .../sdk/util/{ => cid}/CidManager.java | 2 +- .../sdk/util/{ => cid}/CidStorage.java | 2 +- .../android/sdk/views/TrustlyView.java | 2 +- .../sdk/util/api/APIRequestStorageTest.kt | 44 +++++++++++++++++++ 6 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestManager.kt create mode 100644 trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestStorage.kt rename trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/{ => cid}/CidManager.java (98%) rename trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/{ => cid}/CidStorage.java (95%) create mode 100644 trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestStorageTest.kt diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestManager.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestManager.kt new file mode 100644 index 0000000..0d4489f --- /dev/null +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestManager.kt @@ -0,0 +1,22 @@ +package net.trustly.android.sdk.util.api + +import android.content.Context +import java.util.Calendar + +object APIRequestManager { + + private const val API_REQUEST = "API_REQUEST" + + fun saveAPIRequest(context: Context) { + APIRequestStorage.saveData(context, API_REQUEST, getTimestamp()) + } + + fun getAPIRequest(context: Context): String? { + return APIRequestStorage.readDataFrom(context, API_REQUEST) + } + + private fun getTimestamp(): String { + return Calendar.getInstance().timeInMillis.toString() + } + +} \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestStorage.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestStorage.kt new file mode 100644 index 0000000..ace6ce8 --- /dev/null +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestStorage.kt @@ -0,0 +1,22 @@ +package net.trustly.android.sdk.util.api + +import android.content.Context +import android.content.SharedPreferences + +object APIRequestStorage { + + private const val API_STORAGE = "API_STORAGE" + + fun saveData(context: Context, preferenceId: String?, preferenceValue: String?) { + getSharedPreferences(context).edit().putString(preferenceId, preferenceValue).apply() + } + + fun readDataFrom(context: Context, preferenceId: String?): String? { + return getSharedPreferences(context).getString(preferenceId, null) + } + + private fun getSharedPreferences(context: Context): SharedPreferences { + return context.getSharedPreferences(API_STORAGE, Context.MODE_PRIVATE) + } + +} \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/CidManager.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidManager.java similarity index 98% rename from trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/CidManager.java rename to trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidManager.java index 2c307d2..b7663cb 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/CidManager.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidManager.java @@ -1,4 +1,4 @@ -package net.trustly.android.sdk.util; +package net.trustly.android.sdk.util.cid; import android.annotation.SuppressLint; import android.content.Context; diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/CidStorage.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidStorage.java similarity index 95% rename from trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/CidStorage.java rename to trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidStorage.java index 8347c04..2aa8fd5 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/CidStorage.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidStorage.java @@ -1,4 +1,4 @@ -package net.trustly.android.sdk.util; +package net.trustly.android.sdk.util.cid; import android.content.Context; import android.content.SharedPreferences; diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 60fa5ce..78a0ae6 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -26,7 +26,7 @@ import net.trustly.android.sdk.interfaces.Trustly; import net.trustly.android.sdk.interfaces.TrustlyCallback; import net.trustly.android.sdk.interfaces.TrustlyListener; -import net.trustly.android.sdk.util.CidManager; +import net.trustly.android.sdk.util.cid.CidManager; import net.trustly.android.sdk.util.CustomTabsManager; import net.trustly.android.sdk.util.UrlUtils; diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestStorageTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestStorageTest.kt new file mode 100644 index 0000000..a23db6d --- /dev/null +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestStorageTest.kt @@ -0,0 +1,44 @@ +package net.trustly.android.sdk.util.api + +import android.content.Context +import android.content.SharedPreferences +import org.junit.Test +import org.mockito.Mockito.anyString +import org.mockito.Mockito.mock +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` + +class APIRequestStorageTest { + + @Test + fun testSavingDataAPIRequest() { + val mockEdit = mock(SharedPreferences.Editor::class.java) + `when`(mockEdit.putString(anyString(), anyString())).thenReturn(mockEdit) + + val mockedPrefs = mock(SharedPreferences::class.java) + `when`(mockedPrefs.edit()).thenReturn(mockEdit) + + val mockedContext = mock(Context::class.java) + `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) + + APIRequestStorage.saveData(mockedContext, "API_REQUEST", "1724258668") + + verify(mockEdit, times(1)).putString("API_REQUEST", "1724258668") + verify(mockEdit, times(1)).apply() + } + + @Test + fun testReadingDataAPIRequest() { + val mockedPrefs = mock(SharedPreferences::class.java) + `when`(mockedPrefs.getString(anyString(), anyString())).thenReturn("1724258668") + + val mockedContext = mock(Context::class.java) + `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) + + APIRequestStorage.readDataFrom(mockedContext, "API_REQUEST") + + verify(mockedPrefs, times(1)).getString("API_REQUEST", null) + } + +} \ No newline at end of file From 9658c4c5b81f36aec2035894da503cb2067f5602 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Wed, 21 Aug 2024 18:50:58 -0300 Subject: [PATCH 25/46] Adding unit tests for apirequests --- trustly-android-sdk/build.gradle | 1 + .../trustly/android/sdk/data/APIRequest.kt | 2 +- .../sdk/util/api/APIRequestManagerTest.kt | 68 +++++++++++++++++++ .../sdk/util/api/APIRequestStorageTest.kt | 33 ++++++--- 4 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt diff --git a/trustly-android-sdk/build.gradle b/trustly-android-sdk/build.gradle index 1d06198..e540be6 100644 --- a/trustly-android-sdk/build.gradle +++ b/trustly-android-sdk/build.gradle @@ -53,6 +53,7 @@ dependencies { testImplementation 'junit:junit:4.13.2' testImplementation 'com.google.code.gson:gson:2.11.0' testImplementation 'org.mockito:mockito-core:4.2.0' + testImplementation 'org.mockito:mockito-inline:4.2.0' androidTestImplementation 'androidx.test:core:1.6.1' androidTestImplementation 'androidx.test:runner:1.6.2' diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt index 51eed19..dc6bc62 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt @@ -40,7 +40,7 @@ class APIRequest(private val apiInterface: APIMethod, private val settings: (Set //TODO Remove this method used to mock information private fun mockSettingsResult() { - val output = "{'settings': {'lightbox': {'context': 'in-app-browser'}}}"; + val output = "{'settings': {'lightbox': {'context': 'web-view'}}}"; settings.invoke(Gson().fromJson(output, Settings::class.java)) } diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt new file mode 100644 index 0000000..e662a6c --- /dev/null +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt @@ -0,0 +1,68 @@ +package net.trustly.android.sdk.util.api + +import android.content.Context +import android.content.SharedPreferences +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito.CALLS_REAL_METHODS +import org.mockito.Mockito.anyString +import org.mockito.Mockito.clearInvocations +import org.mockito.Mockito.mock +import org.mockito.Mockito.mockStatic +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` + + +class APIRequestManagerTest { + + @Mock + lateinit var mockEdit: SharedPreferences.Editor + + @Mock + lateinit var mockedPrefs: SharedPreferences + + @Mock + lateinit var mockedContext: Context + + @Before + fun setUp() { + mockEdit = mock(SharedPreferences.Editor::class.java) + mockedPrefs = mock(SharedPreferences::class.java) + mockedContext = mock(Context::class.java) + } + + @After + fun tearDown() { + clearInvocations(mockEdit, mockedContext, mockedPrefs) + } + + @Test + fun testGettingDataAPIRequest() { + `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) + `when`(mockedPrefs.getString(anyString(), anyString())).thenReturn("1724258668") + + mockStatic(APIRequestStorage::class.java, CALLS_REAL_METHODS).use { static -> + static.`when` { APIRequestStorage.readDataFrom(mockedContext, "API_REQUEST") } + .thenReturn("13896438") + } + + val result = APIRequestManager.getAPIRequest(mockedContext) + assertEquals("13896438", result) + } + + @Test + fun testSavingDataAPIRequest() { + `when`(mockEdit.putString(anyString(), anyString())).thenReturn(mockEdit) + `when`(mockedPrefs.edit()).thenReturn(mockEdit) + `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) + + APIRequestManager.saveAPIRequest(mockedContext) + + verify(mockEdit, times(1)).apply() + } + +} \ No newline at end of file diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestStorageTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestStorageTest.kt index a23db6d..cb7dc5d 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestStorageTest.kt +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestStorageTest.kt @@ -2,8 +2,12 @@ package net.trustly.android.sdk.util.api import android.content.Context import android.content.SharedPreferences +import org.junit.After +import org.junit.Before import org.junit.Test +import org.mockito.Mock import org.mockito.Mockito.anyString +import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.mock import org.mockito.Mockito.times import org.mockito.Mockito.verify @@ -11,15 +15,31 @@ import org.mockito.Mockito.`when` class APIRequestStorageTest { + @Mock + lateinit var mockEdit: SharedPreferences.Editor + + @Mock + lateinit var mockedPrefs: SharedPreferences + + @Mock + lateinit var mockedContext: Context + + @Before + fun setUp() { + mockEdit = mock(SharedPreferences.Editor::class.java) + mockedPrefs = mock(SharedPreferences::class.java) + mockedContext = mock(Context::class.java) + } + + @After + fun tearDown() { + clearInvocations(mockEdit, mockedContext, mockedPrefs) + } + @Test fun testSavingDataAPIRequest() { - val mockEdit = mock(SharedPreferences.Editor::class.java) `when`(mockEdit.putString(anyString(), anyString())).thenReturn(mockEdit) - - val mockedPrefs = mock(SharedPreferences::class.java) `when`(mockedPrefs.edit()).thenReturn(mockEdit) - - val mockedContext = mock(Context::class.java) `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) APIRequestStorage.saveData(mockedContext, "API_REQUEST", "1724258668") @@ -30,10 +50,7 @@ class APIRequestStorageTest { @Test fun testReadingDataAPIRequest() { - val mockedPrefs = mock(SharedPreferences::class.java) `when`(mockedPrefs.getString(anyString(), anyString())).thenReturn("1724258668") - - val mockedContext = mock(Context::class.java) `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) APIRequestStorage.readDataFrom(mockedContext, "API_REQUEST") From cdf2caf307ac476a83fc8382b49ec28356efdbf3 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 22 Aug 2024 11:45:59 -0300 Subject: [PATCH 26/46] Validating 15 minutes to call API again --- .../trustly/android/sdk/data/APIRequest.kt | 2 +- .../android/sdk/util/api/APIRequestManager.kt | 34 ++++++- .../android/sdk/views/TrustlyView.java | 40 ++++++--- .../sdk/util/api/APIRequestManagerTest.kt | 90 ++++++++++++++++--- .../sdk/util/api/APIRequestStorageTest.kt | 6 +- 5 files changed, 142 insertions(+), 30 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt index dc6bc62..cb16bb7 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt @@ -40,7 +40,7 @@ class APIRequest(private val apiInterface: APIMethod, private val settings: (Set //TODO Remove this method used to mock information private fun mockSettingsResult() { - val output = "{'settings': {'lightbox': {'context': 'web-view'}}}"; + val output = "{'settings': {'lightbox': {'context': 'in-app-browser'}}}" settings.invoke(Gson().fromJson(output, Settings::class.java)) } diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestManager.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestManager.kt index 0d4489f..0fc4cf0 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestManager.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestManager.kt @@ -1,22 +1,52 @@ package net.trustly.android.sdk.util.api import android.content.Context +import com.google.gson.Gson +import net.trustly.android.sdk.data.Settings import java.util.Calendar +import java.util.concurrent.TimeUnit object APIRequestManager { private const val API_REQUEST = "API_REQUEST" + private const val API_REQUEST_SETTINGS = "API_REQUEST_SETTINGS" + private const val EXPIRATION_TIME_LIMIT_MINUTES = 15 - fun saveAPIRequest(context: Context) { - APIRequestStorage.saveData(context, API_REQUEST, getTimestamp()) + fun validateAPIRequest(context: Context): Boolean { + val apiRequest = getAPIRequest(context) + if (apiRequest == null || !isValid(apiRequest)) { + APIRequestStorage.saveData(context, API_REQUEST, getTimestamp()) + return false + } + return true } fun getAPIRequest(context: Context): String? { return APIRequestStorage.readDataFrom(context, API_REQUEST) } + fun saveAPIRequestSettings(context: Context, settings: Settings) { + APIRequestStorage.saveData(context, API_REQUEST_SETTINGS, Gson().toJson(settings)) + } + + fun getAPIRequestSettings(context: Context): Settings { + return Gson().fromJson(APIRequestStorage.readDataFrom(context, API_REQUEST_SETTINGS), Settings::class.java) + } + private fun getTimestamp(): String { return Calendar.getInstance().timeInMillis.toString() } + private fun isValid(timestamp: String): Boolean { + val lastTime = Calendar.getInstance() + lastTime.timeInMillis = timestamp.toLong() + return minutesAgo(lastTime) < EXPIRATION_TIME_LIMIT_MINUTES + } + + private fun minutesAgo(datetime: Calendar): Int { + val now = Calendar.getInstance() + val differenceInMillis = now.timeInMillis - datetime.timeInMillis + return TimeUnit.MILLISECONDS.toMinutes(differenceInMillis).toInt() + } + } \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 78a0ae6..eeb82d4 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -23,12 +23,14 @@ import net.trustly.android.sdk.data.APIMethod; import net.trustly.android.sdk.data.APIRequest; import net.trustly.android.sdk.data.RetrofitInstance; +import net.trustly.android.sdk.data.Settings; import net.trustly.android.sdk.interfaces.Trustly; import net.trustly.android.sdk.interfaces.TrustlyCallback; import net.trustly.android.sdk.interfaces.TrustlyListener; -import net.trustly.android.sdk.util.cid.CidManager; import net.trustly.android.sdk.util.CustomTabsManager; import net.trustly.android.sdk.util.UrlUtils; +import net.trustly.android.sdk.util.api.APIRequestManager; +import net.trustly.android.sdk.util.cid.CidManager; import java.util.HashMap; import java.util.Map; @@ -351,25 +353,35 @@ public Trustly establish(Map establishData) { byte[] parameters = UrlUtils.getParameterString(data).getBytes("UTF-8"); - new APIRequest(apiInterface, settings -> { - if (settings.getSettings().getLightbox().getContext().equals("in-app-browser")) { - String jsonParameters = UrlUtils.getJsonFromParameters(data); - String encodedParameters = UrlUtils.encodeStringToBase64(jsonParameters); - CustomTabsManager.openCustomTabsIntent(getContext(), - getEndpointUrl("dynamic", establishData) + "accessId=" - + establishData.get("accessId") + "&token=" + encodedParameters - ); - } else { - webView.postUrl(getEndpointUrl("index", establishData), parameters); - } - return null; - }).getSettingsMockData(); + if (APIRequestManager.INSTANCE.validateAPIRequest(getContext())) { + Settings settings = APIRequestManager.INSTANCE.getAPIRequestSettings(getContext()); + openWebViewOrCustomTabs(settings, establishData, parameters); + } else { + new APIRequest(apiInterface, settings -> { + APIRequestManager.INSTANCE.saveAPIRequestSettings(getContext(), settings); + openWebViewOrCustomTabs(settings, establishData, parameters); + return null; + }).getSettingsMockData(); // }).getSettingsData(data.get("merchantId"), data.get("grp"), data.get("metadata.flowtype")); + } } catch (Exception e) { } return this; } + private void openWebViewOrCustomTabs(Settings settings, Map establishData, byte[] parameters) { + if (settings.getSettings().getLightbox().getContext().equals("in-app-browser")) { + String jsonParameters = UrlUtils.getJsonFromParameters(data); + String encodedParameters = UrlUtils.encodeStringToBase64(jsonParameters); + CustomTabsManager.openCustomTabsIntent(getContext(), + getEndpointUrl("dynamic", establishData) + "accessId=" + + establishData.get("accessId") + "&token=" + encodedParameters + ); + } else { + webView.postUrl(getEndpointUrl("index", establishData), parameters); + } + } + /** * {@inheritDoc} */ diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt index e662a6c..e7ed0c2 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt @@ -2,8 +2,12 @@ package net.trustly.android.sdk.util.api import android.content.Context import android.content.SharedPreferences +import com.google.gson.Gson +import net.trustly.android.sdk.data.Settings import org.junit.After import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.mockito.Mock @@ -15,12 +19,13 @@ import org.mockito.Mockito.mockStatic import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.`when` +import java.util.Calendar class APIRequestManagerTest { @Mock - lateinit var mockEdit: SharedPreferences.Editor + lateinit var mockedEdit: SharedPreferences.Editor @Mock lateinit var mockedPrefs: SharedPreferences @@ -28,41 +33,104 @@ class APIRequestManagerTest { @Mock lateinit var mockedContext: Context + @Mock + lateinit var mockedCalendar: Calendar + @Before fun setUp() { - mockEdit = mock(SharedPreferences.Editor::class.java) + mockedEdit = mock(SharedPreferences.Editor::class.java) mockedPrefs = mock(SharedPreferences::class.java) mockedContext = mock(Context::class.java) + mockedCalendar = mock(Calendar::class.java) } @After fun tearDown() { - clearInvocations(mockEdit, mockedContext, mockedPrefs) + clearInvocations(mockedEdit, mockedContext, mockedPrefs) + } + + @Test + fun testValidateAPIRequestReturnTrue() { + `when`(mockedEdit.putString(anyString(), anyString())).thenReturn(mockedEdit) + `when`(mockedPrefs.edit()).thenReturn(mockedEdit) + `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) + + mockStatic(Calendar::class.java, CALLS_REAL_METHODS).use { static -> + static.`when` { Calendar.getInstance() } + .thenReturn(mockedCalendar) + } + + mockStatic(APIRequestStorage::class.java, CALLS_REAL_METHODS).use { static -> + static.`when` { APIRequestStorage.readDataFrom(mockedContext, "API_REQUEST") } + .thenReturn("1724337021051") + } + + val validateAPIRequest = APIRequestManager.validateAPIRequest(mockedContext) + + assertTrue(validateAPIRequest) + } + + @Test + fun testValidateAPIRequestReturnFalse() { + `when`(mockedEdit.putString(anyString(), anyString())).thenReturn(mockedEdit) + `when`(mockedPrefs.edit()).thenReturn(mockedEdit) + `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) + + mockStatic(Calendar::class.java, CALLS_REAL_METHODS).use { static -> + static.`when` { Calendar.getInstance() } + .thenReturn(mockedCalendar) + } + + mockStatic(APIRequestStorage::class.java, CALLS_REAL_METHODS).use { static -> + static.`when` { APIRequestStorage.readDataFrom(mockedContext, "API_REQUEST") } + .thenReturn(null) + } + + val validateAPIRequest = APIRequestManager.validateAPIRequest(mockedContext) + + assertFalse(validateAPIRequest) } @Test fun testGettingDataAPIRequest() { `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) - `when`(mockedPrefs.getString(anyString(), anyString())).thenReturn("1724258668") mockStatic(APIRequestStorage::class.java, CALLS_REAL_METHODS).use { static -> static.`when` { APIRequestStorage.readDataFrom(mockedContext, "API_REQUEST") } - .thenReturn("13896438") + .thenReturn("1724258668") } val result = APIRequestManager.getAPIRequest(mockedContext) - assertEquals("13896438", result) + assertEquals("1724258668", result) } @Test - fun testSavingDataAPIRequest() { - `when`(mockEdit.putString(anyString(), anyString())).thenReturn(mockEdit) - `when`(mockedPrefs.edit()).thenReturn(mockEdit) + fun testGettingDataAPIRequestSettings() { + val output = getSettingsMockData() `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) - APIRequestManager.saveAPIRequest(mockedContext) + mockStatic(APIRequestStorage::class.java, CALLS_REAL_METHODS).use { static -> + static.`when` { APIRequestStorage.readDataFrom(mockedContext, "API_REQUEST_SETTINGS") } + .thenReturn(output) + } + + val settings = APIRequestManager.getAPIRequestSettings(mockedContext) + assertEquals("in-app-browser", settings.settings.lightbox.context) + } + + @Test + fun testSavingDataAPIRequestSettings() { + `when`(mockedEdit.putString(anyString(), anyString())).thenReturn(mockedEdit) + `when`(mockedPrefs.edit()).thenReturn(mockedEdit) + `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) - verify(mockEdit, times(1)).apply() + val settings = Gson().fromJson(getSettingsMockData(), Settings::class.java) + APIRequestManager.saveAPIRequestSettings(mockedContext, settings) + + verify(mockedEdit, times(1)).putString("API_REQUEST_SETTINGS", "{\"settings\":{\"lightbox\":{\"context\":\"in-app-browser\"}}}") + verify(mockedEdit, times(1)).apply() } + private fun getSettingsMockData() = "{\"settings\":{\"lightbox\":{\"context\":\"in-app-browser\"}}}" + } \ No newline at end of file diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestStorageTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestStorageTest.kt index cb7dc5d..9656c56 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestStorageTest.kt +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestStorageTest.kt @@ -3,6 +3,7 @@ package net.trustly.android.sdk.util.api import android.content.Context import android.content.SharedPreferences import org.junit.After +import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test import org.mockito.Mock @@ -49,13 +50,14 @@ class APIRequestStorageTest { } @Test - fun testReadingDataAPIRequest() { + fun testReadingDataNullAPIRequest() { `when`(mockedPrefs.getString(anyString(), anyString())).thenReturn("1724258668") `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) - APIRequestStorage.readDataFrom(mockedContext, "API_REQUEST") + val apiRequest = APIRequestStorage.readDataFrom(mockedContext, "API_REQUEST") verify(mockedPrefs, times(1)).getString("API_REQUEST", null) + assertEquals(null, apiRequest) } } \ No newline at end of file From 489adf132f395c1a1d7ca985a8ff611a7f6e5ccd Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 22 Aug 2024 11:58:33 -0300 Subject: [PATCH 27/46] Updating unit test --- .../trustly/android/sdk/util/api/APIRequestManagerTest.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt index e7ed0c2..34a14d3 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt @@ -55,6 +55,9 @@ class APIRequestManagerTest { `when`(mockedPrefs.edit()).thenReturn(mockedEdit) `when`(mockedContext.getSharedPreferences("API_STORAGE", Context.MODE_PRIVATE)).thenReturn(mockedPrefs) + val time = Calendar.getInstance().time + mockedCalendar.time = time + mockStatic(Calendar::class.java, CALLS_REAL_METHODS).use { static -> static.`when` { Calendar.getInstance() } .thenReturn(mockedCalendar) @@ -62,7 +65,7 @@ class APIRequestManagerTest { mockStatic(APIRequestStorage::class.java, CALLS_REAL_METHODS).use { static -> static.`when` { APIRequestStorage.readDataFrom(mockedContext, "API_REQUEST") } - .thenReturn("1724337021051") + .thenReturn(time.time.toString()) } val validateAPIRequest = APIRequestManager.validateAPIRequest(mockedContext) From d439792c532faa269cfdf70266a1367ba2b70590 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 22 Aug 2024 14:05:10 -0300 Subject: [PATCH 28/46] Updating readme file --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 601f8dc..cdcb475 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Java Version](https://badgen.net/badge/java/8/orange?icon=java)](https://www.oracle.com/java/technologies/javase/jdk8-naming.html) [![Platform](https://badgen.net/badge/Android/34/green?icon=java)](https://developer.android.com/about/versions/14) [![Gradle Plugin](https://badgen.net/badge/gradle/v8.0/green?icon=groovy)](https://gradle.org/whats-new/gradle-8) -[![Maven Central Version](https://badgen.net/badge/maven/v1.0.0/yellow?icon=java)](https://central.sonatype.com/artifact/net.trustly/android-sdk/3.2.2) +[![Maven Central Version](https://badgen.net/badge/maven/v1.0.0/yellow?icon=java)](https://central.sonatype.com/artifact/net.trustly/android-sdk/3.3.0) # Trustly Android SDK @@ -29,7 +29,7 @@ it, include the dependency below in your `build.gradle` file. ``` dependencies { - implementation 'net.trustly:trustly-android-sdk:3.2.2' + implementation 'net.trustly:trustly-android-sdk:3.3.0' } ``` @@ -42,6 +42,7 @@ ___ | VERSION | DESCRIPTION | BRANCH | | :-------: | :----------- | :----------- | +3.3.0 | Open WebView or Chrome Custom Tabs by remote configuration | *main* 3.2.2 | Update custom environment host mount | *main* 3.2.1 | Removing allow backup flag from Application | *main* 3.2.0 | Support for Android API 19 | *main* From aa1f2c5a0612bc13923bcc26b023e0c48166b475 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 22 Aug 2024 14:22:05 -0300 Subject: [PATCH 29/46] Changing api request parameter to establish in base64 --- .../java/net/trustly/android/sdk/data/APIMethod.kt | 4 +--- .../net/trustly/android/sdk/data/APIRequest.kt | 6 +++--- .../net/trustly/android/sdk/views/TrustlyView.java | 4 +++- .../net/trustly/android/sdk/data/APIRequestTest.kt | 14 +++++++------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt index f561f88..bfe8e61 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt @@ -9,9 +9,7 @@ interface APIMethod { //TODO Change this one with the correct endpoint @GET("api/v2/breeds") fun getSettings( - @Query("merchantId") merchantId: String, - @Query("grp") grp: String, - @Query("metadata.flowtype") flowType: String + @Query("establish") establish: String ): Call } \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt index cb16bb7..8f7893b 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt @@ -10,7 +10,7 @@ class APIRequest(private val apiInterface: APIMethod, private val settings: (Set //TODO Remove this method used to mock information fun getSettingsMockData() { - apiInterface.getSettings("", "", "").enqueue(object : Callback { + apiInterface.getSettings("").enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { if (response.isSuccessful && response.body() != null) { mockSettingsResult() @@ -23,8 +23,8 @@ class APIRequest(private val apiInterface: APIMethod, private val settings: (Set }) } - fun getSettingsData(merchantId: String, grp: String, flowType: String) { - apiInterface.getSettings(merchantId, grp, flowType).enqueue(object : Callback { + fun getSettingsData(establish: String) { + apiInterface.getSettings(establish).enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { if (response.isSuccessful && response.body() != null) { Log.d("APIRequestNew", response.body().toString()) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index eeb82d4..ba05f5f 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -362,7 +362,9 @@ public Trustly establish(Map establishData) { openWebViewOrCustomTabs(settings, establishData, parameters); return null; }).getSettingsMockData(); -// }).getSettingsData(data.get("merchantId"), data.get("grp"), data.get("metadata.flowtype")); +// }).getSettingsData( +// UrlUtils.encodeStringToBase64(UrlUtils.getJsonFromParameters(data)) +// ); } } catch (Exception e) { } diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt index 6703e61..dabb01f 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt @@ -30,12 +30,12 @@ class APIRequestTest { fun setup() { MockitoAnnotations.openMocks(this) - `when`(api.getSettings(anyString(), anyString(), anyString())).thenReturn(mockCall) + `when`(api.getSettings(anyString())).thenReturn(mockCall) } @After fun tearDown() { - api.getSettings("110005514", "1", "web-view").cancel() + api.getSettings("RXN0YWJsaXNoRGF0YVN0cmluZw==").cancel() mockCall.cancel() settingsResult = null } @@ -46,7 +46,7 @@ class APIRequestTest { val mockResponse = Response.success(settingsFake) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData("110005514", "1", "web-view") + APIRequest(api) { settingsResult = it }.getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") assertEquals(settingsFake, settingsResult) } @@ -57,7 +57,7 @@ class APIRequestTest { val mockResponse = Response.success(settingsFake) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData("110005514", "1", "web-view") + APIRequest(api) { settingsResult = it }.getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") assertEquals(settingsFake, settingsResult) assertEquals("in-app-browser", settingsResult!!.settings.lightbox.context) @@ -69,7 +69,7 @@ class APIRequestTest { val mockResponse = Response.success(settingsFake) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData("110005514", "1", "web-view") + APIRequest(api) { settingsResult = it }.getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") assertEquals(settingsFake, settingsResult) assertNotEquals("web-view", settingsResult!!.settings.lightbox.context) @@ -83,7 +83,7 @@ class APIRequestTest { ) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData("110005514", "1", "web-view") + APIRequest(api) { settingsResult = it }.getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") assertEquals(null, settingsResult) } @@ -96,7 +96,7 @@ class APIRequestTest { ) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData("110005514", "1", "web-view") + APIRequest(api) { settingsResult = it }.getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") assertEquals(null, settingsResult) } From 51151b8d0f6c1e5fad430f621f90e00a3a4fb6a0 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Fri, 23 Aug 2024 10:44:07 -0300 Subject: [PATCH 30/46] Changing parameter name --- .../src/main/java/net/trustly/android/sdk/data/APIMethod.kt | 2 +- .../src/main/java/net/trustly/android/sdk/data/APIRequest.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt index bfe8e61..1ad9fea 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt @@ -9,7 +9,7 @@ interface APIMethod { //TODO Change this one with the correct endpoint @GET("api/v2/breeds") fun getSettings( - @Query("establish") establish: String + @Query("token") token: String ): Call } \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt index 8f7893b..df47bde 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt @@ -23,8 +23,8 @@ class APIRequest(private val apiInterface: APIMethod, private val settings: (Set }) } - fun getSettingsData(establish: String) { - apiInterface.getSettings(establish).enqueue(object : Callback { + fun getSettingsData(token: String) { + apiInterface.getSettings(token).enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { if (response.isSuccessful && response.body() != null) { Log.d("APIRequestNew", response.body().toString()) From 90aa026d8deee0adcc16f53c3db273a6b380f0ea Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 3 Sep 2024 12:00:48 -0300 Subject: [PATCH 31/46] Show webview or CCT by integration strategy --- trustly-android-sdk/build.gradle | 1 + .../net/trustly/android/sdk/data/APIMethod.kt | 3 +- .../trustly/android/sdk/data/APIRequest.kt | 25 +----------- .../android/sdk/data/RetrofitInstance.kt | 15 ++++--- .../net/trustly/android/sdk/data/Settings.kt | 10 ++--- .../trustly/android/sdk/util/UrlUtils.java | 3 +- .../android/sdk/util/api/APIRequestManager.kt | 4 +- .../android/sdk/views/TrustlyView.java | 39 +++++++++++-------- .../android/sdk/data/APIRequestTest.kt | 24 ++++++------ .../android/sdk/data/RetrofitInstanceTest.kt | 6 +-- .../sdk/util/api/APIRequestManagerTest.kt | 6 +-- 11 files changed, 61 insertions(+), 75 deletions(-) diff --git a/trustly-android-sdk/build.gradle b/trustly-android-sdk/build.gradle index e540be6..5ec4404 100644 --- a/trustly-android-sdk/build.gradle +++ b/trustly-android-sdk/build.gradle @@ -49,6 +49,7 @@ dependencies { implementation 'androidx.core:core-ktx:1.13.1' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' + implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0' testImplementation 'junit:junit:4.13.2' testImplementation 'com.google.code.gson:gson:2.11.0' diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt index 1ad9fea..15cf3d1 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIMethod.kt @@ -6,8 +6,7 @@ import retrofit2.http.Query interface APIMethod { - //TODO Change this one with the correct endpoint - @GET("api/v2/breeds") + @GET("frontend/mobile/setup") fun getSettings( @Query("token") token: String ): Call diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt index df47bde..7577847 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/APIRequest.kt @@ -1,27 +1,11 @@ package net.trustly.android.sdk.data import android.util.Log -import com.google.gson.Gson import retrofit2.Call import retrofit2.Callback import retrofit2.Response -class APIRequest(private val apiInterface: APIMethod, private val settings: (Settings) -> Unit) { - - //TODO Remove this method used to mock information - fun getSettingsMockData() { - apiInterface.getSettings("").enqueue(object : Callback { - override fun onResponse(call: Call, response: Response) { - if (response.isSuccessful && response.body() != null) { - mockSettingsResult() - } - } - - override fun onFailure(call: Call, t: Throwable) { - mockSettingsResult() - } - }) - } +class APIRequest(private val apiInterface: APIMethod, private val settings: (Settings) -> Unit, private val error: (String) -> Unit) { fun getSettingsData(token: String) { apiInterface.getSettings(token).enqueue(object : Callback { @@ -34,14 +18,9 @@ class APIRequest(private val apiInterface: APIMethod, private val settings: (Set override fun onFailure(call: Call, t: Throwable) { Log.e("APIRequestNew", t.message.toString()) + error.invoke(t.message.toString()) } }) } - //TODO Remove this method used to mock information - private fun mockSettingsResult() { - val output = "{'settings': {'lightbox': {'context': 'in-app-browser'}}}" - settings.invoke(Gson().fromJson(output, Settings::class.java)) - } - } \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/RetrofitInstance.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/RetrofitInstance.kt index 6092e19..9ac3ba8 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/RetrofitInstance.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/RetrofitInstance.kt @@ -1,16 +1,21 @@ package net.trustly.android.sdk.data +import net.trustly.android.sdk.BuildConfig +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory -object RetrofitInstance { - //TODO Change this one with the correct endpoint - private const val BASE_URL = "https://dogapi.dog/" +object RetrofitInstance { - fun getInstance(): Retrofit { - return Retrofit.Builder().baseUrl(BASE_URL) + fun getInstance(baseUrl: String): Retrofit { + val interceptor = HttpLoggingInterceptor() + if (BuildConfig.DEBUG) interceptor.setLevel(HttpLoggingInterceptor.Level.BODY) + val okHttpClient = OkHttpClient.Builder().addInterceptor(interceptor).build() + return Retrofit.Builder().baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) + .client(okHttpClient) .build() } diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Settings.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Settings.kt index 30fc229..3408c81 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Settings.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/data/Settings.kt @@ -1,13 +1,9 @@ package net.trustly.android.sdk.data data class Settings( - val settings: LightBoxSetting + val settings: StrategySetting ) -data class LightBoxSetting( - val lightbox: LightBoxContext -) - -data class LightBoxContext( - val context: String +data class StrategySetting( + val integrationStrategy: String ) \ No newline at end of file diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java index 5ec4ba5..f87db4e 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/UrlUtils.java @@ -118,8 +118,7 @@ public static JSONObject buildJsonObject(Map data) throws JSONEx } public static String encodeStringToBase64(String value) { - byte[] encode = Base64.encode(value.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT); - return new String(encode, StandardCharsets.UTF_8); + return Base64.encodeToString(value.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT); } } diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestManager.kt b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestManager.kt index 0fc4cf0..e4f3507 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestManager.kt +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/api/APIRequestManager.kt @@ -3,6 +3,7 @@ package net.trustly.android.sdk.util.api import android.content.Context import com.google.gson.Gson import net.trustly.android.sdk.data.Settings +import net.trustly.android.sdk.data.StrategySetting import java.util.Calendar import java.util.concurrent.TimeUnit @@ -30,7 +31,8 @@ object APIRequestManager { } fun getAPIRequestSettings(context: Context): Settings { - return Gson().fromJson(APIRequestStorage.readDataFrom(context, API_REQUEST_SETTINGS), Settings::class.java) + val settings = Gson().fromJson(APIRequestStorage.readDataFrom(context, API_REQUEST_SETTINGS), Settings::class.java) + return settings ?: Settings(StrategySetting("webview")) } private fun getTimestamp(): String { diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index ba05f5f..7d34cae 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -7,6 +7,7 @@ import android.os.Build; import android.os.Message; import android.util.AttributeSet; +import android.util.Log; import android.view.ViewGroup; import android.webkit.WebChromeClient; import android.webkit.WebResourceError; @@ -24,6 +25,7 @@ import net.trustly.android.sdk.data.APIRequest; import net.trustly.android.sdk.data.RetrofitInstance; import net.trustly.android.sdk.data.Settings; +import net.trustly.android.sdk.data.StrategySetting; import net.trustly.android.sdk.interfaces.Trustly; import net.trustly.android.sdk.interfaces.TrustlyCallback; import net.trustly.android.sdk.interfaces.TrustlyListener; @@ -47,7 +49,6 @@ public class TrustlyView extends LinearLayout implements Trustly { static String DOMAIN = "paywithmybank.com"; static String version = BuildConfig.SDK_VERSION; private static boolean isLocalEnvironment = false; - APIMethod apiInterface = RetrofitInstance.INSTANCE.getInstance().create(APIMethod.class); enum Status { START, @@ -353,34 +354,38 @@ public Trustly establish(Map establishData) { byte[] parameters = UrlUtils.getParameterString(data).getBytes("UTF-8"); + String jsonFromParameters = UrlUtils.getJsonFromParameters(data); + String encodeStringToBase64 = UrlUtils.encodeStringToBase64(jsonFromParameters).replace("\n", ""); + if (APIRequestManager.INSTANCE.validateAPIRequest(getContext())) { Settings settings = APIRequestManager.INSTANCE.getAPIRequestSettings(getContext()); - openWebViewOrCustomTabs(settings, establishData, parameters); + openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); } else { + APIMethod apiInterface = RetrofitInstance.INSTANCE.getInstance(establishData.get("localUrl")).create(APIMethod.class); new APIRequest(apiInterface, settings -> { APIRequestManager.INSTANCE.saveAPIRequestSettings(getContext(), settings); - openWebViewOrCustomTabs(settings, establishData, parameters); + openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); + return null; + }, error -> { + openWebViewOrCustomTabs(new Settings(new StrategySetting("webview")), data, parameters, encodeStringToBase64); return null; - }).getSettingsMockData(); -// }).getSettingsData( -// UrlUtils.encodeStringToBase64(UrlUtils.getJsonFromParameters(data)) -// ); + }).getSettingsData(encodeStringToBase64); } } catch (Exception e) { + Log.e("TrustlyView", e.getMessage()); } return this; } - private void openWebViewOrCustomTabs(Settings settings, Map establishData, byte[] parameters) { - if (settings.getSettings().getLightbox().getContext().equals("in-app-browser")) { - String jsonParameters = UrlUtils.getJsonFromParameters(data); - String encodedParameters = UrlUtils.encodeStringToBase64(jsonParameters); - CustomTabsManager.openCustomTabsIntent(getContext(), - getEndpointUrl("dynamic", establishData) + "accessId=" - + establishData.get("accessId") + "&token=" + encodedParameters - ); + private void openWebViewOrCustomTabs(Settings settings, Map establishData, byte[] parameters, String encodedParameters) { + if (settings.getSettings().getIntegrationStrategy().equals("webview")) { + if (establishData.get("env").equals("dynamic")) { + webView.loadUrl(getEndpointUrl("dynamic", establishData) + "?token=" + encodedParameters); + } else { + webView.postUrl(getEndpointUrl("index", establishData), parameters); + } } else { - webView.postUrl(getEndpointUrl("index", establishData), parameters); + CustomTabsManager.openCustomTabsIntent(getContext(), getEndpointUrl("dynamic", establishData) + "?token=" + encodedParameters); } } @@ -522,7 +527,7 @@ public void notifyListener(String eventName, HashMap eventDetail */ protected String getEndpointUrl(String function, Map establishData) { if ("dynamic".equals(function)) { - return "http://" + establishData.get("localUrl") + "/start/app/establish?"; + return establishData.get("localUrl") + "/frontend/mobile/establish"; } String subDomain = establishData.get("env") != null diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt index dabb01f..5a1b1d9 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt @@ -1,8 +1,8 @@ package net.trustly.android.sdk.data import com.google.gson.Gson -import okhttp3.MediaType -import okhttp3.ResponseBody +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.ResponseBody.Companion.toResponseBody import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals @@ -46,7 +46,7 @@ class APIRequestTest { val mockResponse = Response.success(settingsFake) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") + APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") assertEquals(settingsFake, settingsResult) } @@ -57,10 +57,10 @@ class APIRequestTest { val mockResponse = Response.success(settingsFake) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") + APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") assertEquals(settingsFake, settingsResult) - assertEquals("in-app-browser", settingsResult!!.settings.lightbox.context) + assertEquals("webview", settingsResult!!.settings.integrationStrategy) } @Test @@ -69,21 +69,21 @@ class APIRequestTest { val mockResponse = Response.success(settingsFake) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") + APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") assertEquals(settingsFake, settingsResult) - assertNotEquals("web-view", settingsResult!!.settings.lightbox.context) + assertNotEquals("inappbrowser", settingsResult!!.settings.integrationStrategy) } @Test fun testGetSettingDataWhenReturnFailure() { val mockResponse = Response.error( 401, - ResponseBody.create(MediaType.parse("application/json"), "") + "".toResponseBody("application/json".toMediaTypeOrNull()) ) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") + APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") assertEquals(null, settingsResult) } @@ -92,11 +92,11 @@ class APIRequestTest { fun testGetSettingDataWhenReturnNetworkExceptionError() { val mockResponse = Response.error( 500, - ResponseBody.create(MediaType.parse("plain/text"), "API Not found") + "API Not found".toResponseBody("plain/text".toMediaTypeOrNull()) ) mockCallbackResponse(mockResponse) - APIRequest(api) { settingsResult = it }.getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") + APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") assertEquals(null, settingsResult) } @@ -112,6 +112,6 @@ class APIRequestTest { return Gson().fromJson(getSettingsJson(), Settings::class.java) } - private fun getSettingsJson() = "{'settings': {'lightbox': {'context': 'in-app-browser'}}}" + private fun getSettingsJson() = "{'settings': {'integrationStrategy': 'webview'}}" } \ No newline at end of file diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/RetrofitInstanceTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/RetrofitInstanceTest.kt index 28e29d7..147e107 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/RetrofitInstanceTest.kt +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/RetrofitInstanceTest.kt @@ -7,13 +7,13 @@ class RetrofitInstanceTest { @Test fun testRetrofitInstance() { - val instance = RetrofitInstance.getInstance() - assert(instance.baseUrl().toString() == "https://dogapi.dog/") + val instance = RetrofitInstance.getInstance("https://trustly.one/") + assert(instance.baseUrl().toString() == "https://trustly.one/") } @Test fun testRetrofitInstanceNotNull() { - val instance = RetrofitInstance.getInstance() + val instance = RetrofitInstance.getInstance("https://trustly.one/") assertNotNull(instance) } diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt index 34a14d3..6f2a18c 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/api/APIRequestManagerTest.kt @@ -118,7 +118,7 @@ class APIRequestManagerTest { } val settings = APIRequestManager.getAPIRequestSettings(mockedContext) - assertEquals("in-app-browser", settings.settings.lightbox.context) + assertEquals("webview", settings.settings.integrationStrategy) } @Test @@ -130,10 +130,10 @@ class APIRequestManagerTest { val settings = Gson().fromJson(getSettingsMockData(), Settings::class.java) APIRequestManager.saveAPIRequestSettings(mockedContext, settings) - verify(mockedEdit, times(1)).putString("API_REQUEST_SETTINGS", "{\"settings\":{\"lightbox\":{\"context\":\"in-app-browser\"}}}") + verify(mockedEdit, times(1)).putString("API_REQUEST_SETTINGS", "{\"settings\":{\"integrationStrategy\":\"webview\"}}") verify(mockedEdit, times(1)).apply() } - private fun getSettingsMockData() = "{\"settings\":{\"lightbox\":{\"context\":\"in-app-browser\"}}}" + private fun getSettingsMockData() = "{\"settings\":{\"integrationStrategy\":\"webview\"}}" } \ No newline at end of file From 63255fc6eb2575abdd51064180cfac8054c308c2 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Mon, 9 Sep 2024 15:34:52 -0300 Subject: [PATCH 32/46] Adding callbacks --- .../android/sdk/views/TrustlyView.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 7d34cae..6377ff4 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -40,6 +40,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import kotlin.Unit; + /** * TrustlyView is a view class that implements the Trustly SDK interface */ @@ -331,8 +333,14 @@ public Trustly establish(Map establishData) { } data.put("metadata.sdkAndroidVersion", version); data.put("deviceType", deviceType); - data.put("returnUrl", returnURL); - data.put("cancelUrl", cancelURL); + + if (data.get("env").equals("dynamic")) { + data.put("returnUrl", establishData.get("metadata.urlScheme")); + data.put("cancelUrl", establishData.get("metadata.urlScheme")); + } else { + data.put("returnUrl", returnURL); + data.put("cancelUrl", cancelURL); + } data.put("grp", Integer.toString(grp)); if (data.containsKey("paymentProviderId")) { @@ -362,14 +370,15 @@ public Trustly establish(Map establishData) { openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); } else { APIMethod apiInterface = RetrofitInstance.INSTANCE.getInstance(establishData.get("localUrl")).create(APIMethod.class); - new APIRequest(apiInterface, settings -> { + APIRequest apiRequest = new APIRequest(apiInterface, settings -> { APIRequestManager.INSTANCE.saveAPIRequestSettings(getContext(), settings); openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); - return null; - }, error -> { + return Unit.INSTANCE; + }, error -> { openWebViewOrCustomTabs(new Settings(new StrategySetting("webview")), data, parameters, encodeStringToBase64); - return null; - }).getSettingsData(encodeStringToBase64); + return Unit.INSTANCE; + }); + apiRequest.getSettingsData(encodeStringToBase64); } } catch (Exception e) { Log.e("TrustlyView", e.getMessage()); From 9a125dcc08c6868d1a3e2d6897e8971153d202d5 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 10 Sep 2024 15:32:56 -0300 Subject: [PATCH 33/46] Adding constant for TOKEN --- .../trustly/android/sdk/data/APIRequestTest.kt | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt index 5a1b1d9..9799f06 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/APIRequestTest.kt @@ -35,7 +35,7 @@ class APIRequestTest { @After fun tearDown() { - api.getSettings("RXN0YWJsaXNoRGF0YVN0cmluZw==").cancel() + api.getSettings(TOKEN).cancel() mockCall.cancel() settingsResult = null } @@ -46,7 +46,7 @@ class APIRequestTest { val mockResponse = Response.success(settingsFake) mockCallbackResponse(mockResponse) - APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") + APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData(TOKEN) assertEquals(settingsFake, settingsResult) } @@ -57,7 +57,7 @@ class APIRequestTest { val mockResponse = Response.success(settingsFake) mockCallbackResponse(mockResponse) - APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") + APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData(TOKEN) assertEquals(settingsFake, settingsResult) assertEquals("webview", settingsResult!!.settings.integrationStrategy) @@ -69,7 +69,7 @@ class APIRequestTest { val mockResponse = Response.success(settingsFake) mockCallbackResponse(mockResponse) - APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") + APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData(TOKEN) assertEquals(settingsFake, settingsResult) assertNotEquals("inappbrowser", settingsResult!!.settings.integrationStrategy) @@ -83,7 +83,7 @@ class APIRequestTest { ) mockCallbackResponse(mockResponse) - APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") + APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData(TOKEN) assertEquals(null, settingsResult) } @@ -96,7 +96,7 @@ class APIRequestTest { ) mockCallbackResponse(mockResponse) - APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData("RXN0YWJsaXNoRGF0YVN0cmluZw==") + APIRequest(api, { settingsResult = it }, { settingsResult = null }).getSettingsData(TOKEN) assertEquals(null, settingsResult) } @@ -114,4 +114,10 @@ class APIRequestTest { private fun getSettingsJson() = "{'settings': {'integrationStrategy': 'webview'}}" + companion object { + + const val TOKEN = "RXN0YWJsaXNoRGF0YVN0cmluZw==" + + } + } \ No newline at end of file From f96ec438068a9308fe6670717f59803776a99fab Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 10 Sep 2024 15:51:15 -0300 Subject: [PATCH 34/46] Changing from lint --- .../android/sdk/views/TrustlyView.java | 16 +++++++----- .../net/trustly/android/sdk/UrlUtilsTest.java | 26 +++++++++++-------- .../android/sdk/data/RetrofitInstanceTest.kt | 12 ++++++--- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 6377ff4..39a1ef6 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -34,6 +34,7 @@ import net.trustly.android.sdk.util.api.APIRequestManager; import net.trustly.android.sdk.util.cid.CidManager; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.Random; @@ -50,6 +51,9 @@ public class TrustlyView extends LinearLayout implements Trustly { static String PROTOCOL = "https://"; static String DOMAIN = "paywithmybank.com"; static String version = BuildConfig.SDK_VERSION; + + static String ENV_DYNAMIC = "dynamic"; + private static boolean isLocalEnvironment = false; enum Status { @@ -334,7 +338,7 @@ public Trustly establish(Map establishData) { data.put("metadata.sdkAndroidVersion", version); data.put("deviceType", deviceType); - if (data.get("env").equals("dynamic")) { + if (data.get("env").equals(ENV_DYNAMIC)) { data.put("returnUrl", establishData.get("metadata.urlScheme")); data.put("cancelUrl", establishData.get("metadata.urlScheme")); } else { @@ -360,7 +364,7 @@ public Trustly establish(Map establishData) { isLocalEnvironment = true; } - byte[] parameters = UrlUtils.getParameterString(data).getBytes("UTF-8"); + byte[] parameters = UrlUtils.getParameterString(data).getBytes(StandardCharsets.UTF_8); String jsonFromParameters = UrlUtils.getJsonFromParameters(data); String encodeStringToBase64 = UrlUtils.encodeStringToBase64(jsonFromParameters).replace("\n", ""); @@ -388,13 +392,13 @@ public Trustly establish(Map establishData) { private void openWebViewOrCustomTabs(Settings settings, Map establishData, byte[] parameters, String encodedParameters) { if (settings.getSettings().getIntegrationStrategy().equals("webview")) { - if (establishData.get("env").equals("dynamic")) { - webView.loadUrl(getEndpointUrl("dynamic", establishData) + "?token=" + encodedParameters); + if (establishData.get("env").equals(ENV_DYNAMIC)) { + webView.loadUrl(getEndpointUrl(ENV_DYNAMIC, establishData) + "?token=" + encodedParameters); } else { webView.postUrl(getEndpointUrl("index", establishData), parameters); } } else { - CustomTabsManager.openCustomTabsIntent(getContext(), getEndpointUrl("dynamic", establishData) + "?token=" + encodedParameters); + CustomTabsManager.openCustomTabsIntent(getContext(), getEndpointUrl(ENV_DYNAMIC, establishData) + "?token=" + encodedParameters); } } @@ -535,7 +539,7 @@ public void notifyListener(String eventName, HashMap eventDetail * {@inheritDoc} */ protected String getEndpointUrl(String function, Map establishData) { - if ("dynamic".equals(function)) { + if (ENV_DYNAMIC.equals(function)) { return establishData.get("localUrl") + "/frontend/mobile/establish"; } diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/UrlUtilsTest.java b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/UrlUtilsTest.java index d37a9b4..f2737ff 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/UrlUtilsTest.java +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/UrlUtilsTest.java @@ -12,6 +12,10 @@ public class UrlUtilsTest { + private static final String VALUE_1 = "value1"; + private static final String VALUE_2 = "value2"; + private static final String VALUE_3 = "value3"; + @Test(expected = Exception.class) public void shouldThrowExceptionWhenGetQueryParameterNamesReceiveNull() { UrlUtils.getQueryParameterNames(null); @@ -25,9 +29,9 @@ public void shouldThrowExceptionWhenGetParameterStringReceiveNull() { @Test public void shouldInvalidateReturnedValueWhenGetParameterString() { Map values = new HashMap<>(); - values.put("key1", "value1"); - values.put("key2", "value2"); - values.put("key3", "value3"); + values.put("key1", VALUE_1); + values.put("key2", VALUE_2); + values.put("key3", VALUE_3); String parameter = UrlUtils.getParameterString(values); assertNotEquals("key1=value1,key2=value2,key3=value3", parameter); } @@ -35,9 +39,9 @@ public void shouldInvalidateReturnedValueWhenGetParameterString() { @Test public void shouldValidateReturnedValueWhenGetParameterString() { Map values = new HashMap<>(); - values.put("key1", "value1"); - values.put("key2", "value2"); - values.put("key3", "value3"); + values.put("key1", VALUE_1); + values.put("key2", VALUE_2); + values.put("key3", VALUE_3); String parameter = UrlUtils.getParameterString(values); assertEquals("key1=value1&key2=value2&key3=value3", parameter); } @@ -45,9 +49,9 @@ public void shouldValidateReturnedValueWhenGetParameterString() { @Test public void shouldValidateReturnedValueWhenGetParameterStringWithNullKey() { Map values = new HashMap<>(); - values.put(null, "value1"); - values.put("key2", "value2"); - values.put("key3", "value3"); + values.put(null, VALUE_1); + values.put("key2", VALUE_2); + values.put("key3", VALUE_3); String parameter = UrlUtils.getParameterString(values); assertEquals("=value1&key2=value2&key3=value3", parameter); } @@ -55,9 +59,9 @@ public void shouldValidateReturnedValueWhenGetParameterStringWithNullKey() { @Test public void shouldValidateReturnedValueWhenGetParameterStringWithNullValue() { Map values = new HashMap<>(); - values.put("key1", "value1"); + values.put("key1", VALUE_1); values.put("key2", null); - values.put("key3", "value3"); + values.put("key3", VALUE_3); String parameter = UrlUtils.getParameterString(values); assertEquals("key1=value1&key2=&key3=value3", parameter); } diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/RetrofitInstanceTest.kt b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/RetrofitInstanceTest.kt index 147e107..aae73fa 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/RetrofitInstanceTest.kt +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/data/RetrofitInstanceTest.kt @@ -5,15 +5,21 @@ import org.junit.Test class RetrofitInstanceTest { + companion object { + + const val TEST_URL = "https://trustly.one/" + + } + @Test fun testRetrofitInstance() { - val instance = RetrofitInstance.getInstance("https://trustly.one/") - assert(instance.baseUrl().toString() == "https://trustly.one/") + val instance = RetrofitInstance.getInstance(TEST_URL) + assert(instance.baseUrl().toString() == TEST_URL) } @Test fun testRetrofitInstanceNotNull() { - val instance = RetrofitInstance.getInstance("https://trustly.one/") + val instance = RetrofitInstance.getInstance(TEST_URL) assertNotNull(instance) } From 86b413375507d0bcca9ff789cb35886728fc683e Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 10 Sep 2024 15:57:05 -0300 Subject: [PATCH 35/46] Changing from lint --- .../net/trustly/android/sdk/views/TrustlyView.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 39a1ef6..f187e4a 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -52,7 +52,7 @@ public class TrustlyView extends LinearLayout implements Trustly { static String DOMAIN = "paywithmybank.com"; static String version = BuildConfig.SDK_VERSION; - static String ENV_DYNAMIC = "dynamic"; + private static final String DYNAMIC = "dynamic"; private static boolean isLocalEnvironment = false; @@ -338,7 +338,7 @@ public Trustly establish(Map establishData) { data.put("metadata.sdkAndroidVersion", version); data.put("deviceType", deviceType); - if (data.get("env").equals(ENV_DYNAMIC)) { + if (data.get("env").equals(DYNAMIC)) { data.put("returnUrl", establishData.get("metadata.urlScheme")); data.put("cancelUrl", establishData.get("metadata.urlScheme")); } else { @@ -392,13 +392,13 @@ public Trustly establish(Map establishData) { private void openWebViewOrCustomTabs(Settings settings, Map establishData, byte[] parameters, String encodedParameters) { if (settings.getSettings().getIntegrationStrategy().equals("webview")) { - if (establishData.get("env").equals(ENV_DYNAMIC)) { - webView.loadUrl(getEndpointUrl(ENV_DYNAMIC, establishData) + "?token=" + encodedParameters); + if (establishData.get("env").equals(DYNAMIC)) { + webView.loadUrl(getEndpointUrl(DYNAMIC, establishData) + "?token=" + encodedParameters); } else { webView.postUrl(getEndpointUrl("index", establishData), parameters); } } else { - CustomTabsManager.openCustomTabsIntent(getContext(), getEndpointUrl(ENV_DYNAMIC, establishData) + "?token=" + encodedParameters); + CustomTabsManager.openCustomTabsIntent(getContext(), getEndpointUrl(DYNAMIC, establishData) + "?token=" + encodedParameters); } } @@ -539,7 +539,7 @@ public void notifyListener(String eventName, HashMap eventDetail * {@inheritDoc} */ protected String getEndpointUrl(String function, Map establishData) { - if (ENV_DYNAMIC.equals(function)) { + if (DYNAMIC.equals(function)) { return establishData.get("localUrl") + "/frontend/mobile/establish"; } From 814cc65ac4142a24f670332d4220622ddcbeeb6a Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Fri, 20 Sep 2024 15:35:18 -0300 Subject: [PATCH 36/46] Changing version name to DEV --- trustly-android-sdk/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trustly-android-sdk/build.gradle b/trustly-android-sdk/build.gradle index 5ec4404..387a28e 100644 --- a/trustly-android-sdk/build.gradle +++ b/trustly-android-sdk/build.gradle @@ -5,7 +5,7 @@ plugins { id 'org.jetbrains.kotlin.android' version '1.8.22' } -def sdkVersion = "3.3.0" +def sdkVersion = "3.3.1-dev" android { publishing { From 07ae19d2cda153c2aff5599f6957ae14eea2612b Mon Sep 17 00:00:00 2001 From: Renato DelPupo <16341269+renatodelpupo@users.noreply.github.com> Date: Wed, 25 Sep 2024 17:14:44 -0300 Subject: [PATCH 37/46] Add new constants --- .../java/net/trustly/android/sdk/views/TrustlyView.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index f187e4a..733962d 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -53,6 +53,8 @@ public class TrustlyView extends LinearLayout implements Trustly { static String version = BuildConfig.SDK_VERSION; private static final String DYNAMIC = "dynamic"; + private static final String INDEX = "index"; + private static final String LOCAL = "local"; private static boolean isLocalEnvironment = false; @@ -359,7 +361,7 @@ public Trustly establish(Map establishData) { notifyOpen(); - if ("local".equals(data.get("env"))) { + if (LOCAL.equals(data.get("env"))) { webView.setWebContentsDebuggingEnabled(true); isLocalEnvironment = true; } @@ -395,7 +397,7 @@ private void openWebViewOrCustomTabs(Settings settings, Map esta if (establishData.get("env").equals(DYNAMIC)) { webView.loadUrl(getEndpointUrl(DYNAMIC, establishData) + "?token=" + encodedParameters); } else { - webView.postUrl(getEndpointUrl("index", establishData), parameters); + webView.postUrl(getEndpointUrl(INDEX, establishData), parameters); } } else { CustomTabsManager.openCustomTabsIntent(getContext(), getEndpointUrl(DYNAMIC, establishData) + "?token=" + encodedParameters); @@ -555,7 +557,7 @@ protected String getEndpointUrl(String function, Map establishDa subDomain = subDomain + "."; } - if ("index".equals(function) && + if (INDEX.equals(function) && !"Verification".equals(establishData.get("paymentType")) && establishData.get("paymentProviderId") != null) { function = "selectBank"; From 660e32da3fdb5b89f285a219f956e0243a3c67d7 Mon Sep 17 00:00:00 2001 From: Renato DelPupo <16341269+renatodelpupo@users.noreply.github.com> Date: Wed, 25 Sep 2024 17:36:46 -0300 Subject: [PATCH 38/46] Refactor domain mount --- .../android/sdk/views/TrustlyView.java | 51 +++++++++++-------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 733962d..321709d 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -537,6 +537,35 @@ public void notifyListener(String eventName, HashMap eventDetail } } + private String getDomain(Map establishData) { + String environment = establishData.get("env") != null ? establishData.get("env").toLowerCase() : env; + String envHost = establishData.get("envHost"); + + if (environment == null) { + return PROTOCOL + DOMAIN; + } + + switch (environment) { + case DYNAMIC: { + String host = envHost != null ? envHost : ""; + return "https://" + host + ".int.trustly.one"; + } + case LOCAL: { + String host = (envHost != null && !envHost.equals("localhost")) ? envHost : "10.0.2.2"; + return "http://" + host + ":8000"; + } + case "prod": + case "production": + environment = ""; + break; + default: + environment = environment + "."; + break; + } + + return PROTOCOL + environment + DOMAIN; + } + /** * {@inheritDoc} */ @@ -545,17 +574,7 @@ protected String getEndpointUrl(String function, Map establishDa return establishData.get("localUrl") + "/frontend/mobile/establish"; } - String subDomain = establishData.get("env") != null - ? establishData.get("env").toLowerCase() - : env; - - String envHost = establishData.get("envHost"); - - if (subDomain == null || "prod".equals(subDomain) || "production".equals(subDomain)) { - subDomain = ""; - } else { - subDomain = subDomain + "."; - } + String domain = getDomain(establishData); if (INDEX.equals(function) && !"Verification".equals(establishData.get("paymentType")) && @@ -564,15 +583,7 @@ protected String getEndpointUrl(String function, Map establishDa } - if (subDomain.equals("local.")) { - String domain = (envHost != null && !envHost.equals("localhost")) ? envHost : "10.0.2.2"; - return "http://" + domain + ":8000/start/selectBank/" + function + "?v=" + version + "-android-sdk"; - } else if (subDomain.equals("dynamic.")) { - String host = envHost != null ? envHost : ""; - return "https://" + host + ".int.trustly.one/start/selectBank/" + function + "?v=" + version + "-android-sdk"; - } - - return PROTOCOL + subDomain + DOMAIN + "/start/selectBank/" + function + "?v=" + version + "-android-sdk"; + return domain + "/start/selectBank/" + function + "?v=" + version + "-android-sdk"; } private void notifyOpen() { From be986fde655b193c66e205f9e49016eef56e1430 Mon Sep 17 00:00:00 2001 From: Renato DelPupo <16341269+renatodelpupo@users.noreply.github.com> Date: Thu, 26 Sep 2024 15:43:58 -0300 Subject: [PATCH 39/46] Refactor mobile setup use case --- .../trustly/android/sdk/views/TrustlyView.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 321709d..1454fbc 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -55,6 +55,7 @@ public class TrustlyView extends LinearLayout implements Trustly { private static final String DYNAMIC = "dynamic"; private static final String INDEX = "index"; private static final String LOCAL = "local"; + private static final String MOBILE = "mobile"; private static boolean isLocalEnvironment = false; @@ -375,7 +376,7 @@ public Trustly establish(Map establishData) { Settings settings = APIRequestManager.INSTANCE.getAPIRequestSettings(getContext()); openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); } else { - APIMethod apiInterface = RetrofitInstance.INSTANCE.getInstance(establishData.get("localUrl")).create(APIMethod.class); + APIMethod apiInterface = RetrofitInstance.INSTANCE.getInstance(getDomain(establishData)).create(APIMethod.class); APIRequest apiRequest = new APIRequest(apiInterface, settings -> { APIRequestManager.INSTANCE.saveAPIRequestSettings(getContext(), settings); openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); @@ -395,12 +396,12 @@ public Trustly establish(Map establishData) { private void openWebViewOrCustomTabs(Settings settings, Map establishData, byte[] parameters, String encodedParameters) { if (settings.getSettings().getIntegrationStrategy().equals("webview")) { if (establishData.get("env").equals(DYNAMIC)) { - webView.loadUrl(getEndpointUrl(DYNAMIC, establishData) + "?token=" + encodedParameters); + webView.loadUrl(getEndpointUrl(MOBILE, establishData) + "?token=" + encodedParameters); } else { webView.postUrl(getEndpointUrl(INDEX, establishData), parameters); } } else { - CustomTabsManager.openCustomTabsIntent(getContext(), getEndpointUrl(DYNAMIC, establishData) + "?token=" + encodedParameters); + CustomTabsManager.openCustomTabsIntent(getContext(), getEndpointUrl(MOBILE, establishData) + "?token=" + encodedParameters); } } @@ -540,7 +541,7 @@ public void notifyListener(String eventName, HashMap eventDetail private String getDomain(Map establishData) { String environment = establishData.get("env") != null ? establishData.get("env").toLowerCase() : env; String envHost = establishData.get("envHost"); - + if (environment == null) { return PROTOCOL + DOMAIN; } @@ -570,12 +571,12 @@ private String getDomain(Map establishData) { * {@inheritDoc} */ protected String getEndpointUrl(String function, Map establishData) { - if (DYNAMIC.equals(function)) { - return establishData.get("localUrl") + "/frontend/mobile/establish"; - } - String domain = getDomain(establishData); + if (MOBILE.equals(function)) { + return domain + "/frontend/mobile/establish"; + } + if (INDEX.equals(function) && !"Verification".equals(establishData.get("paymentType")) && establishData.get("paymentProviderId") != null) { From 26fcfbef5cdc4b24c1bbe8378495915128717bbf Mon Sep 17 00:00:00 2001 From: Renato DelPupo <16341269+renatodelpupo@users.noreply.github.com> Date: Tue, 1 Oct 2024 16:05:15 -0300 Subject: [PATCH 40/46] Fix mobile flow local port --- .../android/sdk/views/TrustlyView.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 1454fbc..b5214cc 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -376,7 +376,7 @@ public Trustly establish(Map establishData) { Settings settings = APIRequestManager.INSTANCE.getAPIRequestSettings(getContext()); openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); } else { - APIMethod apiInterface = RetrofitInstance.INSTANCE.getInstance(getDomain(establishData)).create(APIMethod.class); + APIMethod apiInterface = RetrofitInstance.INSTANCE.getInstance(getDomain(MOBILE, establishData)).create(APIMethod.class); APIRequest apiRequest = new APIRequest(apiInterface, settings -> { APIRequestManager.INSTANCE.saveAPIRequestSettings(getContext(), settings); openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); @@ -538,7 +538,7 @@ public void notifyListener(String eventName, HashMap eventDetail } } - private String getDomain(Map establishData) { + private String getDomain(String function, Map establishData) { String environment = establishData.get("env") != null ? establishData.get("env").toLowerCase() : env; String envHost = establishData.get("envHost"); @@ -553,7 +553,16 @@ private String getDomain(Map establishData) { } case LOCAL: { String host = (envHost != null && !envHost.equals("localhost")) ? envHost : "10.0.2.2"; - return "http://" + host + ":8000"; + String port = ""; + String protocol = "http://"; + + if (function.equals("mobile")) { + port = ":10000"; + } else { + port = ":8000"; + } + + return protocol + host + port; } case "prod": case "production": @@ -571,10 +580,10 @@ private String getDomain(Map establishData) { * {@inheritDoc} */ protected String getEndpointUrl(String function, Map establishData) { - String domain = getDomain(establishData); + String domain = getDomain(function, establishData); if (MOBILE.equals(function)) { - return domain + "/frontend/mobile/establish"; + return domain + "/frontend/mobile/establish"; } if (INDEX.equals(function) && From 8fe11a41c8ed2bbe80be3744d97b334556a1d331 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 10 Oct 2024 15:36:48 -0300 Subject: [PATCH 41/46] Adding validation for normal flows --- .../android/sdk/views/TrustlyView.java | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index b5214cc..6726769 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -372,20 +372,24 @@ public Trustly establish(Map establishData) { String jsonFromParameters = UrlUtils.getJsonFromParameters(data); String encodeStringToBase64 = UrlUtils.encodeStringToBase64(jsonFromParameters).replace("\n", ""); - if (APIRequestManager.INSTANCE.validateAPIRequest(getContext())) { - Settings settings = APIRequestManager.INSTANCE.getAPIRequestSettings(getContext()); - openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); - } else { - APIMethod apiInterface = RetrofitInstance.INSTANCE.getInstance(getDomain(MOBILE, establishData)).create(APIMethod.class); - APIRequest apiRequest = new APIRequest(apiInterface, settings -> { - APIRequestManager.INSTANCE.saveAPIRequestSettings(getContext(), settings); + if (data.get("env").equals(DYNAMIC)) { + if (APIRequestManager.INSTANCE.validateAPIRequest(getContext())) { + Settings settings = APIRequestManager.INSTANCE.getAPIRequestSettings(getContext()); openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); - return Unit.INSTANCE; - }, error -> { - openWebViewOrCustomTabs(new Settings(new StrategySetting("webview")), data, parameters, encodeStringToBase64); - return Unit.INSTANCE; - }); - apiRequest.getSettingsData(encodeStringToBase64); + } else { + APIMethod apiInterface = RetrofitInstance.INSTANCE.getInstance(getDomain(MOBILE, establishData)).create(APIMethod.class); + APIRequest apiRequest = new APIRequest(apiInterface, settings -> { + APIRequestManager.INSTANCE.saveAPIRequestSettings(getContext(), settings); + openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); + return Unit.INSTANCE; + }, error -> { + openWebViewOrCustomTabs(new Settings(new StrategySetting("webview")), data, parameters, encodeStringToBase64); + return Unit.INSTANCE; + }); + apiRequest.getSettingsData(encodeStringToBase64); + } + } else { + webView.postUrl(getEndpointUrl(INDEX, data), parameters); } } catch (Exception e) { Log.e("TrustlyView", e.getMessage()); @@ -590,7 +594,6 @@ protected String getEndpointUrl(String function, Map establishDa !"Verification".equals(establishData.get("paymentType")) && establishData.get("paymentProviderId") != null) { function = "selectBank"; - } return domain + "/start/selectBank/" + function + "?v=" + version + "-android-sdk"; From b8b5c356d4a1f95a15febdb48e9373f483049f84 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 10 Oct 2024 16:22:27 -0300 Subject: [PATCH 42/46] Updating callbacks with urlScheme --- .../android/sdk/views/TrustlyView.java | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index 6726769..eee054d 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -340,14 +340,8 @@ public Trustly establish(Map establishData) { } data.put("metadata.sdkAndroidVersion", version); data.put("deviceType", deviceType); - - if (data.get("env").equals(DYNAMIC)) { - data.put("returnUrl", establishData.get("metadata.urlScheme")); - data.put("cancelUrl", establishData.get("metadata.urlScheme")); - } else { - data.put("returnUrl", returnURL); - data.put("cancelUrl", cancelURL); - } + data.put("returnUrl", returnURL); + data.put("cancelUrl", cancelURL); data.put("grp", Integer.toString(grp)); if (data.containsKey("paymentProviderId")) { @@ -368,9 +362,7 @@ public Trustly establish(Map establishData) { } byte[] parameters = UrlUtils.getParameterString(data).getBytes(StandardCharsets.UTF_8); - - String jsonFromParameters = UrlUtils.getJsonFromParameters(data); - String encodeStringToBase64 = UrlUtils.encodeStringToBase64(jsonFromParameters).replace("\n", ""); + String encodeStringToBase64 = getTokenByEncodedParameters(data); if (data.get("env").equals(DYNAMIC)) { if (APIRequestManager.INSTANCE.validateAPIRequest(getContext())) { @@ -405,10 +397,17 @@ private void openWebViewOrCustomTabs(Settings settings, Map esta webView.postUrl(getEndpointUrl(INDEX, establishData), parameters); } } else { - CustomTabsManager.openCustomTabsIntent(getContext(), getEndpointUrl(MOBILE, establishData) + "?token=" + encodedParameters); + data.put("returnUrl", establishData.get("metadata.urlScheme")); + data.put("cancelUrl", establishData.get("metadata.urlScheme")); + CustomTabsManager.openCustomTabsIntent(getContext(), getEndpointUrl(MOBILE, establishData) + "?token=" + getTokenByEncodedParameters(data)); } } + private String getTokenByEncodedParameters(Map data) { + String jsonFromParameters = UrlUtils.getJsonFromParameters(data); + return UrlUtils.encodeStringToBase64(jsonFromParameters).replace("\n", ""); + } + /** * {@inheritDoc} */ From 8ecb1af73d623e553a50e3b6e772e2954cd99d28 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Mon, 4 Nov 2024 18:29:09 -0300 Subject: [PATCH 43/46] Adding gradle property --- trustly-android-sdk/.DS_Store | Bin 8196 -> 8196 bytes trustly-android-sdk/build.gradle | 14 +++++++++----- .../android/sdk/views/TrustlyView.java | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/trustly-android-sdk/.DS_Store b/trustly-android-sdk/.DS_Store index 816eea50b9c67c212b8e3de7eaa1c15e1da498c1..fa2d372c2261c63d954362a1cfea8131777c9d9d 100644 GIT binary patch delta 41 xcmZp1XmOa}&nUbxU^hRb@MIo={>_^NL)kVqh%;_xm-xoASw!qJS|*H3mpYR6BDyq9ffL3BLf`;6JxX5T22m8Wqs?Q u`0SkAy!`IT>jmYddr%E43ogpb$ establishData) { return "https://" + host + ".int.trustly.one"; } case LOCAL: { - String host = (envHost != null && !envHost.equals("localhost")) ? envHost : "10.0.2.2"; + String host = (envHost != null && !envHost.equals("localhost")) ? envHost : BuildConfig.LOCAL_IP; String port = ""; String protocol = "http://"; From 03fdb1023d663bb240ce3d2dfe1d93fde87d2031 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Mon, 4 Nov 2024 18:37:56 -0300 Subject: [PATCH 44/46] Solving some code smells --- .../net/trustly/android/sdk/views/TrustlyView.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index a33ed53..b6cb1b4 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -56,6 +56,7 @@ public class TrustlyView extends LinearLayout implements Trustly { private static final String INDEX = "index"; private static final String LOCAL = "local"; private static final String MOBILE = "mobile"; + private static final String PAYMENT_PROVIDER_ID = "paymentProviderId"; private static boolean isLocalEnvironment = false; @@ -289,9 +290,9 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { switch (params[0]) { case "PayWithMyBank.createTransaction": if (params.length > 1) { - data.put("paymentProviderId", params[1]); + data.put(PAYMENT_PROVIDER_ID, params[1]); } else { - data.put("paymentProviderId", ""); + data.put(PAYMENT_PROVIDER_ID, ""); } if (onWidgetBankSelected != null) { @@ -344,7 +345,7 @@ public Trustly establish(Map establishData) { data.put("cancelUrl", cancelURL); data.put("grp", Integer.toString(grp)); - if (data.containsKey("paymentProviderId")) { + if (data.containsKey(PAYMENT_PROVIDER_ID)) { data.put("widgetLoaded", "true"); } @@ -559,7 +560,7 @@ private String getDomain(String function, Map establishData) { String port = ""; String protocol = "http://"; - if (function.equals("mobile")) { + if (MOBILE.equals(function)) { port = ":10000"; } else { port = ":8000"; @@ -591,7 +592,7 @@ protected String getEndpointUrl(String function, Map establishDa if (INDEX.equals(function) && !"Verification".equals(establishData.get("paymentType")) && - establishData.get("paymentProviderId") != null) { + establishData.get(PAYMENT_PROVIDER_ID) != null) { function = "selectBank"; } From e2b27fb08e1a6435970ce9a28beaec4b8ccd1df7 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Wed, 27 Nov 2024 16:22:31 -0300 Subject: [PATCH 45/46] Adding integration context to webview flow --- .../android/sdk/views/TrustlyView.java | 47 +++++++------------ 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java index b6cb1b4..ed8b455 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/views/TrustlyView.java @@ -335,10 +335,6 @@ public Trustly establish(Map establishData) { String lang = establishData.get("metadata.lang"); if (lang != null) data.put("lang", lang); - String integrationContext = establishData.get("metadata.integrationContext"); - if (integrationContext == null || integrationContext.isEmpty()) { - data.put("metadata.integrationContext", "InAppBrowser"); - } data.put("metadata.sdkAndroidVersion", version); data.put("deviceType", deviceType); data.put("returnUrl", returnURL); @@ -362,27 +358,20 @@ public Trustly establish(Map establishData) { isLocalEnvironment = true; } - byte[] parameters = UrlUtils.getParameterString(data).getBytes(StandardCharsets.UTF_8); - String encodeStringToBase64 = getTokenByEncodedParameters(data); - - if (data.get("env").equals(DYNAMIC)) { - if (APIRequestManager.INSTANCE.validateAPIRequest(getContext())) { - Settings settings = APIRequestManager.INSTANCE.getAPIRequestSettings(getContext()); - openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); - } else { - APIMethod apiInterface = RetrofitInstance.INSTANCE.getInstance(getDomain(MOBILE, establishData)).create(APIMethod.class); - APIRequest apiRequest = new APIRequest(apiInterface, settings -> { - APIRequestManager.INSTANCE.saveAPIRequestSettings(getContext(), settings); - openWebViewOrCustomTabs(settings, data, parameters, encodeStringToBase64); - return Unit.INSTANCE; - }, error -> { - openWebViewOrCustomTabs(new Settings(new StrategySetting("webview")), data, parameters, encodeStringToBase64); - return Unit.INSTANCE; - }); - apiRequest.getSettingsData(encodeStringToBase64); - } + if (APIRequestManager.INSTANCE.validateAPIRequest(getContext())) { + Settings settings = APIRequestManager.INSTANCE.getAPIRequestSettings(getContext()); + openWebViewOrCustomTabs(settings, data); } else { - webView.postUrl(getEndpointUrl(INDEX, data), parameters); + APIMethod apiInterface = RetrofitInstance.INSTANCE.getInstance(getDomain(MOBILE, establishData)).create(APIMethod.class); + APIRequest apiRequest = new APIRequest(apiInterface, settings -> { + APIRequestManager.INSTANCE.saveAPIRequestSettings(getContext(), settings); + openWebViewOrCustomTabs(settings, data); + return Unit.INSTANCE; + }, error -> { + openWebViewOrCustomTabs(new Settings(new StrategySetting("webview")), data); + return Unit.INSTANCE; + }); + apiRequest.getSettingsData(getTokenByEncodedParameters(data)); } } catch (Exception e) { Log.e("TrustlyView", e.getMessage()); @@ -390,13 +379,11 @@ public Trustly establish(Map establishData) { return this; } - private void openWebViewOrCustomTabs(Settings settings, Map establishData, byte[] parameters, String encodedParameters) { + private void openWebViewOrCustomTabs(Settings settings, Map establishData) { if (settings.getSettings().getIntegrationStrategy().equals("webview")) { - if (establishData.get("env").equals(DYNAMIC)) { - webView.loadUrl(getEndpointUrl(MOBILE, establishData) + "?token=" + encodedParameters); - } else { - webView.postUrl(getEndpointUrl(INDEX, establishData), parameters); - } + data.put("metadata.integrationContext", "InAppBrowser"); + byte[] encodedParameters = UrlUtils.getParameterString(data).getBytes(StandardCharsets.UTF_8); + webView.postUrl(getEndpointUrl(INDEX, establishData), encodedParameters); } else { data.put("returnUrl", establishData.get("metadata.urlScheme")); data.put("cancelUrl", establishData.get("metadata.urlScheme")); From 596a20f1b37635a629f0ec2a6fd5828e8b6cc175 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 28 Nov 2024 17:00:46 -0300 Subject: [PATCH 46/46] Changes from code smells --- .../java/net/trustly/android/sdk/util/cid/CidManager.java | 2 +- .../java/net/trustly/android/sdk/util/cid/CidStorage.java | 2 +- .../java/net/trustly/android/sdk/util/CidManagerTest.java | 7 ------- .../java/net/trustly/android/sdk/util/CidStorageTest.java | 7 ------- 4 files changed, 2 insertions(+), 16 deletions(-) diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidManager.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidManager.java index 07ac180..55d839f 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidManager.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidManager.java @@ -17,7 +17,7 @@ public class CidManager { public static final String SESSION_CID_PARAM = "SESSION_CID"; private static final String DIVIDER = "-"; - public CidManager() { + private CidManager() { throw new IllegalStateException("Utility class cannot be instantiated"); } diff --git a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidStorage.java b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidStorage.java index 98b4c29..6ffffd0 100644 --- a/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidStorage.java +++ b/trustly-android-sdk/src/main/java/net/trustly/android/sdk/util/cid/CidStorage.java @@ -9,7 +9,7 @@ public class CidStorage { public static final String SESSION_CID = "SESSION_CID"; public static final String CID = "CID"; - public CidStorage() { + private CidStorage() { throw new IllegalStateException("Utility class cannot be instantiated"); } diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/CidManagerTest.java b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/CidManagerTest.java index b6dd33e..724ebb3 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/CidManagerTest.java +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/CidManagerTest.java @@ -2,7 +2,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.CALLS_REAL_METHODS; @@ -74,12 +73,6 @@ public void tearDown() { clearInvocations(mockSharedPreferencesEditor, mockSharedPreferences, mockContext, mockCalendar); } - @Test - public void shouldThrowExceptionWhenCidManagerInstanceIsCalled() { - Throwable exception = assertThrows(IllegalStateException.class, CidManager::new); - assertEquals("Utility class cannot be instantiated", exception.getMessage()); - } - @Test public void shouldValidateCidManagerGenerateCIDMethod() { Date timeNow = Calendar.getInstance().getTime(); diff --git a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/CidStorageTest.java b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/CidStorageTest.java index f1e0b01..9a398a2 100644 --- a/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/CidStorageTest.java +++ b/trustly-android-sdk/src/test/java/net/trustly/android/sdk/util/CidStorageTest.java @@ -2,7 +2,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; @@ -49,12 +48,6 @@ public void tearDown() { clearInvocations(mockSharedPreferencesEditor, mockSharedPreferences, mockContext); } - @Test - public void shouldThrowExceptionWhenCidStorageInstanceIsCalled() { - Throwable exception = assertThrows(IllegalStateException.class, CidStorage::new); - assertEquals("Utility class cannot be instantiated", exception.getMessage()); - } - @Test public void shouldValidateCidStorageSaveDataMethod() { when(mockSharedPreferencesEditor.putString(anyString(), anyString())).thenReturn(mockSharedPreferencesEditor);