diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d5dbce9e163640e1364ff954126869aa3e22e8e8..176d74d0c557a9c1ea95338eb353642c18cd44c6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -13,10 +13,15 @@ cache:
paths:
- .gradle/
+test:
+ stage: build
+ script:
+ - ./gradlew test
+
build:
stage: build
script:
- - ./gradlew :app:k9mail:build -x test
+ - ./gradlew :app:k9mail:build
artifacts:
paths:
- app/k9mail/build/outputs/apk/
diff --git a/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java b/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java
index 356e9abb4993733abd515fc220891302696d7027..e3396031efdbd1b5af382773940d70eb6ea7aff5 100644
--- a/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java
+++ b/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java
@@ -1435,7 +1435,7 @@ public class MessagingController {
showSendingNotificationIfNecessary(account);
try {
- sendPendingMessagesSynchronous(account);
+ sendPendingMessagesSynchronous(account, true);
} finally {
clearSendingNotificationIfNecessary(account);
}
@@ -1472,6 +1472,10 @@ public class MessagingController {
*/
@VisibleForTesting
protected void sendPendingMessagesSynchronous(final Account account) {
+ sendPendingMessagesSynchronous(account, false);
+ }
+
+ private void sendPendingMessagesSynchronous(final Account account, boolean okToMakeSound) {
Exception lastFailure = null;
try {
if (isAuthenticationProblem(account, false)) {
@@ -1552,7 +1556,7 @@ public class MessagingController {
Timber.i("Sending message with UID %s", message.getUid());
backend.sendMessage(message);
- if (K9.isSentSoundEnabled()) {
+ if (okToMakeSound && K9.isSentSoundEnabled()) {
MessageSentAudio.play(context);
}
diff --git a/app/core/src/test/java/com/fsck/k9/message/html/DisplayHtmlTest.kt b/app/core/src/test/java/com/fsck/k9/message/html/DisplayHtmlTest.kt
index 6dcb06aa35b946c376a7bc129b55fe691e0ac2f5..5789d6acda1ef847c883fe5739f62812c66dab4d 100644
--- a/app/core/src/test/java/com/fsck/k9/message/html/DisplayHtmlTest.kt
+++ b/app/core/src/test/java/com/fsck/k9/message/html/DisplayHtmlTest.kt
@@ -28,15 +28,6 @@ class DisplayHtmlTest {
assertHtmlContainsElement(html, "head > style")
}
- @Test
- fun wrapMessageContent_whenDarkMessageViewTheme_addsDarkThemeCSS() {
- val darkModeDisplayHtml = DisplayHtml(HtmlSettings(useDarkMode = true, useFixedWidthFont = false))
-
- val html = darkModeDisplayHtml.wrapMessageContent("Some text")
-
- assertHtmlContainsElement(html, "head > style", 2)
- }
-
@Test
fun wrapMessageContent_putsMessageContentInBody() {
val content = "Some text"
diff --git a/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt b/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt
index 6c0da20e609131a2bcf5274fe51e7280e72fa8a9..fbc3c135f4eb0b9ae96311f7f4090759d8c78437 100644
--- a/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt
+++ b/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt
@@ -4,7 +4,6 @@ import android.view.ContextThemeWrapper
import androidx.lifecycle.LifecycleOwner
import androidx.work.WorkerParameters
import com.fsck.k9.job.MailSyncWorker
-import com.fsck.k9.ui.R
import com.fsck.k9.ui.changelog.ChangeLogMode
import com.fsck.k9.ui.changelog.ChangelogViewModel
import com.fsck.k9.ui.endtoend.AutocryptKeyTransferActivity
diff --git a/app/ui/base/build.gradle.kts b/app/ui/base/build.gradle.kts
index a8cd49b19f3b3019df4764cf8b2563c50c0423bb..1e956c9615188ed1686d7d7869b1bccd42829ff6 100644
--- a/app/ui/base/build.gradle.kts
+++ b/app/ui/base/build.gradle.kts
@@ -16,6 +16,7 @@ dependencies {
implementation(libs.androidx.biometric)
implementation(libs.timber)
implementation(libs.kotlinx.coroutines.core)
+ implementation(libs.elib)
}
android {
diff --git a/app/ui/base/src/main/res/drawable/edittext_cursor.xml b/app/ui/base/src/main/res/drawable/edittext_cursor.xml
index bc3ba972d37891d968b04af2c8be74ae60fb5b97..2662b82833c76326930bb92b101bd38615e17399 100644
--- a/app/ui/base/src/main/res/drawable/edittext_cursor.xml
+++ b/app/ui/base/src/main/res/drawable/edittext_cursor.xml
@@ -16,5 +16,5 @@
-
+
diff --git a/app/ui/base/src/main/res/drawable/ic_arrow_back.xml b/app/ui/base/src/main/res/drawable/ic_arrow_back.xml
index 4ee8f72dd7c745b77097be6c0cf06575eb0f4dfc..59a61a058e5344d82a00dc4f1dab26ba01bb5627 100644
--- a/app/ui/base/src/main/res/drawable/ic_arrow_back.xml
+++ b/app/ui/base/src/main/res/drawable/ic_arrow_back.xml
@@ -19,6 +19,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/app/ui/base/src/main/res/drawable/ic_close.xml b/app/ui/base/src/main/res/drawable/ic_close.xml
index 9b5c5e25b12cfcdabaff3cc75bc88a963421a1a9..704e1e13f0ef68f9e300770a2761e4480f871d1b 100644
--- a/app/ui/base/src/main/res/drawable/ic_close.xml
+++ b/app/ui/base/src/main/res/drawable/ic_close.xml
@@ -5,6 +5,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/app/ui/base/src/main/res/layout/toolbar.xml b/app/ui/base/src/main/res/layout/toolbar.xml
index dac4b6ccdee730d8b847c92c69ce141d2bdc8d87..216f55a49b4dc538bf83d49965d1d168f18b7e33 100644
--- a/app/ui/base/src/main/res/layout/toolbar.xml
+++ b/app/ui/base/src/main/res/layout/toolbar.xml
@@ -4,5 +4,5 @@
style="?attr/toolbarStyle"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
- android:background="@color/color_default_primary_dark"
+ android:background="@color/e_action_bar"
android:theme="@style/ToolbarTheme" />
diff --git a/app/ui/base/src/main/res/values/styles.xml b/app/ui/base/src/main/res/values/styles.xml
index 32cfef3d6e4a4966dcc11cb90ec716821a3615e0..a7dbd190cd55a62f5dfa6a07efe5ae6f4b6a634c 100644
--- a/app/ui/base/src/main/res/values/styles.xml
+++ b/app/ui/base/src/main/res/values/styles.xml
@@ -1,28 +1,28 @@
+
diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/RecipientPresenterTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/RecipientPresenterTest.kt
index d10191777c80e27fb4164883d2619b921a4cdee9..7da5d0e90cfe3c7fe6ce859e3a2119e7917f4e2a 100644
--- a/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/RecipientPresenterTest.kt
+++ b/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/RecipientPresenterTest.kt
@@ -82,6 +82,7 @@ class RecipientPresenterTest : K9RobolectricTest() {
autocryptStatusInteractor,
replyToParser,
autocryptDraftStateHeaderParser,
+ mock()
)
}
diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt
index 03e7ad1a3f932e9393c57a702c43ed86753bf0fc..c538956d11fd1fca5bbcac7895ab11ed0a98260f 100644
--- a/app/ui/legacy/src/test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt
+++ b/app/ui/legacy/src/test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt
@@ -87,48 +87,6 @@ class PgpMessageBuilderTest : K9RobolectricTest() {
.thenReturn(AUTOCRYPT_KEY_MATERIAL)
}
- @Test
- @Throws(MessagingException::class)
- fun build__withCryptoProviderUnconfigured__shouldThrow() {
- val cryptoStatus = defaultCryptoStatus.copy(openPgpProviderState = OpenPgpProviderState.UNCONFIGURED)
-
- pgpMessageBuilder.setCryptoStatus(cryptoStatus)
-
- val mockCallback = mock(Callback::class.java)
- pgpMessageBuilder.buildAsync(mockCallback)
-
- verify(mockCallback).onMessageBuildException(any())
- verifyNoMoreInteractions(mockCallback)
- }
-
- @Test
- @Throws(MessagingException::class)
- fun build__withCryptoProviderUninitialized__shouldThrow() {
- val cryptoStatus = defaultCryptoStatus.copy(openPgpProviderState = OpenPgpProviderState.UNINITIALIZED)
-
- pgpMessageBuilder.setCryptoStatus(cryptoStatus)
-
- val mockCallback = mock(Callback::class.java)
- pgpMessageBuilder.buildAsync(mockCallback)
-
- verify(mockCallback).onMessageBuildException(any())
- verifyNoMoreInteractions(mockCallback)
- }
-
- @Test
- @Throws(MessagingException::class)
- fun build__withCryptoProviderError__shouldThrow() {
- val cryptoStatus = defaultCryptoStatus.copy(openPgpProviderState = OpenPgpProviderState.ERROR)
-
- pgpMessageBuilder.setCryptoStatus(cryptoStatus)
-
- val mockCallback = mock(Callback::class.java)
- pgpMessageBuilder.buildAsync(mockCallback)
-
- verify(mockCallback).onMessageBuildException(any())
- verifyNoMoreInteractions(mockCallback)
- }
-
@Test
fun buildCleartext__withNoSigningKey__shouldBuildTrivialMessage() {
val cryptoStatus = defaultCryptoStatus.copy(openPgpKeyId = null)
diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/ui/K9DrawerTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/ui/K9DrawerTest.kt
deleted file mode 100644
index 7db67cbf5b769df8f29b244b684ca494400b31e3..0000000000000000000000000000000000000000
--- a/app/ui/legacy/src/test/java/com/fsck/k9/ui/K9DrawerTest.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.fsck.k9.ui
-
-import com.fsck.k9.RobolectricTest
-import com.fsck.k9.core.R
-import org.junit.Assert.assertEquals
-import org.junit.Test
-import org.robolectric.RuntimeEnvironment
-
-class K9DrawerTest : RobolectricTest() {
- @Test
- fun testAccountColorLengthEqualsDrawerColorLength() {
- val resources = RuntimeEnvironment.getApplication().resources
-
- val lightColors = resources.getIntArray(R.array.account_colors)
- val darkColors = resources.getIntArray(R.array.drawer_account_accent_color_dark_theme)
-
- assertEquals(lightColors.size, darkColors.size)
- }
-}
diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/ui/messagelist/MessageListAdapterTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/ui/messagelist/MessageListAdapterTest.kt
index e3018c8d2b6a814764ba1d5916e1bd6a8776d16f..b4da61c8c2373ea0236311ce3f1772618a2026b9 100644
--- a/app/ui/legacy/src/test/java/com/fsck/k9/ui/messagelist/MessageListAdapterTest.kt
+++ b/app/ui/legacy/src/test/java/com/fsck/k9/ui/messagelist/MessageListAdapterTest.kt
@@ -38,7 +38,7 @@ private const val DATE_DEFAULT_FONT_SIZE = 14f
class MessageListAdapterTest : RobolectricTest() {
val activity = Robolectric.buildActivity(AppCompatActivity::class.java).create().get()
- val context: Context = ContextThemeWrapper(activity, R.style.Theme_K9_Light)
+ val context: Context = ContextThemeWrapper(activity, R.style.Theme_K9_DayNight)
val contactsPictureLoader: ContactPictureLoader = mock()
val listItemListener: MessageListItemActionListener = mock()
@@ -71,22 +71,13 @@ class MessageListAdapterTest : RobolectricTest() {
}
@Test
- fun withStars_shouldShowStarView() {
- val adapter = createAdapter(stars = true)
-
- val view = adapter.createAndBindView()
-
- assertTrue(view.starView.isVisible)
- }
-
- @Test
- fun withStarsAndStarredMessage_shouldSetStarViewToSelected() {
+ fun withStarsAndStarredMessage_shouldShowStarView() {
val adapter = createAdapter(stars = true)
val messageListItem = createMessageListItem(isStarred = true)
val view = adapter.createAndBindView(messageListItem)
- assertTrue(view.starView.isSelected)
+ assertTrue(view.starView.isVisible)
}
@Test
@@ -140,46 +131,6 @@ class MessageListAdapterTest : RobolectricTest() {
assertEquals("Display Name", view.firstLineView.textString)
}
- @Test
- fun withoutSenderAboveSubjectAndZeroPreviewLines_shouldShowDisplayNameInSecondLine() {
- val adapter = createAdapter(senderAboveSubject = false, previewLines = 0)
- val messageListItem = createMessageListItem(displayName = "Display Name")
-
- val view = adapter.createAndBindView(messageListItem)
-
- assertEquals("Display Name", view.secondLineView.textString)
- }
-
- @Test
- fun withoutSenderAboveSubjectAndPreviewLines_shouldShowDisplayNameAndPreviewInSecondLine() {
- val adapter = createAdapter(senderAboveSubject = false, previewLines = 1)
- val messageListItem = createMessageListItem(displayName = "Display Name", previewText = "Preview")
-
- val view = adapter.createAndBindView(messageListItem)
-
- assertEquals(secondLine("Display Name", "Preview"), view.secondLineView.textString)
- }
-
- @Test
- fun withSenderAboveSubjectAndZeroPreviewLines_shouldShowSubjectInSecondLine() {
- val adapter = createAdapter(senderAboveSubject = true, previewLines = 0)
- val messageListItem = createMessageListItem(subject = "Subject")
-
- val view = adapter.createAndBindView(messageListItem)
-
- assertEquals("Subject", view.secondLineView.textString)
- }
-
- @Test
- fun withSenderAboveSubjectAndPreviewLines_shouldShowSubjectAndPreviewInSecondLine() {
- val adapter = createAdapter(senderAboveSubject = true, previewLines = 1)
- val messageListItem = createMessageListItem(subject = "Subject", previewText = "Preview")
-
- val view = adapter.createAndBindView(messageListItem)
-
- assertEquals(secondLine("Subject", "Preview"), view.secondLineView.textString)
- }
-
@Test
fun withMissingSubject_shouldDisplayNoSubjectIndicator() {
val adapter = createAdapter(senderAboveSubject = false)
@@ -280,18 +231,6 @@ class MessageListAdapterTest : RobolectricTest() {
assertNull(view.secondLineView.getFirstAbsoluteSizeSpanValueOrNull())
}
- @Test
- fun withoutSenderAboveSubjectAndNonDefaultFontSize_shouldSetTextSizeSpanInSecondLineView() {
- val adapter = createAdapter(
- fontSizes = createFontSizes(sender = LARGE),
- senderAboveSubject = false,
- )
-
- val view = adapter.createAndBindView()
-
- assertEquals(22, view.secondLineView.getFirstAbsoluteSizeSpanValueOrNull())
- }
-
@Test
fun withSenderAboveSubjectAndDefaultFontSize_shouldNotSetTextSizeSpanInSecondLineView() {
val adapter = createAdapter(
@@ -304,27 +243,6 @@ class MessageListAdapterTest : RobolectricTest() {
assertNull(view.secondLineView.getFirstAbsoluteSizeSpanValueOrNull())
}
- @Test
- fun withSenderAboveSubjectAndNonDefaultFontSize_shouldSetTextSizeSpanInSecondLineView() {
- val adapter = createAdapter(
- fontSizes = createFontSizes(subject = LARGE),
- senderAboveSubject = true,
- )
-
- val view = adapter.createAndBindView()
-
- assertEquals(22, view.secondLineView.getFirstAbsoluteSizeSpanValueOrNull())
- }
-
- @Test
- fun dateWithDefaultFontSize_shouldNotSetTextSizeOfDateView() {
- val adapter = createAdapter(fontSizes = createFontSizes(date = FONT_DEFAULT))
-
- val view = adapter.createAndBindView()
-
- assertEquals(DATE_DEFAULT_FONT_SIZE, view.dateView.textSize)
- }
-
@Test
fun dateWithNonDefaultFontSize_shouldSetTextSizeOfDateView() {
val adapter = createAdapter(fontSizes = createFontSizes(date = LARGE))
diff --git a/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapConnectionTest.kt b/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapConnectionTest.kt
index b56a1ca1f5dc8d089f965ea852876339aee58172..620452e26f64c3436c9224ecf8d3eccb3f583707 100644
--- a/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapConnectionTest.kt
+++ b/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapConnectionTest.kt
@@ -1210,7 +1210,7 @@ class RealImapConnectionTest {
class TestTokenProvider : OAuth2TokenProvider {
private var invalidationCount = 0
- override fun getToken(timeoutMillis: Long): String {
+ override fun getToken(email: String?, timeoutMillis: Long): String {
assertThat(timeoutMillis).isEqualTo(OAuth2TokenProvider.OAUTH2_TIMEOUT.toLong())
return when (invalidationCount) {
diff --git a/mail/protocols/smtp/src/test/java/com/fsck/k9/mail/transport/smtp/SmtpTransportTest.kt b/mail/protocols/smtp/src/test/java/com/fsck/k9/mail/transport/smtp/SmtpTransportTest.kt
index 5d35e5bdb5c074dcd8abfd3318d067f819ba4647..1e5832fac8e0c9df3112bdabd14a3241012d6b0e 100644
--- a/mail/protocols/smtp/src/test/java/com/fsck/k9/mail/transport/smtp/SmtpTransportTest.kt
+++ b/mail/protocols/smtp/src/test/java/com/fsck/k9/mail/transport/smtp/SmtpTransportTest.kt
@@ -23,7 +23,9 @@ import com.fsck.k9.mail.internet.MimeMessage
import com.fsck.k9.mail.oauth.OAuth2TokenProvider
import com.fsck.k9.mail.transport.mockServer.MockSmtpServer
import org.junit.Test
+import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.anyLong
+import org.mockito.ArgumentMatchers.anyString
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.doThrow
import org.mockito.kotlin.inOrder
@@ -255,7 +257,7 @@ class SmtpTransportTest {
)
inOrder(oAuth2TokenProvider) {
- verify(oAuth2TokenProvider).getToken(anyLong())
+ verify(oAuth2TokenProvider).getToken(anyString(), anyLong())
verify(oAuth2TokenProvider).invalidateToken()
}
server.verifyConnectionClosed()
@@ -282,9 +284,9 @@ class SmtpTransportTest {
transport.open()
inOrder(oAuth2TokenProvider) {
- verify(oAuth2TokenProvider).getToken(anyLong())
+ verify(oAuth2TokenProvider).getToken(anyString(), anyLong())
verify(oAuth2TokenProvider).invalidateToken()
- verify(oAuth2TokenProvider).getToken(anyLong())
+ verify(oAuth2TokenProvider).getToken(anyString(), anyLong())
}
server.verifyConnectionStillOpen()
server.verifyInteractionCompleted()
@@ -310,9 +312,9 @@ class SmtpTransportTest {
transport.open()
inOrder(oAuth2TokenProvider) {
- verify(oAuth2TokenProvider).getToken(anyLong())
+ verify(oAuth2TokenProvider).getToken(anyString(), anyLong())
verify(oAuth2TokenProvider).invalidateToken()
- verify(oAuth2TokenProvider).getToken(anyLong())
+ verify(oAuth2TokenProvider).getToken(anyString(), anyLong())
}
server.verifyConnectionStillOpen()
server.verifyInteractionCompleted()
@@ -338,9 +340,9 @@ class SmtpTransportTest {
transport.open()
inOrder(oAuth2TokenProvider) {
- verify(oAuth2TokenProvider).getToken(anyLong())
+ verify(oAuth2TokenProvider).getToken(anyString(), anyLong())
verify(oAuth2TokenProvider).invalidateToken()
- verify(oAuth2TokenProvider).getToken(anyLong())
+ verify(oAuth2TokenProvider).getToken(anyString(), anyLong())
}
server.verifyConnectionStillOpen()
server.verifyInteractionCompleted()
@@ -393,7 +395,7 @@ class SmtpTransportTest {
output("221 BYE")
}
stubbing(oAuth2TokenProvider) {
- on { getToken(anyLong()) } doThrow AuthenticationFailedException("Failed to fetch token")
+ on { getToken(anyString(), anyLong()) } doThrow AuthenticationFailedException("Failed to fetch token")
}
val transport = startServerAndCreateSmtpTransport(server, authenticationType = AuthType.XOAUTH2)
@@ -563,7 +565,7 @@ class SmtpTransportTest {
)
inOrder(oAuth2TokenProvider) {
- verify(oAuth2TokenProvider).getToken(anyLong())
+ verify(oAuth2TokenProvider).getToken(anyString(), anyLong())
verify(oAuth2TokenProvider).invalidateToken()
}
server.verifyConnectionClosed()
@@ -984,7 +986,7 @@ class SmtpTransportTest {
private fun createMockOAuth2TokenProvider(): OAuth2TokenProvider {
return mock {
- on { getToken(anyLong()) } doReturn "oldToken" doReturn "newToken"
+ on { getToken(anyString(), anyLong()) } doReturn "oldToken" doReturn "newToken"
}
}
}