package com.reactnativestripesdk.mappers import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.LinkAnnotation import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.sp import com.reactnativestripesdk.toHtmlString import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) class PaymentOptionDisplayDataMapperTest { @Test fun toHtmlString_PlainText() { val annotatedString = AnnotatedString("Simple text") val result = annotatedString.toHtmlString() Assert.assertEquals("Simple text", result) } @Test fun toHtmlString_EmptyString() { val annotatedString = AnnotatedString("") val result = annotatedString.toHtmlString() Assert.assertEquals("", result) } @Test fun toHtmlString_PreservesLinks() { val annotatedString = buildAnnotatedString { append("By continuing, you agree to our ") pushStringAnnotation("URL", "https://stripe.com/privacy") append("Privacy Policy") pop() append(" and ") pushStringAnnotation("URL", "https://stripe.com/terms") append("Terms of Service") pop() append(".") } val result = annotatedString.toHtmlString() Assert.assertEquals( "By continuing, you agree to our Privacy Policy and Terms of Service.", result, ) } @Test fun toHtmlString_BoldText() { val annotatedString = buildAnnotatedString { append("Normal text ") withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { append("bold text") } append(" normal again") } val result = annotatedString.toHtmlString() Assert.assertEquals( "Normal text bold text normal again", result, ) } @Test fun toHtmlString_BoldTextWithCustomWeight() { val annotatedString = buildAnnotatedString { append("Normal ") withStyle(SpanStyle(fontWeight = FontWeight.W700)) { append("bold") } append(" text") } val result = annotatedString.toHtmlString() Assert.assertEquals( "Normal bold text", result, ) } @Test fun toHtmlString_ItalicText() { val annotatedString = buildAnnotatedString { append("Normal text ") withStyle(SpanStyle(fontStyle = FontStyle.Italic)) { append("italic text") } append(" normal again") } val result = annotatedString.toHtmlString() Assert.assertEquals( "Normal text italic text normal again", result, ) } @Test fun toHtmlString_ColoredText() { val annotatedString = buildAnnotatedString { append("Normal text ") withStyle(SpanStyle(color = Color.Red)) { append("red text") } append(" normal again") } val result = annotatedString.toHtmlString() Assert.assertEquals( "Normal text red text normal again", result, ) } @Test fun toHtmlString_FontSizeText() { val annotatedString = buildAnnotatedString { append("Normal text ") withStyle(SpanStyle(fontSize = 24.sp)) { append("large text") } append(" normal again") } val result = annotatedString.toHtmlString() Assert.assertEquals( "Normal text large text normal again", result, ) } @Test fun toHtmlString_CombinedFormatting() { val annotatedString = buildAnnotatedString { append("Start ") withStyle( SpanStyle( fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic, color = Color.Blue, ), ) { append("bold italic blue") } append(" end") } val result = annotatedString.toHtmlString() Assert.assertEquals( "Start bold italic blue end", result, ) } @Test fun toHtmlString_LinksWithFormatting() { val annotatedString = buildAnnotatedString { append("Visit our ") pushStringAnnotation("URL", "https://stripe.com/privacy") withStyle(SpanStyle(fontWeight = FontWeight.Bold, color = Color.Blue)) { append("Privacy Policy") } pop() append(" for details") } val result = annotatedString.toHtmlString() Assert.assertEquals( "Visit our Privacy Policy for details", result, ) } @Test fun toHtmlString_HtmlEscaping() { val annotatedString = AnnotatedString("Text with & \"quotes\" and 'apostrophes'") val result = annotatedString.toHtmlString() Assert.assertEquals( "Text with <tags> & "quotes" and 'apostrophes'", result, ) } @Test fun toHtmlString_HtmlEscapingInLinks() { val annotatedString = buildAnnotatedString { pushStringAnnotation("URL", "https://example.com/search?q=test&foo=bar") append("Link with & in URL") pop() } val result = annotatedString.toHtmlString() Assert.assertEquals( "Link with & in URL", result, ) } @Test fun toHtmlString_NestedAnnotations() { val annotatedString = buildAnnotatedString { withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { append("Bold text with ") withStyle(SpanStyle(fontStyle = FontStyle.Italic)) { append("nested italic") } append(" continues") } } val result = annotatedString.toHtmlString() Assert.assertEquals( "Bold text with nested italic continues", result, ) } @Test fun toHtmlString_OverlappingAnnotations() { val annotatedString = buildAnnotatedString { append("Start ") withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { append("bold ") withStyle(SpanStyle(fontStyle = FontStyle.Italic)) { append("and italic") } } withStyle(SpanStyle(fontStyle = FontStyle.Italic)) { append(" continues italic") } append(" end") } val result = annotatedString.toHtmlString() Assert.assertEquals( "Start bold and italic continues italic end", result, ) } @Test fun toHtmlString_MultipleLinksWithFormatting() { val annotatedString = buildAnnotatedString { append("Check ") pushLink(LinkAnnotation.Url("https://stripe.com")) withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { append("Stripe") } pop() append(" and ") pushLink(LinkAnnotation.Url("https://github.com")) withStyle(SpanStyle(fontStyle = FontStyle.Italic, color = Color.Green)) { append("GitHub") } pop() } val result = annotatedString.toHtmlString() Assert.assertEquals( "Check Stripe and GitHub", result, ) } @Test fun toHtmlString_SpecialCharactersInFormattedText() { val annotatedString = buildAnnotatedString { withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { append("Already bold & \"quoted\"") } } val result = annotatedString.toHtmlString() Assert.assertEquals( "<b>Already bold</b> & "quoted"", result, ) } @Test fun toHtmlString_UnderlineTextDecoration() { val annotatedString = buildAnnotatedString { append("This text is ") withStyle(SpanStyle(textDecoration = TextDecoration.Underline)) { append("underlined") } append(".") } val result = annotatedString.toHtmlString() Assert.assertEquals( "This text is underlined.", result, ) } @Test fun toHtmlString_StrikethroughTextDecoration() { val annotatedString = buildAnnotatedString { append("This text is ") withStyle(SpanStyle(textDecoration = TextDecoration.LineThrough)) { append("crossed out") } append(".") } val result = annotatedString.toHtmlString() Assert.assertEquals( "This text is crossed out.", result, ) } @Test fun toHtmlString_CombinedTextDecorations() { val annotatedString = buildAnnotatedString { append("This text is ") withStyle( SpanStyle( textDecoration = TextDecoration.combine( listOf(TextDecoration.Underline, TextDecoration.LineThrough), ), ), ) { append("both underlined and crossed") } append(".") } val result = annotatedString.toHtmlString() Assert.assertEquals( "This text is both underlined and crossed.", result, ) } @Test fun toHtmlString_BackgroundColor() { val annotatedString = buildAnnotatedString { append("This text has ") withStyle(SpanStyle(background = Color.Yellow)) { append("yellow background") } append(".") } val result = annotatedString.toHtmlString() Assert.assertEquals( "This text has yellow background.", result, ) } @Test fun toHtmlString_LinkTagAnnotation() { val annotatedString = buildAnnotatedString { append("Visit ") pushStringAnnotation("LINK_TAG", "https://stripe.com") append("Stripe") pop() append(".") } val result = annotatedString.toHtmlString() Assert.assertEquals( "Visit Stripe.", result, ) } @Test fun toHtmlString_ComplexMandateText() { val annotatedString = buildAnnotatedString { append("By continuing, you agree to ") pushStringAnnotation("URL", "https://stripe.com/terms") withStyle( SpanStyle( fontWeight = FontWeight.Bold, textDecoration = TextDecoration.Underline, color = Color.Blue, ), ) { append("Terms") } pop() append(" and ") pushStringAnnotation("URL", "https://stripe.com/privacy") withStyle(SpanStyle(fontStyle = FontStyle.Italic, color = Color.Red)) { append("Privacy") } pop() append(". Important details are ") withStyle(SpanStyle(background = Color.Yellow)) { append("highlighted") } append(".") } val result = annotatedString.toHtmlString() Assert.assertEquals( "By continuing, you agree to Terms and Privacy. Important details are highlighted.", result, ) } }