From c98f4567440e365aac9721620edac1612eb15def Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Mon, 2 Mar 2020 09:54:58 +0300 Subject: [PATCH] LinkResolverDef defaults to https when no scheme is available --- CHANGELOG.md | 1 + .../io/noties/markwon/LinkResolverDef.java | 21 ++++- .../noties/markwon/LinkResolverDefTest.java | 79 +++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 markwon-core/src/test/java/io/noties/markwon/LinkResolverDefTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index ca948871..64de0ca5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * `JLatexMathPlugin`: add `theme` (to customize both inlines and blocks) * `JLatexMathPlugin`: add `renderMode` to use previous (pre `4.3.0`) LaTeX rendering * add `SoftBreakAddsNewLinePlugin` plugin (`core` module) +* `LinkResolverDef` defaults to `https` when a link does not have scheme information # 4.2.2 diff --git a/markwon-core/src/main/java/io/noties/markwon/LinkResolverDef.java b/markwon-core/src/main/java/io/noties/markwon/LinkResolverDef.java index f61ad21f..44c5da9c 100644 --- a/markwon-core/src/main/java/io/noties/markwon/LinkResolverDef.java +++ b/markwon-core/src/main/java/io/noties/markwon/LinkResolverDef.java @@ -5,15 +5,20 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.provider.Browser; +import android.text.TextUtils; import android.util.Log; import android.view.View; import androidx.annotation.NonNull; public class LinkResolverDef implements LinkResolver { + + // @since 4.3.0-SNAPSHOT + private static final String DEFAULT_SCHEME = "https"; + @Override public void resolve(@NonNull View view, @NonNull String link) { - final Uri uri = Uri.parse(link); + final Uri uri = parseLink(link); final Context context = view.getContext(); final Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()); @@ -23,4 +28,18 @@ public class LinkResolverDef implements LinkResolver { Log.w("LinkResolverDef", "Actvity was not found for the link: '" + link + "'"); } } + + /** + * @since 4.3.0-SNAPSHOT + */ + @NonNull + private static Uri parseLink(@NonNull String link) { + final Uri uri = Uri.parse(link); + if (TextUtils.isEmpty(uri.getScheme())) { + return uri.buildUpon() + .scheme(DEFAULT_SCHEME) + .build(); + } + return uri; + } } diff --git a/markwon-core/src/test/java/io/noties/markwon/LinkResolverDefTest.java b/markwon-core/src/test/java/io/noties/markwon/LinkResolverDefTest.java new file mode 100644 index 00000000..eb19d933 --- /dev/null +++ b/markwon-core/src/test/java/io/noties/markwon/LinkResolverDefTest.java @@ -0,0 +1,79 @@ +package io.noties.markwon; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.view.View; + +import androidx.annotation.NonNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class LinkResolverDefTest { + + @Test + public void no_scheme_https() { + // when supplied url doesn't have scheme fallback to `https` + + // must be => `https://www.markw.on + final String link = "www.markw.on"; + + final Uri uri = resolve(link); + + final String scheme = uri.getScheme(); + assertNotNull(uri.toString(), scheme); + + assertEquals(uri.toString(), "https", scheme); + } + + @Test + public void scheme_present() { + // when scheme is present, it won't be touched + + final String link = "whatnot://hey/ho"; + + final Uri uri = resolve(link); + + final String scheme = uri.getScheme(); + assertEquals(uri.toString(), "whatnot", scheme); + + assertEquals(Uri.parse(link), uri); + } + + // we could call `parseLink` directly, but this doesn't mean LinkResolverDef uses it + @NonNull + private Uri resolve(@NonNull String link) { + final View view = mock(View.class); + final Context context = mock(Context.class); + when(view.getContext()).thenReturn(context); + + final LinkResolverDef def = new LinkResolverDef(); + def.resolve(view, link); + + final ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); + + verify(context, times(1)) + .startActivity(captor.capture()); + + final Intent intent = captor.getValue(); + assertNotNull(intent); + + final Uri uri = intent.getData(); + assertNotNull(uri); + + return uri; + } +} \ No newline at end of file