diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/PostUtils.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/PostUtils.java index 7e2172df94a5..65922b791961 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/PostUtils.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/PostUtils.java @@ -444,8 +444,8 @@ public static String replaceMediaFileWithUrlInGutenbergPost(@NonNull String post public static boolean isMediaInGutenbergPostBody(@NonNull String postContent, String localMediaId) { List patterns = new ArrayList<>(); - // Regex for Image, Video, and File blocks - patterns.add(""); + // Regex for Image, Video, Audio and File blocks + patterns.add(""); // Regex for Media&Text block patterns.add(""); // Regex for Gallery block diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/AudioBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/AudioBlockProcessor.kt new file mode 100644 index 000000000000..679f3a92f939 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/AudioBlockProcessor.kt @@ -0,0 +1,39 @@ +package org.wordpress.android.ui.posts.mediauploadcompletionprocessors + +import com.google.gson.JsonObject +import org.jsoup.nodes.Document +import org.wordpress.android.util.helpers.MediaFile + +class AudioBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockProcessor(localId, mediaFile) { + override fun processBlockContentDocument(document: Document?): Boolean { + val audioElements = document?.select(AUDIO_TAG) + + audioElements?.let { elements -> + for (element in elements) { + // replaces the src attribute's local url with the remote counterpart. + element.attr(SRC_ATTRIBUTE, mRemoteUrl) + } + return true + } + return false + } + + override fun processBlockJsonAttributes(jsonAttributes: JsonObject?): Boolean { + val id = jsonAttributes?.get(ID_ATTRIBUTE) + + return if (id != null && !id.isJsonNull && id.asString == mLocalId) { + jsonAttributes.apply { + addProperty(ID_ATTRIBUTE, Integer.parseInt(mRemoteId)) + } + true + } else { + false + } + } + + companion object { + const val AUDIO_TAG = "audio" + const val SRC_ATTRIBUTE = "src" + const val ID_ATTRIBUTE = "id" + } +} diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java index 20a93f520d54..4258b5a3ee48 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.Map; +import static org.wordpress.android.ui.posts.mediauploadcompletionprocessors.MediaBlockType.AUDIO; import static org.wordpress.android.ui.posts.mediauploadcompletionprocessors.MediaBlockType.COVER; import static org.wordpress.android.ui.posts.mediauploadcompletionprocessors.MediaBlockType.FILE; import static org.wordpress.android.ui.posts.mediauploadcompletionprocessors.MediaBlockType.GALLERY; @@ -39,6 +40,7 @@ BlockProcessorFactory init(String localId, MediaFile mediaFile, String siteUrl) mMediaBlockTypeBlockProcessorMap.put(COVER, new CoverBlockProcessor(localId, mediaFile, mMediaUploadCompletionProcessor)); mMediaBlockTypeBlockProcessorMap.put(FILE, new FileBlockProcessor(localId, mediaFile)); + mMediaBlockTypeBlockProcessorMap.put(AUDIO, new AudioBlockProcessor(localId, mediaFile)); return this; } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/MediaBlockType.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/MediaBlockType.java index 2ca21dd09cb1..e5eefff16d05 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/MediaBlockType.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/MediaBlockType.java @@ -16,7 +16,8 @@ enum MediaBlockType { MEDIA_TEXT("media-text"), GALLERY("gallery"), COVER("cover"), - FILE("file"); + FILE("file"), + AUDIO("audio"); private static final Map MAP = new HashMap<>(); private static final String MATCHING_GROUP; diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/PostUtilsUnitTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/PostUtilsUnitTest.kt index a8eb6b557b46..63670e401cea 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/PostUtilsUnitTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/PostUtilsUnitTest.kt @@ -130,6 +130,13 @@ class PostUtilsUnitTest { assertThat(PostUtils.isMediaInGutenbergPostBody(postContent, mediaId)).isTrue() } + @Test + fun `isMediaInGutenberg returns true when an Audio Block is found in the post content`() { + val mediaId = "999" + val postContent = " ...... " + assertThat(PostUtils.isMediaInGutenbergPostBody(postContent, mediaId)).isTrue() + } + @Test fun `isMediaInGutenberg returns false when an imageBlock with provided id is NOT found in the post content`() { val imgId = "123" @@ -158,6 +165,13 @@ class PostUtilsUnitTest { assertThat(PostUtils.isMediaInGutenbergPostBody(postContent, "999")).isFalse() } + @Test + fun `isMediaInGutenberg returns false when an Audio Block with provided id is NOT found in the post content`() { + val mediaId = "123" + val postContent = " ...... " + assertThat(PostUtils.isMediaInGutenbergPostBody(postContent, "999")).isFalse() + } + @Test fun `isMediaInGutenberg returns false for an imageBlock when only part of the id matches`() { val imgId = "12345" @@ -186,6 +200,13 @@ class PostUtilsUnitTest { assertThat(PostUtils.isMediaInGutenbergPostBody(postContent, "123")).isFalse() } + @Test + fun `isMediaInGutenberg returns false for an Audio Block when only part of the id matches`() { + val mediaId = "12345" + val postContent = " ...... " + assertThat(PostUtils.isMediaInGutenbergPostBody(postContent, "123")).isFalse() + } + @Test fun `isMediaInGutenberg returns false when a galleryBlock with provided id is NOT found in the post content`() { val imgId = "123" diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/AudioBlockProcessorTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/AudioBlockProcessorTest.kt new file mode 100644 index 000000000000..b6c4aa232205 --- /dev/null +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/AudioBlockProcessorTest.kt @@ -0,0 +1,34 @@ +package org.wordpress.android.ui.posts.mediauploadcompletionprocessors + +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.whenever +import org.assertj.core.api.Assertions +import org.junit.Before +import org.junit.Test +import org.wordpress.android.util.helpers.MediaFile + +class AudioBlockProcessorTest { + private val mediaFile: MediaFile = mock() + private lateinit var processor: AudioBlockProcessor + + @Before + fun before() { + whenever(mediaFile.mediaId).thenReturn(TestContent.remoteMediaId) + whenever(mediaFile.fileURL).thenReturn(TestContent.remoteAudioUrl) + processor = AudioBlockProcessor(TestContent.localMediaId, mediaFile) + } + + @Test + fun `processBlock replaces id and src in matching block`() { + val processedBlock = processor.processBlock(TestContent.oldAudioBlock) + Assertions.assertThat(processedBlock).isEqualTo(TestContent.newAudioBlock) + } + + @Test + fun `processBlock leaves non-matching block unchanged`() { + val nonMatchingId = "123" + val processor = AudioBlockProcessor(nonMatchingId, mediaFile) + val processedBlock = processor.processBlock(TestContent.oldFileBlock) + Assertions.assertThat(processedBlock).isEqualTo(TestContent.oldFileBlock) + } +} diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt index a9c175d89c50..54f321ce8a82 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt @@ -6,8 +6,10 @@ object TestContent { const val siteUrl = "https://wordpress.org" const val localImageUrl = "file://Screenshot-1-1.png" const val localImageUrl2 = "file://Screenshot-1-2.png" + const val localAudioUrl = "file://test-song.mp3" const val remoteImageUrl = "https://onetwoonetwothisisjustatesthome.files.wordpress.com/2019/11/pexels-photo-1671668.jpg" const val remoteImageUrl2 = "https://onetwoonetwothisisjustatesthome.files.wordpress.com/2019/12/img_20191202_094944-19.jpg" + const val remoteAudioUrl = "https://onetwoonetwothisisjustatesthome.files.wordpress.com/2020/11/test-song.mp3" private const val remoteImageUrlBlogLink = "http://onetwoonetwothisisjustatest.home.blog/pexels-photo-1671668/" private const val remoteImageUrlWithSize = "https://onetwoonetwothisisjustatesthome.files.wordpress.com/2019/11/pexels-photo-1671668.jpg?w=1024" private const val remoteImageUrl2BlogLink = "http://onetwoonetwothisisjustatest.home.blog/?attachment_id=369" @@ -571,6 +573,13 @@ object TestContent { """ + const val oldAudioBlock = """ +
+""" + + const val newAudioBlock = """ +
+""" const val oldPostImage = paragraphBlock + oldImageBlock + newVideoBlock + newMediaTextBlock + newGalleryBlock const val newPostImage = paragraphBlock + newImageBlock + newVideoBlock + newMediaTextBlock + newGalleryBlock