@@ -615,6 +615,133 @@ class PgpMsgTest {
615615 assertEquals(1 , document.select(" summary" ).size)
616616 }
617617
618+ @Test
619+ fun testQuotesParsingAndHtmlManipulationForPlainMode () {
620+ val mimeMessageRaw = """
621+ MIME-Version: 1.0
622+ Date: Mon, 24 Feb 2025 17:02:47 +0200
623+ Message-ID: <messageid@flowcrypt.test>
624+ Subject: Re: Quotes for plain text
625+ From: Den at FlowCrypt <den@flowcrypt.test>
626+ To: DenBond7 <denbond7@flowcrypt.test>
627+ Content-Type: text/plain; charset="UTF-8"
628+ Content-Transfer-Encoding: quoted-printable
629+
630+ reply 2
631+
632+ The top-level build.gradle.kts file (for the Kotlin DSL) or
633+ build.gradle file (for the Groovy DSL) is located in the root project
634+ directory. It typically defines the common versions of plugins used by
635+ modules in your project.
636+
637+ The following code sample describes the default settings and DSL
638+ elements in the top-level build script after creating a new project
639+
640+ On Mon, Feb 24, 2025 at 5:02=E2=80=AFPM DenBond7 <denbond7@flowcrypt.tes=
641+ t> wrote:
642+ >
643+ > 2
644+ >
645+ > Creating custom build configurations requires you to make changes to
646+ > one or more build configuration files. These plain-text files use a
647+ > domain-specific language (DSL) to describe and manipulate the build
648+ > logic using Kotlin script, which is a flavor of the Kotlin language.
649+ > You can also use Groovy, which is a dynamic language for the Java
650+ > Virtual Machine (JVM), to configure your builds.
651+ >
652+ > You don't need to know Kotlin script or Groovy to start configuring
653+ > your build because the Android Gradle plugin introduces most of the
654+ > DSL elements you need. To learn more about the Android Gradle plugin
655+ > DSL, read the DSL reference documentation. Kotlin script also relies
656+ > on the underlying Gradle Kotlin DSL
657+ >
658+ > When starting a new project, Android Studio automatically creates some
659+ > of these files for you and populates them based on sensible defaults.
660+ > For an overview of the created files, see Android build structure.
661+ >
662+ > =D0=BF=D0=BD, 24 =D0=BB=D1=8E=D1=82. 2025=E2=80=AF=D1=80. =D0=BE 17:01 De=
663+ n at FlowCrypt <den@flowcrypt.test> =D0=BF=D0=B8=D1=88=D0=B5:
664+ > >
665+ > > reply 1
666+ > >
667+ > > Build types define certain properties that Gradle uses when building
668+ > > and packaging your app. Build types are typically configured for
669+ > > different stages of your development lifecycle.
670+ > >
671+ > > For example, the debug build type enables debug options and signs the
672+ > > app with the debug key, while the release build type may shrink,
673+ > > obfuscate, and sign your app with a release key for distribution.
674+ > >
675+ > > You must define at least one build type to build your app. Android
676+ > > Studio creates the debug and release build types by default. To start
677+ > > customizing packaging settings for your app, learn how to configure
678+ > > build types.
679+ > >
680+ > >
681+ > > On Mon, Feb 24, 2025 at 5:00=E2=80=AFPM DenBond7 <denbond7@flowcrypt.tes=
682+ t> wrote:
683+ > > >
684+ > > > 1
685+ > > >
686+ > > > The Android build system compiles app resources and source code and
687+ > > > packages them into APKs or Android App Bundles that you can test,
688+ > > > deploy, sign, and distribute.
689+ > > >
690+ > > > In Gradle build overview and Android build structure, we discussed
691+ > > > build concepts and the structure of an Android app. Now it's time to
692+ > > > configure the build.
693+ > > >
694+ > > >
695+ > > > --
696+ > > > Regards,
697+ > > > Denys Bondarenko
698+ > >
699+ > >
700+ > >
701+ > > --
702+ > > Regards,
703+ > > Den at FlowCrypt
704+ >
705+ >
706+ >
707+ > --
708+ > Regards,
709+ > Denys Bondarenko
710+
711+
712+
713+ --=20
714+ Regards,
715+ Den at FlowCrypt""" .trimIndent()
716+
717+ val processedMimeMessageResult = runBlocking {
718+ PgpMsg .processMimeMessage(
719+ MimeMessage (Session .getInstance(Properties ()), mimeMessageRaw.toInputStream()),
720+ PGPPublicKeyRingCollection (listOf ()),
721+ PGPSecretKeyRingCollection (listOf ()),
722+ SecretKeyRingProtector .unprotectedKeys(),
723+ )
724+ }
725+
726+ assertEquals(1 , processedMimeMessageResult.blocks.size)
727+
728+ val plainHtmlBlock = processedMimeMessageResult.blocks.first {
729+ it.type == MsgBlock .Type .PLAIN_HTML
730+ }
731+
732+ val document = Jsoup .parse(requireNotNull(plainHtmlBlock.content), " " , Parser .xmlParser())
733+ assertNotNull(document.select(" details" ).first())
734+ assertEquals(1 , document.select(" details" ).size)
735+ assertNotNull(document.select(" summary" ).first())
736+ assertEquals(1 , document.select(" summary" ).size)
737+
738+ val quotes = document.select(" blockquote" )
739+ assertEquals(3 , quotes.size)
740+ assertTrue(quotes[0 ].text().startsWith(" 2 Creating custom build configurations requires" ))
741+ assertTrue(quotes[1 ].text().startsWith(" reply 1" ))
742+ assertTrue(quotes[2 ].text().startsWith(" 1 The Android build system" ))
743+ }
744+
618745 private data class RenderedBlock (
619746 val rendered : Boolean ,
620747 val frameColor : String? ,
0 commit comments