From 144bfa7d0f6ba1eb243ef4745dc529d42a1d0666 Mon Sep 17 00:00:00 2001 From: manas-yu Date: Thu, 5 Dec 2024 19:50:55 +0530 Subject: [PATCH 01/10] HTML-parser tests --- .../android/app/parser/HtmlParserTest.kt | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt index 1e1ca843c6a..ad777f81bc0 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt @@ -5,14 +5,19 @@ import android.app.Application import android.app.Instrumentation import android.content.Context import android.content.Intent +import android.graphics.Bitmap +import android.graphics.drawable.BitmapDrawable import android.text.Spannable +import android.text.SpannableStringBuilder import android.text.style.ClickableSpan import android.text.style.ImageSpan import android.view.View +import android.widget.ImageView import android.widget.TextView import androidx.annotation.DimenRes import androidx.annotation.IdRes import androidx.appcompat.app.AppCompatActivity +import androidx.core.graphics.drawable.toBitmap import androidx.core.view.ViewCompat import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ApplicationProvider @@ -135,6 +140,7 @@ import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode import javax.inject.Inject import javax.inject.Singleton +import junit.framework.Assert.fail import kotlin.reflect.KClass // TODO(#277): Add tests for UrlImageParser. @@ -312,6 +318,60 @@ class HtmlParserTest { .check(matches(withText(textView.text.toString()))) } + @Test + fun testHtmlContent_withEscapedNewlineTabsAndDoubleNewlines_removesExtraNewlinesCorrectly() { + val rawHtmlContent = "This is a line.\\n\\t

This is another line with a tab.

\\n\\n

And this is a third line.

" + + val cleanedHtmlContent = rawHtmlContent + .replace("\\n\\t", "") + .replace("\\n\\n", "") + + val htmlParser = htmlParserFactory.create( + resourceBucketName, + entityType = "", + entityId = "", + imageCenterAlign = true, + displayLocale = appLanguageLocaleHandler.getDisplayLocale() + ) + val (textView, parsedHtmlResult) = activityScenarioRule.scenario.runWithActivity { + val textView: TextView = it.findViewById(R.id.test_html_content_text_view) + val spannableResult = htmlParser.parseOppiaHtml(cleanedHtmlContent, textView) + return@runWithActivity textView to spannableResult + } + + assertThat(parsedHtmlResult.toString()).doesNotContain("\\n\\t") + assertThat(parsedHtmlResult.toString()).doesNotContain("\\n\\n") + assertThat(parsedHtmlResult.toString()).isEqualTo(cleanedHtmlContent) + + assertThat(textView.text.toString()).isEqualTo(parsedHtmlResult.toString()) + } + + @Test + fun testHtmlContent_withLeadingTrailingNewlinesAndImage_trimsNewlinesCorrectly() { + val htmlParser = htmlParserFactory.create( + resourceBucketName, + entityType = "", + entityId = "", + imageCenterAlign = true, + displayLocale = appLanguageLocaleHandler.getDisplayLocale() + ) + val rawHtmlContent = "\n" + + "\n" + val (textView, trimmedHtmlResult) = activityScenarioRule.scenario.runWithActivity { + val textView: TextView = it.findViewById(R.id.test_html_content_text_view) + val spannableResult = htmlParser.parseOppiaHtml(rawHtmlContent, textView) + return@runWithActivity textView to spannableResult + } + + assertThat(trimmedHtmlResult.toString()) + .isEqualTo("" + + "") + assertThat(textView.text.toString()).isEqualTo(trimmedHtmlResult.toString()) + + assertThat(trimmedHtmlResult.startsWith("\n")).isFalse() + assertThat(trimmedHtmlResult.endsWith("\n")).isFalse() + } + @Test fun testHtmlContent_handleCustomOppiaTags_parsedHtmlDisplaysStyledText() { val htmlParser = htmlParserFactory.create( From 947f7864dbc7661599a428033d217e4b679678d8 Mon Sep 17 00:00:00 2001 From: manas-yu Date: Thu, 5 Dec 2024 21:14:43 +0530 Subject: [PATCH 02/10] formatting --- .../android/app/parser/HtmlParserTest.kt | 110 ++++++++---------- 1 file changed, 50 insertions(+), 60 deletions(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt index ad777f81bc0..3147eb439d9 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt @@ -5,19 +5,14 @@ import android.app.Application import android.app.Instrumentation import android.content.Context import android.content.Intent -import android.graphics.Bitmap -import android.graphics.drawable.BitmapDrawable import android.text.Spannable -import android.text.SpannableStringBuilder import android.text.style.ClickableSpan import android.text.style.ImageSpan import android.view.View -import android.widget.ImageView import android.widget.TextView import androidx.annotation.DimenRes import androidx.annotation.IdRes import androidx.appcompat.app.AppCompatActivity -import androidx.core.graphics.drawable.toBitmap import androidx.core.view.ViewCompat import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ApplicationProvider @@ -140,7 +135,6 @@ import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode import javax.inject.Inject import javax.inject.Singleton -import junit.framework.Assert.fail import kotlin.reflect.KClass // TODO(#277): Add tests for UrlImageParser. @@ -318,60 +312,6 @@ class HtmlParserTest { .check(matches(withText(textView.text.toString()))) } - @Test - fun testHtmlContent_withEscapedNewlineTabsAndDoubleNewlines_removesExtraNewlinesCorrectly() { - val rawHtmlContent = "This is a line.\\n\\t

This is another line with a tab.

\\n\\n

And this is a third line.

" - - val cleanedHtmlContent = rawHtmlContent - .replace("\\n\\t", "") - .replace("\\n\\n", "") - - val htmlParser = htmlParserFactory.create( - resourceBucketName, - entityType = "", - entityId = "", - imageCenterAlign = true, - displayLocale = appLanguageLocaleHandler.getDisplayLocale() - ) - val (textView, parsedHtmlResult) = activityScenarioRule.scenario.runWithActivity { - val textView: TextView = it.findViewById(R.id.test_html_content_text_view) - val spannableResult = htmlParser.parseOppiaHtml(cleanedHtmlContent, textView) - return@runWithActivity textView to spannableResult - } - - assertThat(parsedHtmlResult.toString()).doesNotContain("\\n\\t") - assertThat(parsedHtmlResult.toString()).doesNotContain("\\n\\n") - assertThat(parsedHtmlResult.toString()).isEqualTo(cleanedHtmlContent) - - assertThat(textView.text.toString()).isEqualTo(parsedHtmlResult.toString()) - } - - @Test - fun testHtmlContent_withLeadingTrailingNewlinesAndImage_trimsNewlinesCorrectly() { - val htmlParser = htmlParserFactory.create( - resourceBucketName, - entityType = "", - entityId = "", - imageCenterAlign = true, - displayLocale = appLanguageLocaleHandler.getDisplayLocale() - ) - val rawHtmlContent = "\n" + - "\n" - val (textView, trimmedHtmlResult) = activityScenarioRule.scenario.runWithActivity { - val textView: TextView = it.findViewById(R.id.test_html_content_text_view) - val spannableResult = htmlParser.parseOppiaHtml(rawHtmlContent, textView) - return@runWithActivity textView to spannableResult - } - - assertThat(trimmedHtmlResult.toString()) - .isEqualTo("" + - "") - assertThat(textView.text.toString()).isEqualTo(trimmedHtmlResult.toString()) - - assertThat(trimmedHtmlResult.startsWith("\n")).isFalse() - assertThat(trimmedHtmlResult.endsWith("\n")).isFalse() - } - @Test fun testHtmlContent_handleCustomOppiaTags_parsedHtmlDisplaysStyledText() { val htmlParser = htmlParserFactory.create( @@ -487,6 +427,56 @@ class HtmlParserTest { assertThat(htmlResult.toString()).endsWith(" ") } + @Test + fun testHtmlContentReplace_removesUnwantedNewlines() { + val htmlParser = htmlParserFactory.create( + resourceBucketName, + entityType = "", + entityId = "", + imageCenterAlign = true, + displayLocale = appLanguageLocaleHandler.getDisplayLocale() + ) + val (_, htmlResult) = activityScenarioRule.scenario.runWithActivity { + val textView: TextView = it.findViewById(R.id.test_html_content_text_view) + val htmlResult = htmlParser.parseOppiaHtml( + "", + textView + ) + textView.text = htmlResult + return@runWithActivity textView to htmlResult + } + assertThat(htmlResult.toString()).isEqualTo( + "The counting numbers (1, 2, 3, 4, 5 ….)\nHow to tell whether one counting " + + "number is bigger or smaller than another" + ) + } + + @Test + fun testHtmlContent_withImageTag_trimsLeadingAndTrailingNewlines() { + val htmlParser = htmlParserFactory.create( + resourceBucketName, + entityType = "", + entityId = "", + imageCenterAlign = true, + displayLocale = appLanguageLocaleHandler.getDisplayLocale() + ) + val htmlResult = activityScenarioRule.scenario.runWithActivity { + val textView: TextView = it.findViewById(R.id.test_html_content_text_view) + return@runWithActivity htmlParser.parseOppiaHtml( + "\n" + + "\n", + textView + ) + } + + val imageSpans = htmlResult.getSpansFromWholeString(ImageSpan::class) + assertThat(imageSpans).hasLength(1) + assertThat(imageSpans.first().source).isEqualTo("test.png") + assertThat(htmlResult.toString().startsWith("\n")).isFalse() + assertThat(htmlResult.toString().endsWith("\n")).isFalse() + } + @Test fun testHtmlContent_changeDeviceToLtr_textViewDirectionIsSetToLtr() { val htmlParser = htmlParserFactory.create( From 50862f45564765d48f4133408af6ea903d85778c Mon Sep 17 00:00:00 2001 From: manas-yu Date: Thu, 5 Dec 2024 21:58:07 +0530 Subject: [PATCH 03/10] test --- .../java/org/oppia/android/app/parser/HtmlParserTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt index 3147eb439d9..7f6b1187da6 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt @@ -446,6 +446,7 @@ class HtmlParserTest { textView.text = htmlResult return@runWithActivity textView to htmlResult } + assertThat(htmlResult.toString()).isEqualTo( "The counting numbers (1, 2, 3, 4, 5 ….)\nHow to tell whether one counting " + "number is bigger or smaller than another" @@ -473,6 +474,7 @@ class HtmlParserTest { val imageSpans = htmlResult.getSpansFromWholeString(ImageSpan::class) assertThat(imageSpans).hasLength(1) assertThat(imageSpans.first().source).isEqualTo("test.png") + assertThat(htmlResult.toString().startsWith("\n")).isFalse() assertThat(htmlResult.toString().endsWith("\n")).isFalse() } From 706744b45b6a13bad8e10763718d68578e7b69f6 Mon Sep 17 00:00:00 2001 From: manas-yu Date: Fri, 6 Dec 2024 00:27:50 +0530 Subject: [PATCH 04/10] test --- .../java/org/oppia/android/app/parser/HtmlParserTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt index 7f6b1187da6..cb323852861 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt @@ -470,7 +470,6 @@ class HtmlParserTest { textView ) } - val imageSpans = htmlResult.getSpansFromWholeString(ImageSpan::class) assertThat(imageSpans).hasLength(1) assertThat(imageSpans.first().source).isEqualTo("test.png") From db92ebf0003080764601966f62881b40483c9105 Mon Sep 17 00:00:00 2001 From: manas-yu Date: Wed, 11 Dec 2024 02:15:29 +0530 Subject: [PATCH 05/10] modified image tag handler --- .../util/parser/html/ImageTagHandler.kt | 12 ++++++- .../util/parser/html/ImageTagHandlerTest.kt | 34 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt b/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt index 27bdc52cb37..ce31262ae25 100644 --- a/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt +++ b/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt @@ -11,6 +11,7 @@ import org.xml.sax.Attributes const val CUSTOM_IMG_TAG = "oppia-noninteractive-image" private const val CUSTOM_IMG_FILE_PATH_ATTRIBUTE = "filepath-with-value" private const val CUSTOM_IMG_ALT_TEXT_ATTRIBUTE = "alt-with-value" +private const val CUSTOM_IMG_CAPTION_ATTRIBUTE = "caption-with-value" /** * A custom tag handler for supporting custom Oppia images parsed with [CustomHtmlContentHandler]. @@ -27,6 +28,8 @@ class ImageTagHandler( ) { val source = attributes.getJsonStringValue(CUSTOM_IMG_FILE_PATH_ATTRIBUTE) val contentDescription = attributes.getJsonStringValue(CUSTOM_IMG_ALT_TEXT_ATTRIBUTE) + val caption = attributes.getJsonStringValue(CUSTOM_IMG_CAPTION_ATTRIBUTE) + if (source != null) { val (startIndex, endIndex) = output.run { // Use a control character to ensure that there's at least 1 character on which to "attach" @@ -57,6 +60,13 @@ class ImageTagHandler( Spannable.SPAN_INCLUSIVE_EXCLUSIVE ) output.replace(openIndex, output.length, spannableBuilder) - } else consoleLogger.w("ImageTagHandler", "Failed to parse $CUSTOM_IMG_ALT_TEXT_ATTRIBUTE") + } else consoleLogger.w("ImageTagHandler", + "Failed to parse $CUSTOM_IMG_ALT_TEXT_ATTRIBUTE") + + if (!caption.isNullOrBlank()) { + output.append("\n").append(caption) + } else { + consoleLogger.w("ImageTagHandler", "Failed to parse $CUSTOM_IMG_CAPTION_ATTRIBUTE") + } } } diff --git a/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt b/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt index 17219b230f7..3f2dfeb0c41 100644 --- a/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt +++ b/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt @@ -70,6 +70,11 @@ private const val IMAGE_TAG_WITH_SPACE_ONLY_ALT_VALUE_MARKUP = "caption-with-value=\"""\" " + "filepath-with-value=\""test_image1.png"\">" +private const val IMAGE_TAG_WITH_CAPTION_MARKUP = + "" + /** Tests for [ImageTagHandler]. */ @RunWith(AndroidJUnit4::class) @LooperMode(LooperMode.Mode.PAUSED) @@ -99,6 +104,35 @@ class ImageTagHandlerTest { // TODO(#3085): Introduce test for verifying that the error log scenario is logged correctly. + @Test + fun testParseHtml_withImageCardMarkupAndCaption_includesCaptionBelowImage() { + val parsedHtml = + CustomHtmlContentHandler.fromHtml( + html = IMAGE_TAG_WITH_CAPTION_MARKUP, + imageRetriever = mockImageRetriever, + customTagHandlers = tagHandlersWithImageTagSupport + ) + + val parsedHtmlStr = parsedHtml.toString() + assertThat(parsedHtmlStr).isEqualTo("alt text 1\nThis is a caption") + } + + @Test + fun testParseHtml_withMultipleImageCardMarkupsAndCaptions_includesAllCaptions() { + val combinedHtml = "$IMAGE_TAG_WITH_CAPTION_MARKUP and $IMAGE_TAG_WITH_CAPTION_MARKUP" + + val parsedHtml = + CustomHtmlContentHandler.fromHtml( + html = combinedHtml, + imageRetriever = mockImageRetriever, + customTagHandlers = tagHandlersWithImageTagSupport + ) + + val parsedHtmlStr = parsedHtml.toString() + assertThat(parsedHtmlStr).isEqualTo("alt text 1\nThis is a caption"+ + " and alt text 1\nThis is a caption") + } + @Test fun testParseHtml_emptyString_doesNotIncludeImageSpan() { val parsedHtml = From 3e475fe98afd8ef712f83fb3dfa0777d7e4ddcad Mon Sep 17 00:00:00 2001 From: manas-yu Date: Wed, 11 Dec 2024 02:18:10 +0530 Subject: [PATCH 06/10] capion-with-value --- .../org/oppia/android/util/parser/html/ImageTagHandler.kt | 6 ++++-- .../oppia/android/util/parser/html/ImageTagHandlerTest.kt | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt b/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt index ce31262ae25..0d1bb8869dc 100644 --- a/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt +++ b/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt @@ -60,8 +60,10 @@ class ImageTagHandler( Spannable.SPAN_INCLUSIVE_EXCLUSIVE ) output.replace(openIndex, output.length, spannableBuilder) - } else consoleLogger.w("ImageTagHandler", - "Failed to parse $CUSTOM_IMG_ALT_TEXT_ATTRIBUTE") + } else consoleLogger.w( + "ImageTagHandler", + "Failed to parse $CUSTOM_IMG_ALT_TEXT_ATTRIBUTE" + ) if (!caption.isNullOrBlank()) { output.append("\n").append(caption) diff --git a/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt b/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt index 3f2dfeb0c41..4a97bc656d2 100644 --- a/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt +++ b/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt @@ -129,8 +129,10 @@ class ImageTagHandlerTest { ) val parsedHtmlStr = parsedHtml.toString() - assertThat(parsedHtmlStr).isEqualTo("alt text 1\nThis is a caption"+ - " and alt text 1\nThis is a caption") + assertThat(parsedHtmlStr).isEqualTo( + "alt text 1\nThis is a caption" + + " and alt text 1\nThis is a caption" + ) } @Test From 2c67138e60fe4d5adf84ed49fc6ad65757ecec6d Mon Sep 17 00:00:00 2001 From: manas-yu Date: Wed, 11 Dec 2024 02:26:06 +0530 Subject: [PATCH 07/10] fix --- .../java/org/oppia/android/app/parser/HtmlParserTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt index cb323852861..9b3b36f2d6a 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt @@ -428,7 +428,7 @@ class HtmlParserTest { } @Test - fun testHtmlContentReplace_removesUnwantedNewlines() { + fun testHtmlContentParsing_removesUnwantedNewlines() { val htmlParser = htmlParserFactory.create( resourceBucketName, entityType = "", @@ -454,7 +454,7 @@ class HtmlParserTest { } @Test - fun testHtmlContent_withImageTag_trimsLeadingAndTrailingNewlines() { + fun testHtmlContentParsing_withImageTag_trimsLeadingAndTrailingNewlines() { val htmlParser = htmlParserFactory.create( resourceBucketName, entityType = "", From 890343a7afeee67756dba6d7c1e692a46747e8ad Mon Sep 17 00:00:00 2001 From: manas-yu Date: Fri, 13 Dec 2024 16:26:18 +0530 Subject: [PATCH 08/10] caption styling --- .../util/parser/html/ImageTagHandler.kt | 29 ++++++++-- .../util/parser/html/ImageTagHandlerTest.kt | 55 ++++++++++--------- 2 files changed, 52 insertions(+), 32 deletions(-) diff --git a/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt b/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt index 0d1bb8869dc..bc34ecc70d6 100644 --- a/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt +++ b/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt @@ -1,9 +1,13 @@ package org.oppia.android.util.parser.html +import android.graphics.Typeface import android.text.Editable +import android.text.Layout import android.text.Spannable import android.text.SpannableStringBuilder +import android.text.style.AlignmentSpan import android.text.style.ImageSpan +import android.text.style.StyleSpan import org.oppia.android.util.logging.ConsoleLogger import org.xml.sax.Attributes @@ -64,11 +68,26 @@ class ImageTagHandler( "ImageTagHandler", "Failed to parse $CUSTOM_IMG_ALT_TEXT_ATTRIBUTE" ) - if (!caption.isNullOrBlank()) { - output.append("\n").append(caption) - } else { - consoleLogger.w("ImageTagHandler", "Failed to parse $CUSTOM_IMG_CAPTION_ATTRIBUTE") - } + output.append("\n") + val captionStart = output.length + output.append(caption) + val captionEnd = output.length + output.setSpan( + StyleSpan(Typeface.ITALIC), + captionStart, + captionEnd, + Spannable.SPAN_INCLUSIVE_EXCLUSIVE + ) + output.setSpan( + AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER), + captionStart, + captionEnd, + Spannable.SPAN_PARAGRAPH + ) + } else consoleLogger.w( + "ImageTagHandler", + "Failed to parse $CUSTOM_IMG_CAPTION_ATTRIBUTE" + ) } } diff --git a/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt b/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt index 4a97bc656d2..1588f1e3181 100644 --- a/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt +++ b/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt @@ -2,9 +2,13 @@ package org.oppia.android.util.parser.html import android.app.Application import android.content.Context +import android.graphics.Typeface import android.text.Html +import android.text.Layout import android.text.Spannable +import android.text.style.AlignmentSpan import android.text.style.ImageSpan +import android.text.style.StyleSpan import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.common.truth.Truth.assertThat @@ -70,9 +74,9 @@ private const val IMAGE_TAG_WITH_SPACE_ONLY_ALT_VALUE_MARKUP = "caption-with-value=\"""\" " + "filepath-with-value=\""test_image1.png"\">" -private const val IMAGE_TAG_WITH_CAPTION_MARKUP = - "" /** Tests for [ImageTagHandler]. */ @@ -105,34 +109,31 @@ class ImageTagHandlerTest { // TODO(#3085): Introduce test for verifying that the error log scenario is logged correctly. @Test - fun testParseHtml_withImageCardMarkupAndCaption_includesCaptionBelowImage() { - val parsedHtml = - CustomHtmlContentHandler.fromHtml( - html = IMAGE_TAG_WITH_CAPTION_MARKUP, - imageRetriever = mockImageRetriever, - customTagHandlers = tagHandlersWithImageTagSupport - ) - - val parsedHtmlStr = parsedHtml.toString() - assertThat(parsedHtmlStr).isEqualTo("alt text 1\nThis is a caption") - } + fun testParseHtml_withImageCardMarkup_withCaption_addsCaptionWithStyleAndAlignment() { + val parsedHtml = CustomHtmlContentHandler.fromHtml( + html = IMAGE_TAG_WITH_CAPTION_MARKUP, + imageRetriever = mockImageRetriever, + customTagHandlers = tagHandlersWithImageTagSupport + ) - @Test - fun testParseHtml_withMultipleImageCardMarkupsAndCaptions_includesAllCaptions() { - val combinedHtml = "$IMAGE_TAG_WITH_CAPTION_MARKUP and $IMAGE_TAG_WITH_CAPTION_MARKUP" + val parsedHtmlString = parsedHtml.toString() + assertThat(parsedHtmlString).contains("Sample Caption") - val parsedHtml = - CustomHtmlContentHandler.fromHtml( - html = combinedHtml, - imageRetriever = mockImageRetriever, - customTagHandlers = tagHandlersWithImageTagSupport - ) + val styleSpans = parsedHtml.getSpans( + /* start = */ 0, + /* end = */ parsedHtml.length, + StyleSpan::class.java + ) + assertThat(styleSpans).hasLength(1) + assertThat(styleSpans[0].style).isEqualTo(Typeface.ITALIC) - val parsedHtmlStr = parsedHtml.toString() - assertThat(parsedHtmlStr).isEqualTo( - "alt text 1\nThis is a caption" + - " and alt text 1\nThis is a caption" + val alignmentSpans = parsedHtml.getSpans( + /* start = */ 0, + /* end = */ parsedHtml.length, + AlignmentSpan.Standard::class.java ) + assertThat(alignmentSpans).hasLength(1) + assertThat(alignmentSpans[0].alignment).isEqualTo(Layout.Alignment.ALIGN_CENTER) } @Test From 93fb23209f5b6eafa0ae279ef94f717c5c863e8d Mon Sep 17 00:00:00 2001 From: manas-yu Date: Fri, 13 Dec 2024 23:10:20 +0530 Subject: [PATCH 09/10] alignment fix --- .../oppia/android/util/parser/html/ImageTagHandler.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt b/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt index bc34ecc70d6..9bdc407ee30 100644 --- a/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt +++ b/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt @@ -85,6 +85,17 @@ class ImageTagHandler( captionEnd, Spannable.SPAN_PARAGRAPH ) + + // Insert a newline after the caption and reset alignment. + output.append("\n") + val resetStart = output.length + output.append(" ") // Add a placeholder space for resetting alignment. + output.setSpan( + AlignmentSpan.Standard(Layout.Alignment.ALIGN_NORMAL), + resetStart, + output.length, + Spannable.SPAN_PARAGRAPH + ) } else consoleLogger.w( "ImageTagHandler", "Failed to parse $CUSTOM_IMG_CAPTION_ATTRIBUTE" From dbafb20068a1a23f5212af817a5ac7228464a9f9 Mon Sep 17 00:00:00 2001 From: manas-yu Date: Sat, 14 Dec 2024 00:21:12 +0530 Subject: [PATCH 10/10] adding tests --- .../util/parser/html/ImageTagHandler.kt | 2 +- .../util/parser/html/ImageTagHandlerTest.kt | 23 +++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt b/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt index 9bdc407ee30..499b89fa54d 100644 --- a/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt +++ b/utility/src/main/java/org/oppia/android/util/parser/html/ImageTagHandler.kt @@ -89,7 +89,7 @@ class ImageTagHandler( // Insert a newline after the caption and reset alignment. output.append("\n") val resetStart = output.length - output.append(" ") // Add a placeholder space for resetting alignment. + output.append(" ") output.setSpan( AlignmentSpan.Standard(Layout.Alignment.ALIGN_NORMAL), resetStart, diff --git a/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt b/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt index 1588f1e3181..e1bd9e22a2e 100644 --- a/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt +++ b/utility/src/test/java/org/oppia/android/util/parser/html/ImageTagHandlerTest.kt @@ -74,7 +74,7 @@ private const val IMAGE_TAG_WITH_SPACE_ONLY_ALT_VALUE_MARKUP = "caption-with-value=\"""\" " + "filepath-with-value=\""test_image1.png"\">" -val IMAGE_TAG_WITH_CAPTION_MARKUP = +private const val IMAGE_TAG_WITH_CAPTION_MARKUP = "" @@ -132,8 +132,27 @@ class ImageTagHandlerTest { /* end = */ parsedHtml.length, AlignmentSpan.Standard::class.java ) - assertThat(alignmentSpans).hasLength(1) + assertThat(alignmentSpans).hasLength(2) + + // Check the first AlignmentSpan for center alignment (caption) assertThat(alignmentSpans[0].alignment).isEqualTo(Layout.Alignment.ALIGN_CENTER) + + // Check the second AlignmentSpan for normal alignment (reset) + assertThat(alignmentSpans[1].alignment).isEqualTo(Layout.Alignment.ALIGN_NORMAL) + } + + @Test + fun testParseHtml_withMultipleImages_withCaptions_includesAllCaptions() { + val parsedHtml = + CustomHtmlContentHandler.fromHtml( + html = "$IMAGE_TAG_WITH_CAPTION_MARKUP and $IMAGE_TAG_WITH_CAPTION_MARKUP", + imageRetriever = mockImageRetriever, + customTagHandlers = tagHandlersWithImageTagSupport + ) + + val parsedHtmlStr = parsedHtml.toString() + assertThat(parsedHtmlStr).contains("Sample Caption") + assertThat(parsedHtmlStr).contains("Sample Caption") } @Test