diff options
| author | test@dangofactory.cos <you@example.com> | 2026-08-20 16:57:18 +0000 |
|---|---|---|
| committer | test@dangofactory.cos <you@example.com> | 2026-08-20 16:57:18 +0000 |
| commit | 50ce5d5e6cd0d720ff437d35eace545816848428 (patch) | |
| tree | b59af206a36265cf081945e434900b32b0c43edd /backend/jmap/src/test/java | |
| download | monocles_mail-50ce5d5e6cd0d720ff437d35eace545816848428.tar.gz monocles_mail-50ce5d5e6cd0d720ff437d35eace545816848428.tar.bz2 monocles_mail-50ce5d5e6cd0d720ff437d35eace545816848428.zip | |
Inital
Diffstat (limited to 'backend/jmap/src/test/java')
4 files changed, 576 insertions, 0 deletions
diff --git a/backend/jmap/src/test/java/com/fsck/k9/backend/jmap/CommandRefreshFolderListTest.kt b/backend/jmap/src/test/java/com/fsck/k9/backend/jmap/CommandRefreshFolderListTest.kt new file mode 100644 index 0000000..f79740b --- /dev/null +++ b/backend/jmap/src/test/java/com/fsck/k9/backend/jmap/CommandRefreshFolderListTest.kt @@ -0,0 +1,179 @@ +package com.fsck.k9.backend.jmap + +import app.k9mail.backend.testing.InMemoryBackendStorage +import com.fsck.k9.backend.api.BackendFolderUpdater +import com.fsck.k9.backend.api.FolderInfo +import com.fsck.k9.backend.api.updateFolders +import com.fsck.k9.mail.AuthenticationFailedException +import com.fsck.k9.mail.FolderType +import com.fsck.k9.mail.MessagingException +import junit.framework.AssertionFailedError +import okhttp3.HttpUrl +import okhttp3.mockwebserver.MockResponse +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Assert.fail +import org.junit.Test +import rs.ltt.jmap.client.JmapClient + +class CommandRefreshFolderListTest { + private val backendStorage = InMemoryBackendStorage() + + @Test + fun sessionResourceWithAuthenticationError() { + val command = createCommandRefreshFolderList( + MockResponse().setResponseCode(401) + ) + + try { + command.refreshFolderList() + fail("Expected exception") + } catch (e: AuthenticationFailedException) { + } + } + + @Test + fun invalidSessionResource() { + val command = createCommandRefreshFolderList( + MockResponse().setBody("invalid") + ) + + try { + command.refreshFolderList() + fail("Expected exception") + } catch (e: MessagingException) { + assertTrue(e.isPermanentFailure) + } + } + + @Test + fun fetchMailboxes() { + val command = createCommandRefreshFolderList( + responseBodyFromResource("/jmap_responses/session/valid_session.json"), + responseBodyFromResource("/jmap_responses/mailbox/mailbox_get.json") + ) + + command.refreshFolderList() + + assertFolderList("id_inbox", "id_archive", "id_drafts", "id_sent", "id_trash", "id_folder1") + assertFolderPresent("id_inbox", "Inbox", FolderType.INBOX) + assertFolderPresent("id_archive", "Archive", FolderType.ARCHIVE) + assertFolderPresent("id_drafts", "Drafts", FolderType.DRAFTS) + assertFolderPresent("id_sent", "Sent", FolderType.SENT) + assertFolderPresent("id_trash", "Trash", FolderType.TRASH) + assertFolderPresent("id_folder1", "folder1", FolderType.REGULAR) + assertMailboxState("23") + } + + @Test + fun fetchMailboxUpdates() { + val command = createCommandRefreshFolderList( + responseBodyFromResource("/jmap_responses/session/valid_session.json"), + responseBodyFromResource("/jmap_responses/mailbox/mailbox_changes.json") + ) + createFoldersInBackendStorage(state = "23") + + command.refreshFolderList() + + assertFolderList("id_inbox", "id_archive", "id_drafts", "id_sent", "id_trash", "id_folder2") + assertFolderPresent("id_inbox", "Inbox", FolderType.INBOX) + assertFolderPresent("id_archive", "Archive", FolderType.ARCHIVE) + assertFolderPresent("id_drafts", "Drafts", FolderType.DRAFTS) + assertFolderPresent("id_sent", "Sent", FolderType.SENT) + assertFolderPresent("id_trash", "Deleted messages", FolderType.TRASH) + assertFolderPresent("id_folder2", "folder2", FolderType.REGULAR) + assertMailboxState("42") + } + + @Test + fun fetchMailboxUpdates_withHasMoreChanges() { + val command = createCommandRefreshFolderList( + responseBodyFromResource("/jmap_responses/session/valid_session.json"), + responseBodyFromResource("/jmap_responses/mailbox/mailbox_changes_1.json"), + responseBodyFromResource("/jmap_responses/mailbox/mailbox_changes_2.json") + ) + createFoldersInBackendStorage(state = "23") + + command.refreshFolderList() + + assertFolderList("id_inbox", "id_archive", "id_drafts", "id_sent", "id_trash", "id_folder2") + assertFolderPresent("id_inbox", "Inbox", FolderType.INBOX) + assertFolderPresent("id_archive", "Archive", FolderType.ARCHIVE) + assertFolderPresent("id_drafts", "Drafts", FolderType.DRAFTS) + assertFolderPresent("id_sent", "Sent", FolderType.SENT) + assertFolderPresent("id_trash", "Deleted messages", FolderType.TRASH) + assertFolderPresent("id_folder2", "folder2", FolderType.REGULAR) + assertMailboxState("42") + } + + @Test + fun fetchMailboxUpdates_withCannotCalculateChangesError() { + val command = createCommandRefreshFolderList( + responseBodyFromResource("/jmap_responses/session/valid_session.json"), + responseBodyFromResource("/jmap_responses/mailbox/mailbox_changes_error_cannot_calculate_changes.json"), + responseBodyFromResource("/jmap_responses/mailbox/mailbox_get.json") + ) + setMailboxState("unknownToServer") + + command.refreshFolderList() + + assertFolderList("id_inbox", "id_archive", "id_drafts", "id_sent", "id_trash", "id_folder1") + assertFolderPresent("id_inbox", "Inbox", FolderType.INBOX) + assertFolderPresent("id_archive", "Archive", FolderType.ARCHIVE) + assertFolderPresent("id_drafts", "Drafts", FolderType.DRAFTS) + assertFolderPresent("id_sent", "Sent", FolderType.SENT) + assertFolderPresent("id_trash", "Trash", FolderType.TRASH) + assertFolderPresent("id_folder1", "folder1", FolderType.REGULAR) + assertMailboxState("23") + } + + private fun createCommandRefreshFolderList(vararg mockResponses: MockResponse): CommandRefreshFolderList { + val server = createMockWebServer(*mockResponses) + return createCommandRefreshFolderList(server.url("/jmap/")) + } + + private fun createCommandRefreshFolderList( + baseUrl: HttpUrl, + accountId: String = "test@example.com" + ): CommandRefreshFolderList { + val jmapClient = JmapClient("test", "test", baseUrl) + return CommandRefreshFolderList(backendStorage, jmapClient, accountId) + } + + @Suppress("SameParameterValue") + private fun createFoldersInBackendStorage(state: String) { + backendStorage.updateFolders { + createFolder("id_inbox", "Inbox", FolderType.INBOX) + createFolder("id_archive", "Archive", FolderType.ARCHIVE) + createFolder("id_drafts", "Drafts", FolderType.DRAFTS) + createFolder("id_sent", "Sent", FolderType.SENT) + createFolder("id_trash", "Trash", FolderType.TRASH) + createFolder("id_folder1", "folder1", FolderType.REGULAR) + } + setMailboxState(state) + } + + private fun BackendFolderUpdater.createFolder(serverId: String, name: String, type: FolderType) { + createFolders(listOf(FolderInfo(serverId, name, type))) + } + + private fun setMailboxState(state: String) { + backendStorage.setExtraString("jmapState", state) + } + + private fun assertFolderList(vararg folderServerIds: String) { + assertEquals(folderServerIds.toSet(), backendStorage.getFolderServerIds().toSet()) + } + + private fun assertFolderPresent(serverId: String, name: String, type: FolderType) { + val folder = backendStorage.folders[serverId] + ?: throw AssertionFailedError("Expected folder '$serverId' in BackendStorage") + + assertEquals(name, folder.name) + assertEquals(type, folder.type) + } + + private fun assertMailboxState(expected: String) { + assertEquals(expected, backendStorage.getExtraString("jmapState")) + } +} diff --git a/backend/jmap/src/test/java/com/fsck/k9/backend/jmap/CommandSyncTest.kt b/backend/jmap/src/test/java/com/fsck/k9/backend/jmap/CommandSyncTest.kt new file mode 100644 index 0000000..b4bbdbb --- /dev/null +++ b/backend/jmap/src/test/java/com/fsck/k9/backend/jmap/CommandSyncTest.kt @@ -0,0 +1,266 @@ +package com.fsck.k9.backend.jmap + +import app.k9mail.backend.testing.InMemoryBackendFolder +import app.k9mail.backend.testing.InMemoryBackendStorage +import com.fsck.k9.backend.api.FolderInfo +import com.fsck.k9.backend.api.SyncConfig +import com.fsck.k9.backend.api.SyncConfig.ExpungePolicy +import com.fsck.k9.backend.api.updateFolders +import com.fsck.k9.mail.AuthenticationFailedException +import com.fsck.k9.mail.Flag +import com.fsck.k9.mail.FolderType +import com.fsck.k9.mail.internet.BinaryTempFileBody +import java.io.File +import java.util.EnumSet +import okhttp3.HttpUrl +import okhttp3.OkHttpClient +import okhttp3.mockwebserver.MockResponse +import okhttp3.mockwebserver.MockWebServer +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test +import rs.ltt.jmap.client.JmapClient +import rs.ltt.jmap.client.http.BasicAuthHttpAuthentication + +class CommandSyncTest { + private val backendStorage = InMemoryBackendStorage() + private val okHttpClient = OkHttpClient.Builder().build() + private val syncListener = LoggingSyncListener() + private val syncConfig = SyncConfig( + expungePolicy = ExpungePolicy.IMMEDIATELY, + earliestPollDate = null, + syncRemoteDeletions = true, + maximumAutoDownloadMessageSize = 1000, + defaultVisibleLimit = 25, + syncFlags = EnumSet.of(Flag.SEEN, Flag.FLAGGED, Flag.ANSWERED, Flag.FORWARDED) + ) + + @Before + fun setUp() { + BinaryTempFileBody.setTempDirectory(File(System.getProperty("java.io.tmpdir"))) + createFolderInBackendStorage() + } + + @Test + fun sessionResourceWithAuthenticationError() { + val command = createCommandSync( + MockResponse().setResponseCode(401) + ) + + command.sync(FOLDER_SERVER_ID, syncConfig, syncListener) + + assertEquals(SyncListenerEvent.SyncStarted(FOLDER_SERVER_ID), syncListener.getNextEvent()) + val failedEvent = syncListener.getNextEvent() as SyncListenerEvent.SyncFailed + assertEquals(AuthenticationFailedException::class.java, failedEvent.exception!!.javaClass) + } + + @Test + fun fullSyncStartingWithEmptyLocalMailbox() { + val server = createMockWebServer( + responseBodyFromResource("/jmap_responses/session/valid_session.json"), + responseBodyFromResource("/jmap_responses/email/email_query_M001_and_M002.json"), + responseBodyFromResource("/jmap_responses/email/email_get_ids_M001_and_M002.json"), + responseBodyFromResource("/jmap_responses/blob/email/email_1.eml"), + responseBodyFromResource("/jmap_responses/blob/email/email_2.eml") + ) + val baseUrl = server.url("/jmap/") + val command = createCommandSync(baseUrl) + + command.sync(FOLDER_SERVER_ID, syncConfig, syncListener) + + val backendFolder = backendStorage.getFolder(FOLDER_SERVER_ID) + backendFolder.assertMessages( + "M001" to "/jmap_responses/blob/email/email_1.eml", + "M002" to "/jmap_responses/blob/email/email_2.eml" + ) + backendFolder.assertQueryState("50:0") + syncListener.assertSyncEvents( + SyncListenerEvent.SyncStarted(FOLDER_SERVER_ID), + SyncListenerEvent.SyncProgress(FOLDER_SERVER_ID, completed = 1, total = 2), + SyncListenerEvent.SyncProgress(FOLDER_SERVER_ID, completed = 2, total = 2), + SyncListenerEvent.SyncFinished(FOLDER_SERVER_ID) + ) + server.skipRequests(3) + server.assertRequestUrlPath("/jmap/download/test%40example.com/B001/B001?accept=application%2Foctet-stream") + server.assertRequestUrlPath("/jmap/download/test%40example.com/B002/B002?accept=application%2Foctet-stream") + } + + @Test + fun fullSyncExceedingMaxObjectsInGet() { + val command = createCommandSync( + responseBodyFromResource("/jmap_responses/session/session_with_maxObjectsInGet_2.json"), + responseBodyFromResource("/jmap_responses/email/email_query_M001_to_M005.json"), + responseBodyFromResource("/jmap_responses/email/email_get_ids_M001_and_M002.json"), + responseBodyFromResource("/jmap_responses/email/email_get_ids_M003_and_M004.json"), + responseBodyFromResource("/jmap_responses/email/email_get_ids_M005.json"), + responseBodyFromResource("/jmap_responses/blob/email/email_1.eml"), + responseBodyFromResource("/jmap_responses/blob/email/email_2.eml"), + responseBodyFromResource("/jmap_responses/blob/email/email_3.eml"), + responseBodyFromResource("/jmap_responses/blob/email/email_3.eml"), + responseBodyFromResource("/jmap_responses/blob/email/email_3.eml") + ) + + command.sync(FOLDER_SERVER_ID, syncConfig, syncListener) + + val backendFolder = backendStorage.getFolder(FOLDER_SERVER_ID) + assertEquals(setOf("M001", "M002", "M003", "M004", "M005"), backendFolder.getMessageServerIds()) + syncListener.assertSyncSuccess() + } + + @Test + fun fullSyncWithLocalMessagesAndDifferentMessagesInRemoteMailbox() { + val backendFolder = backendStorage.getFolder(FOLDER_SERVER_ID) + backendFolder.createMessages( + "M001" to "/jmap_responses/blob/email/email_1.eml", + "M002" to "/jmap_responses/blob/email/email_2.eml" + ) + val command = createCommandSync( + responseBodyFromResource("/jmap_responses/session/valid_session.json"), + responseBodyFromResource("/jmap_responses/email/email_query_M002_and_M003.json"), + responseBodyFromResource("/jmap_responses/email/email_get_ids_M003.json"), + responseBodyFromResource("/jmap_responses/blob/email/email_3.eml"), + responseBodyFromResource("/jmap_responses/email/email_get_keywords_M002.json") + ) + + command.sync(FOLDER_SERVER_ID, syncConfig, syncListener) + + backendFolder.assertMessages( + "M002" to "/jmap_responses/blob/email/email_2.eml", + "M003" to "/jmap_responses/blob/email/email_3.eml" + ) + syncListener.assertSyncSuccess() + } + + @Test + fun fullSyncWithLocalMessagesAndEmptyRemoteMailbox() { + val backendFolder = backendStorage.getFolder(FOLDER_SERVER_ID) + backendFolder.createMessages( + "M001" to "/jmap_responses/blob/email/email_1.eml", + "M002" to "/jmap_responses/blob/email/email_2.eml" + ) + val command = createCommandSync( + responseBodyFromResource("/jmap_responses/session/valid_session.json"), + responseBodyFromResource("/jmap_responses/email/email_query_empty_result.json") + ) + + command.sync(FOLDER_SERVER_ID, syncConfig, syncListener) + + assertEquals(emptySet<String>(), backendFolder.getMessageServerIds()) + syncListener.assertSyncEvents( + SyncListenerEvent.SyncStarted(FOLDER_SERVER_ID), + SyncListenerEvent.SyncFinished(FOLDER_SERVER_ID) + ) + } + + @Test + fun deltaSyncWithoutChanges() { + val backendFolder = backendStorage.getFolder(FOLDER_SERVER_ID) + backendFolder.createMessages( + "M001" to "/jmap_responses/blob/email/email_1.eml", + "M002" to "/jmap_responses/blob/email/email_2.eml" + ) + backendFolder.setQueryState("50:0") + val command = createCommandSync( + responseBodyFromResource("/jmap_responses/session/valid_session.json"), + responseBodyFromResource("/jmap_responses/email/email_query_changes_empty_result.json"), + responseBodyFromResource("/jmap_responses/email/email_get_keywords_M001_and_M002.json") + ) + + command.sync(FOLDER_SERVER_ID, syncConfig, syncListener) + + assertEquals(setOf("M001", "M002"), backendFolder.getMessageServerIds()) + assertEquals(emptySet<Flag>(), backendFolder.getMessageFlags("M001")) + assertEquals(setOf(Flag.SEEN), backendFolder.getMessageFlags("M002")) + backendFolder.assertQueryState("50:0") + syncListener.assertSyncEvents( + SyncListenerEvent.SyncStarted(FOLDER_SERVER_ID), + SyncListenerEvent.SyncFinished(FOLDER_SERVER_ID) + ) + } + + @Test + fun deltaSyncWithLocalMessagesAndDifferentMessagesInRemoteMailbox() { + val backendFolder = backendStorage.getFolder(FOLDER_SERVER_ID) + backendFolder.createMessages( + "M001" to "/jmap_responses/blob/email/email_1.eml", + "M002" to "/jmap_responses/blob/email/email_2.eml" + ) + backendFolder.setQueryState("50:0") + val command = createCommandSync( + responseBodyFromResource("/jmap_responses/session/valid_session.json"), + responseBodyFromResource("/jmap_responses/email/email_query_changes_M001_deleted_M003_added.json"), + responseBodyFromResource("/jmap_responses/email/email_get_ids_M003.json"), + responseBodyFromResource("/jmap_responses/blob/email/email_3.eml"), + responseBodyFromResource("/jmap_responses/email/email_get_keywords_M002.json") + ) + + command.sync(FOLDER_SERVER_ID, syncConfig, syncListener) + + assertEquals(setOf("M002", "M003"), backendFolder.getMessageServerIds()) + backendFolder.assertQueryState("51:0") + syncListener.assertSyncSuccess() + } + + @Test + fun deltaSyncCannotCalculateChanges() { + val backendFolder = backendStorage.getFolder(FOLDER_SERVER_ID) + backendFolder.createMessages( + "M001" to "/jmap_responses/blob/email/email_1.eml", + "M002" to "/jmap_responses/blob/email/email_2.eml" + ) + backendFolder.setQueryState("10:0") + val command = createCommandSync( + responseBodyFromResource("/jmap_responses/session/valid_session.json"), + responseBodyFromResource("/jmap_responses/email/email_query_changes_cannot_calculate_changes_error.json"), + responseBodyFromResource("/jmap_responses/email/email_query_M002_and_M003.json"), + responseBodyFromResource("/jmap_responses/email/email_get_ids_M003.json"), + responseBodyFromResource("/jmap_responses/blob/email/email_3.eml"), + responseBodyFromResource("/jmap_responses/email/email_get_keywords_M002.json") + ) + + command.sync(FOLDER_SERVER_ID, syncConfig, syncListener) + + assertEquals(setOf("M002", "M003"), backendFolder.getMessageServerIds()) + backendFolder.assertQueryState("50:0") + syncListener.assertSyncSuccess() + } + + private fun createCommandSync(vararg mockResponses: MockResponse): CommandSync { + val server = createMockWebServer(*mockResponses) + return createCommandSync(server.url("/jmap/")) + } + + private fun createCommandSync(baseUrl: HttpUrl): CommandSync { + val httpAuthentication = BasicAuthHttpAuthentication(USERNAME, PASSWORD) + val jmapClient = JmapClient(httpAuthentication, baseUrl) + return CommandSync(backendStorage, jmapClient, okHttpClient, ACCOUNT_ID, httpAuthentication) + } + + private fun createFolderInBackendStorage() { + backendStorage.updateFolders { + createFolders(listOf(FolderInfo(FOLDER_SERVER_ID, "Regular folder", FolderType.REGULAR))) + } + } + + private fun MockWebServer.assertRequestUrlPath(expected: String) { + val request = takeRequest() + val requestUrl = request.requestUrl ?: error("No request URL") + val requestUrlPath = requestUrl.encodedPath + "?" + requestUrl.encodedQuery + assertEquals(expected, requestUrlPath) + } + + private fun InMemoryBackendFolder.assertQueryState(expected: String) { + assertEquals(expected, getFolderExtraString("jmapQueryState")) + } + + private fun InMemoryBackendFolder.setQueryState(queryState: String) { + setFolderExtraString("jmapQueryState", queryState) + } + + companion object { + private const val FOLDER_SERVER_ID = "id_folder" + private const val USERNAME = "username" + private const val PASSWORD = "password" + private const val ACCOUNT_ID = "test@example.com" + } +} diff --git a/backend/jmap/src/test/java/com/fsck/k9/backend/jmap/LoggingSyncListener.kt b/backend/jmap/src/test/java/com/fsck/k9/backend/jmap/LoggingSyncListener.kt new file mode 100644 index 0000000..2bc08cf --- /dev/null +++ b/backend/jmap/src/test/java/com/fsck/k9/backend/jmap/LoggingSyncListener.kt @@ -0,0 +1,96 @@ +package com.fsck.k9.backend.jmap + +import com.fsck.k9.backend.api.SyncListener +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Assert.fail + +class LoggingSyncListener : SyncListener { + private val events = mutableListOf<SyncListenerEvent>() + + fun assertSyncSuccess() { + events.filterIsInstance<SyncListenerEvent.SyncFailed>().firstOrNull()?.let { syncFailed -> + throw AssertionError("Expected sync success", syncFailed.exception) + } + + if (events.none { it is SyncListenerEvent.SyncFinished }) { + fail("Expected SyncFinished, but only got: $events") + } + } + + fun assertSyncEvents(vararg events: SyncListenerEvent) { + for (event in events) { + assertEquals(event, getNextEvent()) + } + assertNoMoreEventsLeft() + } + + fun getNextEvent(): SyncListenerEvent { + require(events.isNotEmpty()) { "No events left" } + return events.removeAt(0) + } + + private fun assertNoMoreEventsLeft() { + assertTrue("Expected no more events; but still have: $events", events.isEmpty()) + } + + override fun syncStarted(folderServerId: String) { + events.add(SyncListenerEvent.SyncStarted(folderServerId)) + } + + override fun syncAuthenticationSuccess() { + throw UnsupportedOperationException("not implemented") + } + + override fun syncHeadersStarted(folderServerId: String) { + throw UnsupportedOperationException("not implemented") + } + + override fun syncHeadersProgress(folderServerId: String, completed: Int, total: Int) { + throw UnsupportedOperationException("not implemented") + } + + override fun syncHeadersFinished(folderServerId: String, totalMessagesInMailbox: Int, numNewMessages: Int) { + throw UnsupportedOperationException("not implemented") + } + + override fun syncProgress(folderServerId: String, completed: Int, total: Int) { + events.add(SyncListenerEvent.SyncProgress(folderServerId, completed, total)) + } + + override fun syncNewMessage(folderServerId: String, messageServerId: String, isOldMessage: Boolean) { + throw UnsupportedOperationException("not implemented") + } + + override fun syncRemovedMessage(folderServerId: String, messageServerId: String) { + throw UnsupportedOperationException("not implemented") + } + + override fun syncFlagChanged(folderServerId: String, messageServerId: String) { + throw UnsupportedOperationException("not implemented") + } + + override fun syncFinished(folderServerId: String) { + events.add(SyncListenerEvent.SyncFinished(folderServerId)) + } + + override fun syncFailed(folderServerId: String, message: String, exception: Exception?) { + events.add(SyncListenerEvent.SyncFailed(folderServerId, message, exception)) + } + + override fun folderStatusChanged(folderServerId: String) { + throw UnsupportedOperationException("not implemented") + } +} + +sealed class SyncListenerEvent { + data class SyncStarted(val folderServerId: String) : SyncListenerEvent() + data class SyncFinished(val folderServerId: String) : SyncListenerEvent() + data class SyncFailed( + val folderServerId: String, + val message: String, + val exception: Exception? + ) : SyncListenerEvent() + + data class SyncProgress(val folderServerId: String, val completed: Int, val total: Int) : SyncListenerEvent() +} diff --git a/backend/jmap/src/test/java/com/fsck/k9/backend/jmap/MockWebServerHelper.kt b/backend/jmap/src/test/java/com/fsck/k9/backend/jmap/MockWebServerHelper.kt new file mode 100644 index 0000000..e4bee42 --- /dev/null +++ b/backend/jmap/src/test/java/com/fsck/k9/backend/jmap/MockWebServerHelper.kt @@ -0,0 +1,35 @@ +package com.fsck.k9.backend.jmap + +import java.io.InputStream +import okhttp3.mockwebserver.MockResponse +import okhttp3.mockwebserver.MockWebServer +import okio.buffer +import okio.source + +fun createMockWebServer(vararg mockResponses: MockResponse): MockWebServer { + return MockWebServer().apply { + for (mockResponse in mockResponses) { + enqueue(mockResponse) + } + start() + } +} + +fun responseBodyFromResource(name: String): MockResponse { + return MockResponse().setBody(loadResource(name)) +} + +fun MockWebServer.skipRequests(count: Int) { + repeat(count) { + takeRequest() + } +} + +fun loadResource(name: String): String { + val resourceAsStream = ResourceLoader.getResourceAsStream(name) ?: error("Couldn't load resource: $name") + return resourceAsStream.use { it.source().buffer().readUtf8() } +} + +private object ResourceLoader { + fun getResourceAsStream(name: String): InputStream? = javaClass.getResourceAsStream(name) +} |
