diff --git a/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/bodycontent/ConversationDetailHtmlSanitizationTests.kt b/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/bodycontent/ConversationDetailHtmlSanitizationTests.kt
new file mode 100644
index 0000000000..edc6a10ccc
--- /dev/null
+++ b/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/bodycontent/ConversationDetailHtmlSanitizationTests.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2022 Proton Technologies AG
+ * This file is part of Proton Technologies AG and Proton Mail.
+ *
+ * Proton Mail is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Proton Mail is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Proton Mail. If not, see .
+ */
+
+package ch.protonmail.android.uitest.e2e.mailbox.detail.bodycontent
+
+import ch.protonmail.android.di.ServerProofModule
+import ch.protonmail.android.networkmocks.mockwebserver.requests.ignoreQueryParams
+import ch.protonmail.android.networkmocks.mockwebserver.requests.matchWildcards
+import ch.protonmail.android.networkmocks.mockwebserver.requests.respondWith
+import ch.protonmail.android.networkmocks.mockwebserver.requests.serveOnce
+import ch.protonmail.android.networkmocks.mockwebserver.requests.withStatusCode
+import ch.protonmail.android.test.annotations.suite.SmokeTest
+import ch.protonmail.android.uitest.MockedNetworkTest
+import ch.protonmail.android.uitest.helpers.core.TestId
+import ch.protonmail.android.uitest.helpers.core.navigation.Destination
+import ch.protonmail.android.uitest.helpers.core.navigation.navigator
+import ch.protonmail.android.uitest.helpers.login.LoginStrategy
+import ch.protonmail.android.uitest.helpers.network.mockNetworkDispatcher
+import ch.protonmail.android.uitest.robot.detail.conversationDetailRobot
+import ch.protonmail.android.uitest.robot.detail.section.messageBodySection
+import ch.protonmail.android.uitest.robot.detail.section.verify
+import dagger.hilt.android.testing.BindValue
+import dagger.hilt.android.testing.HiltAndroidTest
+import dagger.hilt.android.testing.UninstallModules
+import io.mockk.mockk
+import me.proton.core.auth.domain.usecase.ValidateServerProof
+import org.junit.Test
+
+@SmokeTest
+@HiltAndroidTest
+@UninstallModules(ServerProofModule::class)
+internal class ConversationDetailHtmlSanitizationTests : MockedNetworkTest(loginStrategy = LoginStrategy.LoggedOut) {
+
+ @JvmField
+ @BindValue
+ val serverProofValidation: ValidateServerProof = mockk(relaxUnitFun = true)
+
+ @Test
+ @TestId("189699")
+ fun checkHtmlSanitizationInConversationMode() {
+ mockWebServer.dispatcher = mockNetworkDispatcher(useDefaultMailSettings = false) {
+ addMockRequests(
+ "/mail/v4/settings"
+ respondWith "/mail/v4/settings/mail-v4-settings_placeholder_conversation.json"
+ withStatusCode 200,
+ "/mail/v4/conversations"
+ respondWith "/mail/v4/conversations/conversations_189699.json"
+ withStatusCode 200 matchWildcards true ignoreQueryParams true,
+ "/mail/v4/conversations/*"
+ respondWith "/mail/v4/conversations/conversation-id/conversation-id_189699.json"
+ withStatusCode 200 matchWildcards true serveOnce true,
+ "/mail/v4/messages/*"
+ respondWith "/mail/v4/messages/message-id/message-id_189699.json"
+ withStatusCode 200 matchWildcards true serveOnce true
+ )
+ }
+
+ navigator {
+ navigateTo(Destination.MailDetail(0))
+ }
+
+ conversationDetailRobot {
+ messageBodySection {
+ waitUntilMessageIsShown()
+
+ verify { hasHtmlContentSanitised() }
+ }
+ }
+ }
+}
diff --git a/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/conversation/ConversationDetailRemoteContentTest.kt b/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/bodycontent/ConversationDetailRemoteContentTests.kt
similarity index 99%
rename from app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/conversation/ConversationDetailRemoteContentTest.kt
rename to app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/bodycontent/ConversationDetailRemoteContentTests.kt
index 3a8ffa16ab..3cd76cacc9 100644
--- a/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/conversation/ConversationDetailRemoteContentTest.kt
+++ b/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/bodycontent/ConversationDetailRemoteContentTests.kt
@@ -16,7 +16,7 @@
* along with Proton Mail. If not, see .
*/
-package ch.protonmail.android.uitest.e2e.mailbox.detail.conversation
+package ch.protonmail.android.uitest.e2e.mailbox.detail.bodycontent
import arrow.core.Either
import ch.protonmail.android.di.ServerProofModule
@@ -52,7 +52,7 @@ import org.junit.Test
@RegressionTest
@HiltAndroidTest
@UninstallModules(ServerProofModule::class)
-internal class ConversationDetailRemoteContentTest :
+internal class ConversationDetailRemoteContentTests :
MockedNetworkTest(loginStrategy = LoginStrategy.LoggedOut),
DetailRemoteContentTest {
diff --git a/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/bodycontent/MessageDetailHtmlSanitizationTests.kt b/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/bodycontent/MessageDetailHtmlSanitizationTests.kt
new file mode 100644
index 0000000000..557a1ede10
--- /dev/null
+++ b/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/bodycontent/MessageDetailHtmlSanitizationTests.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2022 Proton Technologies AG
+ * This file is part of Proton Technologies AG and Proton Mail.
+ *
+ * Proton Mail is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Proton Mail is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Proton Mail. If not, see .
+ */
+
+package ch.protonmail.android.uitest.e2e.mailbox.detail.bodycontent
+
+import ch.protonmail.android.di.ServerProofModule
+import ch.protonmail.android.networkmocks.mockwebserver.requests.ignoreQueryParams
+import ch.protonmail.android.networkmocks.mockwebserver.requests.matchWildcards
+import ch.protonmail.android.networkmocks.mockwebserver.requests.respondWith
+import ch.protonmail.android.networkmocks.mockwebserver.requests.serveOnce
+import ch.protonmail.android.networkmocks.mockwebserver.requests.withStatusCode
+import ch.protonmail.android.test.annotations.suite.SmokeTest
+import ch.protonmail.android.uitest.MockedNetworkTest
+import ch.protonmail.android.uitest.helpers.core.TestId
+import ch.protonmail.android.uitest.helpers.core.navigation.Destination
+import ch.protonmail.android.uitest.helpers.core.navigation.navigator
+import ch.protonmail.android.uitest.helpers.login.LoginStrategy
+import ch.protonmail.android.uitest.helpers.network.mockNetworkDispatcher
+import ch.protonmail.android.uitest.robot.detail.messageDetailRobot
+import ch.protonmail.android.uitest.robot.detail.section.messageBodySection
+import ch.protonmail.android.uitest.robot.detail.section.verify
+import dagger.hilt.android.testing.BindValue
+import dagger.hilt.android.testing.HiltAndroidTest
+import dagger.hilt.android.testing.UninstallModules
+import io.mockk.mockk
+import me.proton.core.auth.domain.usecase.ValidateServerProof
+import org.junit.Test
+
+@SmokeTest
+@HiltAndroidTest
+@UninstallModules(ServerProofModule::class)
+internal class MessageDetailHtmlSanitizationTests : MockedNetworkTest(loginStrategy = LoginStrategy.LoggedOut) {
+
+ @JvmField
+ @BindValue
+ val serverProofValidation: ValidateServerProof = mockk(relaxUnitFun = true)
+
+ @Test
+ @TestId("189700")
+ fun checkHtmlSanitizationInMessageMode() {
+ mockWebServer.dispatcher = mockNetworkDispatcher(useDefaultMailSettings = false) {
+ addMockRequests(
+ "/mail/v4/settings"
+ respondWith "/mail/v4/settings/mail-v4-settings_placeholder_messages.json"
+ withStatusCode 200,
+ "/mail/v4/messages"
+ respondWith "/mail/v4/messages/messages_189700.json"
+ withStatusCode 200 matchWildcards true ignoreQueryParams true,
+ "/mail/v4/messages/*"
+ respondWith "/mail/v4/messages/message-id/message-id_189700.json"
+ withStatusCode 200 matchWildcards true serveOnce true
+ )
+ }
+
+ navigator {
+ navigateTo(Destination.MailDetail(0))
+ }
+
+ messageDetailRobot {
+ messageBodySection {
+ waitUntilMessageIsShown()
+
+ verify { hasHtmlContentSanitised() }
+ }
+ }
+ }
+}
diff --git a/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/message/MessageDetailDetailRemoteContentTest.kt b/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/bodycontent/MessageDetailRemoteContentTests.kt
similarity index 97%
rename from app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/message/MessageDetailDetailRemoteContentTest.kt
rename to app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/bodycontent/MessageDetailRemoteContentTests.kt
index 1b3d54efea..82598b0a00 100644
--- a/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/message/MessageDetailDetailRemoteContentTest.kt
+++ b/app/src/uiTest/kotlin/ch/protonmail/android/uitest/e2e/mailbox/detail/bodycontent/MessageDetailRemoteContentTests.kt
@@ -16,7 +16,7 @@
* along with Proton Mail. If not, see .
*/
-package ch.protonmail.android.uitest.e2e.mailbox.detail.message
+package ch.protonmail.android.uitest.e2e.mailbox.detail.bodycontent
import arrow.core.Either
import ch.protonmail.android.di.ServerProofModule
@@ -49,7 +49,7 @@ import org.junit.Test
@SmokeTest
@HiltAndroidTest
@UninstallModules(ServerProofModule::class)
-internal class MessageDetailDetailRemoteContentTest :
+internal class MessageDetailRemoteContentTests :
MockedNetworkTest(loginStrategy = LoginStrategy.LoggedOut),
DetailRemoteContentTest {
diff --git a/app/src/uiTest/kotlin/ch/protonmail/android/uitest/robot/detail/section/MessageBodySection.kt b/app/src/uiTest/kotlin/ch/protonmail/android/uitest/robot/detail/section/MessageBodySection.kt
index e37941d49b..2210e46018 100644
--- a/app/src/uiTest/kotlin/ch/protonmail/android/uitest/robot/detail/section/MessageBodySection.kt
+++ b/app/src/uiTest/kotlin/ch/protonmail/android/uitest/robot/detail/section/MessageBodySection.kt
@@ -97,8 +97,6 @@ internal class MessageBodySection : ComposeSectionRobot() {
}
fun hasRemoteImageLoaded(expected: Boolean) {
- composeTestRule.waitForIdle()
-
val jsSnippet = """
|var image = document.querySelector('img');
|var isLoaded = image.complete && image.naturalWidth != 0 && image.naturalHeight != 0;
@@ -108,6 +106,19 @@ internal class MessageBodySection : ComposeSectionRobot() {
runAndMatchJsCodeOutput(jsSnippet, expected)
}
+ fun hasHtmlContentSanitised() {
+ val jsSnippet = """
+ |var onLoad = document.querySelector('body').onload;
+ |var form = document.querySelector('form');
+ |var relLinks = document.querySelector('link');
+ |var iframe = document.querySelector('iframe');
+ |var ping = document.querySelector('a').ping;
+ |return onLoad == null && form == null && relLinks == null && iframe == null && ping == "";
+ """.trimMargin()
+
+ runAndMatchJsCodeOutput(jsSnippet, true)
+ }
+
private fun runAndMatchJsCodeOutput(script: String, expected: Boolean) {
webView.check(
webMatches(
diff --git a/scripts/uitests/AssetsFile.lock b/scripts/uitests/AssetsFile.lock
index f1481a98ba..ca31de6637 100644
--- a/scripts/uitests/AssetsFile.lock
+++ b/scripts/uitests/AssetsFile.lock
@@ -1 +1 @@
-NETWORK_ASSETS_TARGET_REF=342e486a95b4128ea2c481d8522de77509b7dbc9
+NETWORK_ASSETS_TARGET_REF=25c54c4ebd7d01b426006f2bc53fba56659c7d75