diff --git a/WordPress/build.gradle b/WordPress/build.gradle index e3f33b5c6cf4..03965e2df258 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -44,6 +44,7 @@ repositories { includeGroupByRegex "org.wordpress.react-native-libraries.*" includeGroup "com.automattic" includeGroup "com.automattic.tracks" + includeGroup "com.gravatar" } } maven { @@ -388,6 +389,7 @@ dependencies { exclude group: 'com.mcxiaoke.volley' } implementation "org.wordpress:persistentedittext:$wordPressPersistentEditTextVersion" + implementation "$gradle.ext.gravatarBinaryPath:$gravatarVersion" implementation "androidx.arch.core:core-common:$androidxArchCoreVersion" implementation "androidx.arch.core:core-runtime:$androidxArchCoreVersion" @@ -438,7 +440,6 @@ dependencies { implementation "com.github.chrisbanes:PhotoView:$chrisbanesPhotoviewVersion" implementation "org.greenrobot:eventbus:$eventBusVersion" implementation "org.greenrobot:eventbus-java:$eventBusVersion" - implementation "com.squareup.okio:okio:$squareupOkioVersion" implementation "com.squareup.retrofit2:retrofit:$squareupRetrofitVersion" implementation "org.apache.commons:commons-text:$apacheCommonsTextVersion" implementation "com.airbnb.android:lottie:$lottieVersion" diff --git a/WordPress/src/androidTest/java/org/wordpress/android/networking/GravatarApiTest.java b/WordPress/src/androidTest/java/org/wordpress/android/networking/GravatarApiTest.java deleted file mode 100644 index 762b808321f9..000000000000 --- a/WordPress/src/androidTest/java/org/wordpress/android/networking/GravatarApiTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.wordpress.android.networking; - -import android.content.Context; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; - -import javax.inject.Inject; - -import static junit.framework.TestCase.assertEquals; -import static junit.framework.TestCase.assertTrue; - -import dagger.hilt.android.testing.HiltAndroidRule; -import dagger.hilt.android.testing.HiltAndroidTest; -import okhttp3.Request; -import okhttp3.RequestBody; -import okio.Buffer; - -@HiltAndroidTest -public class GravatarApiTest { - @Rule - public HiltAndroidRule hiltRule = new HiltAndroidRule(this); - - @Inject Context mContext; - - @Before - public void setUp() { - hiltRule.inject(); - } - - @Test - public void testGravatarUploadRequest() throws IOException { - final String fileContent = "abcdefg"; - - File tempFile = new File(mContext.getCacheDir(), "tempFile.jpg"); - FileOutputStream fos = new FileOutputStream(tempFile); - fos.write(fileContent.getBytes()); - fos.flush(); - fos.close(); - - final String email = "a@b.com"; - Request uploadRequest = GravatarApi.prepareGravatarUpload(email, tempFile); - - assertEquals("POST", uploadRequest.method()); - - RequestBody requestBody = uploadRequest.body(); - assertTrue(requestBody.contentType().toString().startsWith("multipart/form-data")); - - final Buffer buffer = new Buffer(); - requestBody.writeTo(buffer); - final String body = buffer.readUtf8(); - - assertTrue(body.contains("Content-Disposition: form-data; name=\"account\"")); - assertTrue(body.contains("Content-Length: " + email.length())); - assertTrue(body.contains(email)); - - assertTrue(body.contains( - "Content-Disposition: form-data; name=\"filedata\"; filename=\"" + tempFile.getName() + "\"")); - assertTrue(body.contains("Content-Type: multipart/form-data")); - assertTrue(body.contains(fileContent)); - } -} diff --git a/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtilsTest.kt b/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtilsTest.kt new file mode 100644 index 000000000000..24cf7d8f9951 --- /dev/null +++ b/WordPress/src/androidTest/java/org/wordpress/android/util/WPAvatarUtilsTest.kt @@ -0,0 +1,43 @@ +package org.wordpress.android.util + +import com.gravatar.DefaultAvatarOption +import dagger.hilt.android.testing.HiltAndroidTest +import junit.framework.TestCase.assertEquals +import org.junit.Test + +@HiltAndroidTest +class WPAvatarUtilsTest { + @Test + fun rewriteAvatarUrlReplaceNonGravatarUrlToPhotonUrl() { + assertEquals( + "https://i0.wp.com/example.com/image.jpg?strip=info&quality=65&resize=100,100&ssl=1", + WPAvatarUtils.rewriteAvatarUrl("https://example.com/image.jpg", 100) + ) + } + + @Test + fun rewriteAvatarUrlDropQueryParamsFromGravatarUrlAndAddDefaults() { + assertEquals( + "https://www.gravatar.com/avatar/" + + "31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66?d=mp&s=100", + WPAvatarUtils.rewriteAvatarUrl( + "https://www.gravatar.com/avatar/" + + "31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66?d=wavatar&s=1000", + 100 + ) + ) + } + + @Test + fun rewriteAvatarUrlAddDefaultsToGravatarUrl() { + assertEquals( + "https://www.gravatar.com/avatar/" + + "31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66?d=404&s=200", + WPAvatarUtils.rewriteAvatarUrl( + "https://www.gravatar.com/avatar/" + + "31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66", + 200, DefaultAvatarOption.Status404 + ) + ) + } +} diff --git a/WordPress/src/jetpack/assets/licenses.html b/WordPress/src/jetpack/assets/licenses.html index 2164dddc6107..cece0d1c64b8 100644 --- a/WordPress/src/jetpack/assets/licenses.html +++ b/WordPress/src/jetpack/assets/licenses.html @@ -31,7 +31,6 @@
+ * see https://docs.gravatar.com/general/images/
+ */
+public class WPAvatarUtils {
+ private WPAvatarUtils() {
+ throw new IllegalStateException("Utility class");
+ }
+ public static final DefaultAvatarOption DEFAULT_AVATAR = MysteryPerson.INSTANCE;
+
+ /**
+ * Remove all query params from a gravatar url and set them to the given size and
+ * default image. If the imageUrl parameters is not a gravatar link,
+ * then use Photon to resize according to the avatarSz parameter.
+ *
+ * @param imageUrl the url of the avatar image
+ * @param avatarSz the size of the avatar image
+ * @param defaultImage the default image to use if the user doesn't have a gravatar
+ * @return the fixed url
+ */
+ public static String rewriteAvatarUrl(@NonNull final String imageUrl, int avatarSz,
+ @Nullable DefaultAvatarOption defaultImage) {
+ if (TextUtils.isEmpty(imageUrl)) {
+ return "";
+ }
+
+ // if this isn't a gravatar image, return as resized photon image url
+ if (!imageUrl.contains("gravatar.com")) {
+ return PhotonUtils.getPhotonImageUrl(imageUrl, avatarSz, avatarSz);
+ } else {
+ try {
+ return new AvatarUrl(new URL(imageUrl),
+ new AvatarQueryOptions(avatarSz, defaultImage, null, null)).url().toString();
+ } catch (MalformedURLException e) {
+ return "";
+ }
+ }
+ }
+
+ public static String rewriteAvatarUrl(@NonNull final String imageUrl, int avatarSz) {
+ return rewriteAvatarUrl(imageUrl, avatarSz, DEFAULT_AVATAR);
+ }
+}
diff --git a/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtilsWrapper.kt b/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtilsWrapper.kt
new file mode 100644
index 000000000000..493cfcf30fc1
--- /dev/null
+++ b/WordPress/src/main/java/org/wordpress/android/util/WPAvatarUtilsWrapper.kt
@@ -0,0 +1,24 @@
+package org.wordpress.android.util
+
+import android.content.Context
+import androidx.annotation.DimenRes
+import dagger.Reusable
+import javax.inject.Inject
+
+/**
+ * Injectable wrapper around GravatarUtils.
+ *
+ * WordPressAvatarUtils interface is consisted of static methods, which makes the client code difficult to test/mock.
+ * Main purpose of this wrapper is to make testing easier.
+ */
+@Reusable
+class WPAvatarUtilsWrapper @Inject constructor(private val appContext: Context) {
+ fun rewriteAvatarUrl(imageUrl: String, avatarSz: Int): String {
+ return WPAvatarUtils.rewriteAvatarUrl(imageUrl, avatarSz)
+ }
+
+ fun rewriteAvatarUrlWithResource(imageUrl: String, @DimenRes avatarSzRes: Int): String {
+ return WPAvatarUtils.rewriteAvatarUrl(imageUrl,
+ appContext.resources.getDimensionPixelSize(avatarSzRes))
+ }
+}
diff --git a/WordPress/src/test/java/org/wordpress/android/ui/main/jetpack/migration/JetpackMigrationViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/main/jetpack/migration/JetpackMigrationViewModelTest.kt
index 984812bf8e71..6e33aee504e3 100644
--- a/WordPress/src/test/java/org/wordpress/android/ui/main/jetpack/migration/JetpackMigrationViewModelTest.kt
+++ b/WordPress/src/test/java/org/wordpress/android/ui/main/jetpack/migration/JetpackMigrationViewModelTest.kt
@@ -40,7 +40,7 @@ import org.wordpress.android.ui.main.jetpack.migration.JetpackMigrationViewModel
import org.wordpress.android.ui.main.jetpack.migration.JetpackMigrationViewModel.UiState.Loading
import org.wordpress.android.ui.prefs.AppPrefsWrapper
import org.wordpress.android.ui.utils.UiString.UiStringRes
-import org.wordpress.android.util.GravatarUtilsWrapper
+import org.wordpress.android.util.WPAvatarUtilsWrapper
import org.wordpress.android.util.JetpackMigrationLanguageUtil
import org.wordpress.android.util.LocaleManagerWrapper
import org.wordpress.android.util.SiteUtilsWrapper
@@ -54,7 +54,7 @@ class JetpackMigrationViewModelTest : BaseUnitTest() {
private val refreshAppThemeObserver: Observer1. [JP/WP] Me Screen [GravatarApi.java + StreamingRequest.java]
-
-- Go to `Me` tab.
-- From the `Me` screen you are in, click on your profile's icon (`CHANGE PHOTO`).
-- Choose an image and wait for the `Edit Photo` screen to appear.
-- Crop the image and click the `done` menu option (top right).
-- Verify the image is updated accordingly.
-
-