Removed outdated, failing insturmented tests

This commit is contained in:
Marino Meneghel 2021-11-24 14:41:18 +01:00
parent 1a63e5e310
commit afbf83816a
16 changed files with 0 additions and 1745 deletions

View File

@ -1,131 +0,0 @@
/*
* Copyright (c) 2020 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail 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.
*
* ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.activities.labelsManager
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.SavedStateHandle
import androidx.paging.DataSource
import ch.protonmail.android.adapters.LabelsAdapter
import ch.protonmail.android.labels.domain.LabelRepository
import ch.protonmail.android.labels.domain.model.Label
import ch.protonmail.android.labels.domain.model.LabelId
import ch.protonmail.android.labels.domain.model.LabelType.MESSAGE_LABEL
import ch.protonmail.android.labels.domain.usecase.DeleteLabels
import ch.protonmail.android.labels.presentation.EXTRA_MANAGE_FOLDERS
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.mockk
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertFalse
import junit.framework.TestCase.assertTrue
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runBlockingTest
import me.proton.core.accountmanager.domain.AccountManager
import me.proton.core.domain.entity.UserId
import me.proton.core.test.kotlin.CoroutinesTest
import me.proton.core.util.kotlin.EMPTY_STRING
import org.junit.Rule
import kotlin.test.BeforeTest
import kotlin.test.Test
/**
* Test suite for [LabelsManagerViewModel]
* @author Davide Farella
*/
internal class LabelsManagerViewModelTest : CoroutinesTest {
@get:Rule
val archRule = InstantTaskExecutorRule()
@MockK
private lateinit var accountManager: AccountManager
@MockK
private lateinit var labelRepository: LabelRepository
@MockK
private lateinit var deleteLabels: DeleteLabels
private lateinit var viewModel: LabelsManagerViewModel
private val savedState = mockk<SavedStateHandle> {
every { get<Boolean>(EXTRA_MANAGE_FOLDERS) } returns false
}
val userId = UserId("testUser")
@BeforeTest
fun setUp() {
MockKAnnotations.init(this)
val testPagedResponse = object : DataSource.Factory<Int, Label>() {
override fun create(): DataSource<Int, Label> {
return mockk()
}
}
every { accountManager.getPrimaryUserId() } returns flowOf(userId)
every { labelRepository.findAllLabelsPaged(userId) } returns testPagedResponse
every { labelRepository.scheduleSaveLabel(any(), any(), any(), any(), any()) } returns flowOf(mockk())
viewModel =
LabelsManagerViewModel(
labelRepository = labelRepository,
savedStateHandle = savedState,
deleteLabels = deleteLabels,
accountManager = accountManager
)
}
@Test
fun verifyCheckedStateIsUpdatedCorrectlyForAdapterItems() {
runBlockingTest {
val adapter = LabelsAdapter()
viewModel.labels.observeDataForever(adapter::submitList)
// Assert adapter is empty
assertEquals(0, adapter.itemCount)
// Add single label
val label = Label(
id = LabelId("1"),
name = EMPTY_STRING,
color = EMPTY_STRING,
order = 0,
type = MESSAGE_LABEL,
path = EMPTY_STRING,
parentId = EMPTY_STRING
)
labelRepository.saveLabel(label, userId)
delay(50) // Wait for async delivery
assertEquals(1, adapter.itemCount)
// Select label
assertFalse(adapter.currentList!![0]!!.isChecked)
viewModel.onLabelSelected("1", true)
delay(50) // Wait for async delivery
assertTrue(adapter.currentList!![0]!!.isChecked)
// Deselect label
viewModel.onLabelSelected("1", false)
delay(50) // Wait for async delivery
assertFalse(adapter.currentList!![0]!!.isChecked)
}
}
}

View File

@ -1,105 +0,0 @@
/*
* Copyright (c) 2020 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail 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.
*
* ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.api.models.room.attachmentMetadata
import android.net.Uri
import androidx.test.core.app.ApplicationProvider
import ch.protonmail.android.core.ProtonMailApplication
import ch.protonmail.android.data.local.AttachmentMetadataDao
import ch.protonmail.android.data.local.AttachmentMetadataDatabase
import ch.protonmail.android.data.local.model.AttachmentMetadata
import ch.protonmail.android.testAndroidInstrumented.ReflectivePropertiesMatcher
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runBlockingTest
import org.hamcrest.Matchers.containsInAnyOrder
import org.junit.Assert
import kotlin.test.Test
class AttachmentMetadataDaoTest {
private val context = ApplicationProvider.getApplicationContext<ProtonMailApplication>()
private var databaseFactory = AttachmentMetadataDatabase.buildInMemoryDatabase(context)
private var database = databaseFactory.getDao()
private val first = AttachmentMetadata("a", "b", 3, "c", "d", 10, Uri.parse("a"))
private val second = AttachmentMetadata("e", "f", 5, "g", "h", 11, Uri.parse("e"))
private val third = AttachmentMetadata("i", "j", 7, "k", "l", 8, Uri.parse("i"))
private val standardTest = listOf(first, second, third)
private fun AttachmentMetadataDao.insert(attachments: Iterable<AttachmentMetadata>) {
attachments.forEach(::insertAttachmentMetadataBlocking)
}
@Test
fun insertGetAll() {
val inserted = standardTest
val expected = standardTest.map { ReflectivePropertiesMatcher(it) }
database.insert(inserted)
val actual = database.getAllAttachmentsMetadata().sortedBy(AttachmentMetadata::id)
Assert.assertThat(actual, containsInAnyOrder(expected))
}
@Test
fun insertDeleteGetAll() {
val inserted = standardTest
val expected = listOf(first, third)
val expectedMatchers = expected.map { ReflectivePropertiesMatcher(it) }
database.insert(inserted)
database.deleteAttachmentMetadata(second)
val actual = database.getAllAttachmentsMetadata().sortedBy(AttachmentMetadata::id)
Assert.assertThat(actual, containsInAnyOrder(expectedMatchers))
}
@Test
fun insertClearCacheGetAll() {
val inserted = standardTest
val expected = emptyList<AttachmentMetadata>()
database.insert(inserted)
database.clearAttachmentMetadataCache()
val actual = database.getAllAttachmentsMetadata().sortedBy(AttachmentMetadata::id)
Assert.assertEquals(expected, actual)
}
@Test
fun insertGetAllAttachmentsSizeUsed() = runBlockingTest {
val inserted = standardTest
val expected = 15L
database.insert(inserted)
val actual = database.getAllAttachmentsSizeUsed().first()
Assert.assertEquals(expected, actual)
}
@Test
fun insertGetAllAttachmentsForMessage() {
val inserted = standardTest
val expected = listOf(second).map { ReflectivePropertiesMatcher(it) }
database.insert(inserted)
val actual = database.getAllAttachmentsForMessage("h")
Assert.assertThat(actual, containsInAnyOrder(expected))
}
@Test
fun insertReplaceGetAll() {
val inserted = standardTest
val replacement = AttachmentMetadata("e", "eee", 18, "eee", "eee", 123, Uri.parse("e"))
val expected = listOf(first, replacement, third).map { ReflectivePropertiesMatcher(it) }
database.insert(inserted)
database.insertAttachmentMetadataBlocking(replacement)
val actual = database.getAllAttachmentsMetadata().sortedBy(AttachmentMetadata::id)
Assert.assertThat(actual, containsInAnyOrder(expected))
}
}

View File

@ -31,7 +31,6 @@ import ch.protonmail.android.data.local.model.FullContactDetails
import kotlinx.coroutines.runBlocking
import org.hamcrest.Matchers.`is`
import org.junit.Assert
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import kotlin.test.BeforeTest
@ -309,13 +308,6 @@ internal class ContactDaoTest {
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun findAllContactsEmailsByContactGroupAsync() {
TODO()
assertDatabaseState()
}
@Test
fun clearByEmail() {
val deletedEmail = contactEmails[1].email
@ -407,111 +399,6 @@ internal class ContactDaoTest {
assertDatabaseState(expectedContactEmails = expected)
}
@Ignore("Implement with contacts groups")
@Test
fun countContactEmails() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun findContactGroupById() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun findContactGroupByIdAsync() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun findContactGroupsLiveData() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun findContactGroupsObservable() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun clearContactGroupsLabelsTable() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun saveContactGroupLabel() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun updateFullContactGroup() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun saveAllContactGroups() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun clearContactGroupsList() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun saveContactGroupsList() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun deleteByContactGroupLabelId() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun deleteContactGroup() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun getAllContactGroupsByIds() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun updatePartially() {
TODO()
assertDatabaseState()
}
@Test
fun insertFullContactDetails() {
val inserted = FullContactDetails(
@ -559,35 +446,6 @@ internal class ContactDaoTest {
assertDatabaseState(expectedFullContactDetails = expected)
}
@Ignore("Implement with contacts groups")
@Test
fun countContactEmailsByLabelId() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun saveContactEmailContactLabel() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun saveContactEmailContactLabel1() {
TODO()
assertDatabaseState()
}
@Ignore("Implement with contacts groups")
@Test
fun saveContactEmailContactLabel2() {
TODO()
assertDatabaseState()
}
@Test
fun testContactEmailsConverter() = runBlocking {
val email1 = ContactEmail(

View File

@ -1,94 +0,0 @@
/*
* Copyright (c) 2020 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail 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.
*
* ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.api.models.room.counters
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.test.core.app.ApplicationProvider
import ch.protonmail.android.core.ProtonMailApplication
import ch.protonmail.android.data.local.CounterDao
import ch.protonmail.android.data.local.CounterDatabase
import ch.protonmail.android.data.local.model.UnreadLabelCounter
import ch.protonmail.android.data.local.model.UnreadLocationCounter
import ch.protonmail.android.testAndroidInstrumented.ReflectivePropertiesMatcher
import org.hamcrest.Matchers.`is`
import org.junit.Assert
import org.junit.Rule
import kotlin.test.BeforeTest
import kotlin.test.Test
internal class CounterDaoTest {
private val context = ApplicationProvider.getApplicationContext<ProtonMailApplication>()
private var databaseFactory = CounterDatabase.buildInMemoryDatabase(context)
private var database = databaseFactory.getDao()
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()
private val unreadLocations = listOf(
UnreadLocationCounter(1, 5),
UnreadLocationCounter(2, 7),
UnreadLocationCounter(3, 2),
UnreadLocationCounter(4, 12)
)
private val unreadLabels = listOf(
UnreadLabelCounter("a", 5),
UnreadLabelCounter("b", 7),
UnreadLabelCounter("c", 2),
UnreadLabelCounter("d", 12)
)
private fun CounterDao.populate() {
insertAllUnreadLocations(unreadLocations)
}
@BeforeTest
fun setUp() {
database.populate()
}
@Test
fun findUnreadLabelById() {
val expected = ReflectivePropertiesMatcher(unreadLabels[1])
val actual = database.findUnreadLabelById(unreadLabels[1].id)
Assert.assertThat(actual, `is`(expected))
}
@Test
fun findUnreadLabelByIdShouldReturnNull() {
val actual = database.findUnreadLabelById("e")
Assert.assertNull(actual)
}
@Test
fun findUnreadLocationById() {
unreadLabels.forEach {
val expected = it
val actual = database.findUnreadLabelById(it.id)
Assert.assertThat(actual!!, `is`(ReflectivePropertiesMatcher(expected)))
}
}
@Test
fun findUnreadLocationByIdShouldReturnNull() {
val actual = database.findUnreadLocationByIdBlocking(5)
Assert.assertNull(actual)
}
}

View File

@ -1,132 +0,0 @@
/*
* Copyright (c) 2020 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail 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.
*
* ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.api.models.room.messages
import androidx.test.core.app.ApplicationProvider
import ch.protonmail.android.api.models.enumerations.MessageEncryption
import ch.protonmail.android.core.ProtonMailApplication
import ch.protonmail.android.data.local.MessageDatabase
import ch.protonmail.android.data.local.model.Message
import ch.protonmail.android.data.local.model.MessageSender
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import me.proton.core.test.kotlin.CoroutinesTest
import org.junit.Assert
import kotlin.test.Test
class MessageDaoTest : CoroutinesTest {
private val context = ApplicationProvider.getApplicationContext<ProtonMailApplication>()
private var databaseFactory = MessageDatabase.buildInMemoryDatabase(context)
private var initiallyEmptyDatabase = databaseFactory.getDao()
private fun createBaseMessage(): Message {
return Message().apply {
messageEncryption = MessageEncryption.INTERNAL
sender = MessageSender("Test", "Test")
}
}
@Test
fun insertFindByIdShouldReturnTheSame() = runBlocking {
val expected = createBaseMessage()
val id = "testId"
expected.messageId = id
initiallyEmptyDatabase.saveMessage(expected)
val actual = initiallyEmptyDatabase.findMessageByIdBlocking(id)
Assert.assertEquals(expected, actual)
}
@Test
fun insertFindByMessageDbIdShouldReturnTheSame() = runBlocking {
val expected = createBaseMessage()
val id = "testId"
expected.messageId = id
val dbId = initiallyEmptyDatabase.saveMessage(expected)
val actual = initiallyEmptyDatabase.findMessageByDatabaseId(dbId).first()
Assert.assertEquals(expected, actual)
}
@Test
fun insertFindMessageLabelIdShouldReturnTheAppropriate() = runBlocking {
val message1 = createBaseMessage()
message1.messageId = "1"
message1.allLabelIDs = listOf("1", "5", "10")
val message2 = createBaseMessage()
message2.messageId = "2"
message2.allLabelIDs = listOf("1", "10")
val message3 = createBaseMessage()
message3.messageId = "3"
message3.allLabelIDs = listOf("1", "5")
initiallyEmptyDatabase.saveMessages(listOf(message1, message2, message3))
val expected = listOf(message1, message3)
val actual = initiallyEmptyDatabase.getMessagesByLabelId("5").sortedBy(Message::messageId)
Assert.assertEquals(expected, actual)
}
@Test
fun insertFindMessageLabelIdShouldReturnTheAppropriateSecond() = runBlocking {
val message1 = createBaseMessage()
message1.messageId = "1"
message1.allLabelIDs = listOf("1", "abcdef50abcdef", "10")
val message2 = createBaseMessage()
message2.messageId = "2"
message2.allLabelIDs = listOf("1", "10")
val message3 = createBaseMessage()
message3.messageId = "3"
message3.allLabelIDs = listOf("1", "ttttt50tttt")
val message4 = createBaseMessage()
message4.messageId = "4"
message4.allLabelIDs = listOf("1", "ttttt50")
val message5 = createBaseMessage()
message5.messageId = "5"
message5.allLabelIDs = listOf("1", "50aaaaaaa")
val message6 = createBaseMessage()
message6.messageId = "6"
message6.allLabelIDs = listOf("1", "aaaa5oaaaaaaa")
initiallyEmptyDatabase.saveMessages(listOf(message1, message2, message3, message4, message5))
val expected = listOf(message1, message3, message4, message5)
val actual = initiallyEmptyDatabase.getMessagesByLabelId("50").sortedBy(Message::messageId)
Assert.assertEquals(expected, actual)
}
@Test
fun testUpdateGoesFine() = runBlocking {
val message1 = createBaseMessage()
message1.messageId = "1"
message1.allLabelIDs = listOf("1", "5", "10")
val message2 = createBaseMessage()
message2.messageId = "2"
message2.allLabelIDs = listOf("1", "10")
val message3 = createBaseMessage()
message3.messageId = "3"
message3.allLabelIDs = listOf("1", "5")
initiallyEmptyDatabase.saveMessages(listOf(message1, message2, message3))
val savedMessage = initiallyEmptyDatabase.findMessageByIdBlocking("2")
savedMessage?.Unread = true
initiallyEmptyDatabase.saveMessage(savedMessage!!)
val savedMEssage2 = initiallyEmptyDatabase.findMessageByIdBlocking("2")
Assert.assertNotNull(savedMEssage2)
}
}

View File

@ -1,111 +0,0 @@
/*
* Copyright (c) 2020 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail 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.
*
* ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.api.models.room.notifications
import androidx.test.core.app.ApplicationProvider
import ch.protonmail.android.core.ProtonMailApplication
import ch.protonmail.android.data.local.NotificationDao
import ch.protonmail.android.data.local.NotificationDatabase
import ch.protonmail.android.data.local.model.Notification
import ch.protonmail.android.testAndroidInstrumented.ReflectivePropertiesMatcher
import ch.protonmail.android.testAndroidInstrumented.matchers
import org.hamcrest.Matchers.`is`
import org.hamcrest.Matchers.containsInAnyOrder
import org.junit.Assert
import kotlin.test.BeforeTest
import kotlin.test.Test
/**
* Created by Kamil Rajtar on 05.09.18. */
internal class NotificationDaoTest {
private val context = ApplicationProvider.getApplicationContext<ProtonMailApplication>()
private val databaseFactory = NotificationDatabase.buildInMemoryDatabase(context)
private val database = databaseFactory.getDao()
private val notifications = listOf(
Notification("a", "aa", "aaa").apply { dbId = 3 },
Notification("b", "bb", "bbb").apply { dbId = 2 },
Notification("c", "cc", "ccc").apply { dbId = 1 },
Notification("d", "dd", "ddd").apply { dbId = 8 },
Notification("e", "ee", "eee").apply { dbId = 7 }
)
private fun NotificationDao.populate() {
notifications.forEach(this::insertNotification)
}
@BeforeTest
fun setUp() {
database.populate()
}
private fun assertDatabaseState(expectedNotifications: List<Notification> = notifications) {
val expected = expectedNotifications.matchers
val actual = database.findAllNotifications()
Assert.assertThat(actual, containsInAnyOrder(expected))
}
@Test
fun findByMessageId() {
notifications.forEach {
val expected = it
val actual = database.findByMessageId(it.messageId)
Assert.assertThat(actual!!, `is`(ReflectivePropertiesMatcher(expected)))
}
assertDatabaseState()
}
@Test
fun findByMessageIdShouldReturnNull() {
val actual = database.findByMessageId("asfsagsg")
Assert.assertNull(actual)
assertDatabaseState()
}
@Test
fun deleteByMessageId() {
val deletedId = notifications[0].messageId
val expected = notifications.filterNot { it.messageId == deletedId }
database.deleteByMessageId(deletedId)
assertDatabaseState(expectedNotifications = expected)
}
@Test
fun insertNotification() {
val inserted = Notification("j", "jj", "jjj").apply {}
database.insertNotification(inserted)
inserted.dbId = database.findByMessageId("j")!!.dbId
assertDatabaseState(expectedNotifications = notifications + inserted)
}
@Test
fun clearNotificationCache() {
database.clearNotificationCache()
assertDatabaseState(expectedNotifications = emptyList())
}
@Test
fun deleteNotifications() {
val deleted = listOf(notifications[2], notifications[1])
val expected = notifications - deleted
database.deleteNotifications(deleted)
assertDatabaseState(expectedNotifications = expected)
}
}

View File

@ -1,179 +0,0 @@
/*
* Copyright (c) 2020 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail 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.
*
* ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.api.models.room.pendingActions
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.test.core.app.ApplicationProvider
import ch.protonmail.android.api.models.room.testValue
import ch.protonmail.android.core.ProtonMailApplication
import ch.protonmail.android.data.local.PendingActionDao
import ch.protonmail.android.data.local.PendingActionDatabase
import ch.protonmail.android.data.local.model.PendingSend
import ch.protonmail.android.data.local.model.PendingUpload
import ch.protonmail.android.testAndroidInstrumented.ReflectivePropertiesMatcher
import ch.protonmail.android.testAndroidInstrumented.matchers
import org.hamcrest.Matchers.`is`
import org.hamcrest.Matchers.containsInAnyOrder
import org.junit.Assert
import org.junit.Rule
import kotlin.test.BeforeTest
import kotlin.test.Test
/**
* Created by Kamil Rajtar on 06.09.18. */
internal class PendingActionDaoTest {
private val context = ApplicationProvider.getApplicationContext<ProtonMailApplication>()
private var databaseFactory = PendingActionDatabase.buildInMemoryDatabase(context)
private var database = databaseFactory.getDao()
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()
private val pendingSends = listOf(
PendingSend("a", "aa", "aaa", false, 5),
PendingSend("b", "bb", "bbb", true, 7),
PendingSend("c", "cc", "ccc", false, 3),
PendingSend("d", "dd", "ddd", true, 2),
PendingSend("e", "ee", "eee", false, 1),
PendingSend("f", "ff", "fff", true, 9)
)
private val pendingUploads = listOf(
PendingUpload("a"),
PendingUpload("b"),
PendingUpload("c"),
PendingUpload("d"),
PendingUpload("e")
)
private fun PendingActionDao.populate() {
pendingSends.forEach(this::insertPendingForSend)
pendingUploads.forEach(this::insertPendingForUpload)
}
@BeforeTest
fun setUp() {
database.populate()
}
private fun assertDatabaseState(
expectedSends: Iterable<PendingSend> = pendingSends,
expectedUploads: Iterable<PendingUpload> = pendingUploads
) {
val expectedSendsMatcher = expectedSends.map { ReflectivePropertiesMatcher(it) }
val expectedUploadsMatcher = expectedUploads.map { ReflectivePropertiesMatcher(it) }
val actualSendsSet = database.findAllPendingSendsAsync().testValue
val actualUploadsSet = database.findAllPendingUploadsAsync().testValue
Assert.assertThat(actualSendsSet, containsInAnyOrder(expectedSendsMatcher))
Assert.assertThat(actualUploadsSet, containsInAnyOrder(expectedUploadsMatcher))
}
@Test
fun insertPendingForSend() {
val inserted = PendingSend("z", "zz", "zzz", true, 101)
val expected = pendingSends + inserted
database.insertPendingForSend(inserted)
assertDatabaseState(expectedSends = expected)
}
@Test
fun findPendingSendByMessageId() {
val expected = pendingSends[3]
val actual = database.findPendingSendByMessageId(expected.messageId!!)
Assert.assertThat(actual!!, `is`(ReflectivePropertiesMatcher(expected)))
assertDatabaseState()
}
@Test
fun deletePendingSendByMessageId() {
val deleted = pendingSends[3]
val expected = pendingSends.filterNot { it.messageId == deleted.messageId }
database.deletePendingSendByMessageId(deleted.messageId!!)
assertDatabaseState(expectedSends = expected)
}
@Test
fun findPendingSendByOfflineMessageId() {
val expected = pendingSends[3]
val actual = database.findPendingSendByOfflineMessageId(expected.offlineMessageId!!)
Assert.assertThat(actual!!, `is`(ReflectivePropertiesMatcher(expected)))
assertDatabaseState()
}
@Test
fun findPendingSendByOfflineMessageIdAsync() {
val expected = pendingSends[3]
val actual = database.findPendingSendByOfflineMessageIdAsync(expected.offlineMessageId!!).testValue
Assert.assertThat(actual!!, `is`(ReflectivePropertiesMatcher(expected)))
assertDatabaseState()
}
@Test
fun findPendingSendByDbId() {
val expected = pendingSends[3]
val actual = database.findPendingSendByDbId(expected.localDatabaseId)
Assert.assertThat(actual!!, `is`(ReflectivePropertiesMatcher(expected)))
assertDatabaseState()
}
@Test
fun clearPendingSendCache() {
database.clearPendingSendCache()
assertDatabaseState(expectedSends = emptyList())
}
@Test
fun insertPendingForUpload() {
val inserted = PendingUpload("z")
val expected = pendingUploads + inserted
database.insertPendingForUpload(inserted)
assertDatabaseState(expectedUploads = expected)
}
@Test
fun findAllPendingUploadsAsync() {
val expected = pendingUploads.matchers
val actual = database.findAllPendingUploadsAsync().testValue!!
Assert.assertThat(actual, containsInAnyOrder(expected))
assertDatabaseState()
}
@Test
fun findPendingUploadByMessageId() {
val expected = pendingUploads[2]
val actual = database.findPendingUploadByMessageId(expected.messageId)
Assert.assertEquals(expected, actual)
assertDatabaseState()
}
@Test
fun deletePendingUploadByMessageId() {
val deletedId = pendingUploads[2].messageId
val expected = pendingUploads.filterNot { it.messageId == deletedId }
database.deletePendingUploadByMessageId(deletedId)
assertDatabaseState(expectedUploads = expected)
}
@Test
fun clearPendingUploadCache() {
database.clearPendingUploadCache()
assertDatabaseState(expectedUploads = emptyList())
}
}

View File

@ -159,29 +159,6 @@ class SetMessageExpirationActivityTest {
onCustomPickerView().checkNotVisible()
}
@Test
fun customInputIsSetCorrectly() {
// given
val expectedDays = 4
val expectedHours = 7
// when
launchActivity(expectedDays, expectedHours)
// then
onNoneCheck().checkNotSelected()
onOneHourCheck().checkNotSelected()
onOneDayCheck().checkNotSelected()
onThreeDaysCheck().checkNotSelected()
onOneWeekCheck().checkNotSelected()
onCustomCheck().checkSelected()
onCustomPickerView().checkVisible()
onCustomDaysView().matchesNumberText(expectedDays)
onCustomHoursView().matchesNumberText(expectedHours)
}
// endregion
// region outputs
@Test
fun noneResultIsSetCorrectly() {
@ -258,22 +235,6 @@ class SetMessageExpirationActivityTest {
assertResult(scenario, expectedDays, expectedHours)
}
@Test
fun customResultIsSetCorrectly() {
// given
val expectedDays = 4
val expectedHours = 7
// when
val scenario = launchActivity()
onCustomView().performSelection()
setCustomDaysAndHours(expectedDays, expectedHours)
performSetClick()
// then
assertResult(scenario, expectedDays, expectedHours)
}
private fun assertResult(
scenario: ActivityScenario<SetMessageExpirationActivity>,
expectedDays: Int,

View File

@ -1,152 +0,0 @@
/*
* Copyright (c) 2020 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail 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.
*
* ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.compose.presentation.ui
import android.content.Intent
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
import ch.protonmail.android.R
import ch.protonmail.android.util.withTextInputEditTextId
import org.hamcrest.core.AllOf.allOf
import org.junit.runner.RunWith
import kotlin.test.BeforeTest
import kotlin.test.Test
/**
* Test suite for [SetMessagePasswordActivity]
*/
@RunWith(AndroidJUnit4ClassRunner::class)
@Suppress("SameParameterValue")
class SetMessagePasswordActivityTest {
private val baseIntent =
Intent(ApplicationProvider.getApplicationContext(), SetMessagePasswordActivity::class.java)
@BeforeTest
fun setup() {
Intents.init()
}
@Test
fun inputIsSetCorrectly() {
// given
val expectedPassword = "12345"
val expectedHint = "hint"
// when
val intent = baseIntent
.putExtra(ARG_SET_MESSAGE_PASSWORD_PASSWORD, expectedPassword)
.putExtra(ARG_SET_MESSAGE_PASSWORD_HINT, expectedHint)
ActivityScenario.launch<SetMessagePasswordActivity>(intent)
// then
onPasswordView().check(matches(withText(expectedPassword)))
onRepeatView().check(matches(withText(expectedPassword)))
onHintView().check(matches(withText(expectedHint)))
}
@Test
fun resultIsSetCorrectly() {
// given
val expectedPassword = "12345"
val expectedHint = "hint"
// when
val scenario = ActivityScenario.launch<SetMessagePasswordActivity>(baseIntent)
setPassword(expectedPassword)
setHint(expectedHint)
performApplyClick()
// then
assertResult(scenario, expectedPassword, expectedHint)
}
@Test
fun passwordIsRemovedCorrectly() {
// given
val expectedPassword: String? = null
val expectedHint: String? = null
// when
val intent = baseIntent
.putExtra(ARG_SET_MESSAGE_PASSWORD_PASSWORD, expectedPassword)
.putExtra(ARG_SET_MESSAGE_PASSWORD_HINT, expectedHint)
val scenario = ActivityScenario.launch<SetMessagePasswordActivity>(intent)
performRemovePasswordClick()
// then
assertResult(scenario, expectedPassword, expectedHint)
}
private fun onPasswordView(): ViewInteraction =
onView(withTextInputEditTextId(R.id.set_msg_password_msg_password_input))
private fun onRepeatView(): ViewInteraction =
onView(withTextInputEditTextId(R.id.set_msg_password_repeat_password_input))
private fun onHintView(): ViewInteraction =
onView(withTextInputEditTextId(R.id.set_msg_password_hint_input))
private fun setPassword(password: String) {
onPasswordView().perform(replaceText(password))
onRepeatView().perform(replaceText(password))
}
private fun setHint(hint: String) {
onHintView().perform(replaceText(hint))
}
private fun performApplyClick() {
onView(withId(R.id.set_msg_password_apply_button)).perform(click())
}
private fun performRemovePasswordClick() {
onView(withId(R.id.set_msg_password_remove_button)).perform(click())
}
private fun assertResult(
scenario: ActivityScenario<SetMessagePasswordActivity>,
expectedPassword: String?,
expectedHint: String?
) {
val resultIntent = scenario.result.resultData
ViewMatchers.assertThat(
resultIntent,
allOf(
hasExtra(ARG_SET_MESSAGE_PASSWORD_PASSWORD, expectedPassword),
hasExtra(ARG_SET_MESSAGE_PASSWORD_HINT, expectedHint)
)
)
}
}

View File

@ -26,24 +26,16 @@ import ch.protonmail.android.data.local.model.Attachment
import ch.protonmail.android.mapper.bridge.AddressKeyBridgeMapper
import ch.protonmail.android.mapper.bridge.AddressKeysBridgeMapper
import ch.protonmail.android.mapper.bridge.UserKeyBridgeMapper
import ch.protonmail.android.usecase.crypto.GenerateTokenAndSignature
import ch.protonmail.android.utils.crypto.OpenPGP
import com.proton.gopenpgp.armor.Armor
import com.proton.gopenpgp.crypto.Crypto.newKeyFromArmored
import com.proton.gopenpgp.crypto.Crypto.newKeyRing
import com.proton.gopenpgp.crypto.Crypto.newPGPMessageFromArmored
import com.proton.gopenpgp.crypto.Crypto.newPGPSignatureFromArmored
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import kotlinx.coroutines.runBlocking
import me.proton.core.domain.arch.map
import me.proton.core.domain.entity.UserId
import me.proton.core.user.domain.entity.AddressId
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Ignore
import javax.mail.internet.InternetHeaders
import kotlin.test.Test
@ -771,35 +763,6 @@ internal class CryptoTest {
)
}
@Test
fun decrypt_message_for_only_address_key() {
every { userManagerMock.currentUser } returns oneKeyUserMock
val encryptedMessage = """
-----BEGIN PGP MESSAGE-----
Version: ProtonMail
wcBMA5kajsUECZmgAQgAgJuGP/0+pUPu24mWeviRQ79s6fKKsKh6y1aBXwJM
eQ8mSaLvHNSaCa8s9yozs9gWo2/Uf8Lpmqb70SMh2npwI5hyOFqXsrMEoEHn
KTf86kSHnGZEtwrScXnekJjO1rfYynnAYuppTfpUc2E/uGZg6RChlwPbBZMw
tOk8n6iL6u0+Ren9fxAmmMTw66vc5PDejmfAgzbdxeD7qV8wzqmipgiErk/w
dPEzI5QGtGXUwsDfJeSGEdCslN1kHtZRj2B3tg6Ms7Ea/VIb3Kq6uyn2hQhS
MlWwjzauF5mryV4Kbi1RP6yTykbPnRz6ia22HwbWzOVJ2Nu534RqNYA/99Bd
G9JcAXjM6al21XdX0ZQww2R0Of3VzFVwQX+RSG1SWGq11u2nu5iXBVUJDa5x
MS2SksqmW3Bh7Tbz2zlrCNZxH8USiAxXt/3xjwNlXgCg4b8sKNHNN4+Wa6S8
HNwbYAc=
=9RxF
-----END PGP MESSAGE-----
""".trimIndent()
val expected = "Test PGP/MIME Message\r\n\r\n\r\n"
val addressCrypto = Crypto.forAddress(userManagerMock, oneAddressKeyUserId, AddressId(oneAddressKeyAddressId))
val result = addressCrypto.decrypt(CipherText(encryptedMessage)).decryptedData
assertEquals(expected, result)
}
@Test
fun encrypt_and_decrypt_message() {
val message = "Text to encrypt and decrypt."
@ -829,43 +792,6 @@ internal class CryptoTest {
assertEquals(message, decrypted.decryptedData)
}
@Test
fun decrypt_message_for_non_first_address_key() {
every { userManagerMock.currentUser } returns manyAddressKeysUserMock
val encryptedMessage = """
-----BEGIN PGP MESSAGE-----
Version: ProtonMail
wcBMA7M4YhTWmh7GAQgAxAdgbJWi7MKSMiMg5rOUu6Y6nFJK9pgU5MsrKYqO
/hXkkpocWTs4BDL+AXmy86e0C52mwsKJj/cFZ88erFLGMrkG+sVkDFi3fZ7Q
dqrqKrzbGg6NubQpCtwGv+KvtFcMfCUWD4jeH/saD4wW9ZAH3Ozu0s/VamIX
62VDi+l6TrZIUwsC6Pnyy5O8O1BnOultCjUP4bYApSfQIBDENBVyMVT9pp1/
ylfgUSZQCj2vWkbMtMH+SAgBgk+MMYVBTx+Pk1O9lhZdqXhjzEmi58AZMdq7
/+CGjJwnySBFCLaHddYfzvVVQEAJngRRl7WA+CVkskMc94w1nwlVeuARuAiy
/9LAaQHHE3Wb1en/rqK4IPK0qWaInpVualn6KeORmtnS3Kl2Xynt92Lcckoj
37WEdjXDCIhl4JyrldelRmaxBisnW3te4vsukGh87E4jL8oDvIMwHN0bm7KH
+kBnlxqrR6N5vZmcjFoU+n9XBYDkoPZ0MZCwCgMi2BbWrQv7zy/o3+35kgms
6c3Mwb7nIP15ksysLz884tF6k5cVoLFISL7OMqem1uKM66BgOYJovvRR1Y+v
70aQ/G2w7B44mzPBOlzOAzhDQDHtxNft1XT+LH2cjrExd0EzYE+8fpYpOHC0
KfHrt6wx/sj/O+e1M9F19UGDIJMFRmlgRIUJCEmpiaZnWjmdajfUpOPd47ac
GYmSnoyEOzjf1Lyy0M6w7BHPQgwaF7Ss94EAcsFcfw==
=iJT4
-----END PGP MESSAGE-----
""".trimIndent()
val expected = "Dear valued customer,\r\n\r\n" +
"Thank you for subscribing to ProtonMail! Your support will enable us to scale up ProtonMail and continue our mission to bring easy-to-use, encrypted email to people everywhere.\r\n\r\n" +
"Thank you,\r\n\r\n" +
"The ProtonMail Team\r\n"
val addressCrypto =
Crypto.forAddress(userManagerMock, manyAddressKeysUserId, AddressId(manyAddressKeysAddressId))
val result = addressCrypto.decrypt(CipherText(encryptedMessage)).decryptedData
assertEquals(expected, result)
}
@Test
fun decrypt_pgp_mime_message_body_only() {
val encryptedMessage = """
@ -1669,72 +1595,4 @@ internal class CryptoTest {
)
}
@Test
fun get_public_key() {
val expected = """
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GopenPGP 0.0.1 (ddacebe0)
Comment: https://gopenpgp.org
xsBNBF1BfxUBCADUpiiG3AhQK08E2nBmQ50XeztOWArmknINQV41pqGFW5VQkfbQ
3FYsANhLGqbDBQ0XxmocjKL7W7W8Y4xmHCGgkCUy6gAqGbi+sXY9Sl8xqQNHuZDh
WVdqT8+Rtv+DRxp/XrGkzC1U8CBYUmmKS92ldy0/zZIvgQXT6t5Q+v+BeUSv4jCs
nY3BE0UBOljtrTXlOcXRZHQxORWG+kon0qgcJERdwwzhxY6eT8jEfAfJY0hzQaYg
+6bj6ZR0zkMtY2Psq2M05kzEw4On/dezZETAu1e9fSqfk1mp+H6BeLJ9RUyrFK/P
qIO48+pU8CmAvTdx5eIihyOM16CFg/3GgV85ABEBAAHNMWFkYW10c3RAcHJvdG9u
bWFpbC5ibHVlIDxhZGFtdHN0QHByb3Rvbm1haWwuYmx1ZT7CwGgEEwEIABwFAl1B
fxUJEBHDHo5eB/TQAhsDAhkBAgsJAhUIAADHoggACDYDZkyTMZX69k9uoAygAQ75
2kb52r0L3dSLge+hUelxJOiVUznbavzVhzjzF2FucXP0csOSJygHNejjS62BDtsX
iIoPiVDO1+Hr72X4gE277VeZ1b6VozJvKC0+H4fhg/EtkD07oVhHJRxOOVlgUXGK
nP2lz2ojny0McggvN+Nk8ILqt6ImlvEk6CnTs9XdmcmosMiQU+U+THKrKZ+5Yec8
4kzlHG8ee7Tim2yn9n/FuBStrYkTJUsDuAL/LOfF9DnzTzukK6kqpDB6kDfMeYQJ
Lq+Tu642n74P0lqOO0Wy7imI/hxM1W8yqcNdafS7PCuGHD99mecdKWVeYHCCY87A
TQRdQX8VAQgAyAIj6ytLB1CUinP6f6aVKlLSM9e9Figv1CAw53NHeQBbmwzU5bZn
tE6UERnvJy6ul7hJr9Jop+O1/jA6zaGanF5wv0nEvTHcoYRpJ4QiJgiQxvhOdItH
29+jBV1F44xOzlGnEzFAv7GbPecKHAsQgX9qYCj+5ydcttQ29gWQ6nN23G03R3Lb
KRS9H2uw1SIYGgif8FgKpJemwJjuSibyViXTf3JC8ZUtYbq+vIXqATFFtbrUHfKM
AKlHo0uLYGq1rRINGR6Dmhu6bGhZonuW0na4+5Wh86kg9c/YI7jSIIspRRkH+v7+
RXH51h8Rbc2Tiv64qy7cIJIH0Bk0lFAaIQARAQABwsBfBBgBCAATBQJdQX8VCRAR
wx6OXgf00AIbDAAAgvAIAGyLaHYTjiXG/ORIIAgdQhKBYOozrOS4EcOPNdMSPBwT
6P+BpNS/GD33pzANVKM9Mft8+NnePUFOR2f4QJrQ1VvSj9ko8P2sX7IAe7+rG614
LQfzjG5R16KlSVOMFW0K2L8ZxumDdYl/N0BhgtZmB1lg1xY2TPHoDetznMnHG8sL
6u6vyhGl5a6qcW2g1urlF0VF/CEqg1lwAKhFHIFiNR+X6jCjg0KJa9MjAW6oICOx
oX0jp195mWix6suRJSWVK14uieT6uL5yYC5tZMz+t9rs7YxCkHxFRT1H5ZLHUD/r
93liqW+pzUx+bVdz5qNMb0ZonHZRLe3/Fzb19x8UMPc=
=6gp8
-----END PGP PUBLIC KEY BLOCK-----
""".trimIndent()
val armoredKey = Armor.armorKey(openPgp.getPublicKey(oneAddressKeyAddressKeys[0].privateKey))
assertEquals(expected, armoredKey)
}
@Test
fun generate_token_and_signature_private_user() {
every { userManagerMock.currentUser } returns oneKeyUserMock
every { userManagerMock.getCurrentUserPassphrase() } returns passphrase
runBlocking {
val (token, signature) =
GenerateTokenAndSignature(userManagerMock, openPgpMock).invoke("")
val testMessage = newPGPMessageFromArmored(token)
val testKey = newKeyFromArmored(armoredPrivateKey)
val unlocked = testKey.unlock(passphrase)
val verificationKeyRing = newKeyRing(unlocked)
val decryptedTokenPlainMessage = verificationKeyRing.decrypt(testMessage, null, 0)
val decryptedTokenString = decryptedTokenPlainMessage.string
assertEquals(randomTokenString, decryptedTokenString)
val armoredSignature = newPGPSignatureFromArmored(signature)
verificationKeyRing.verifyDetached(
decryptedTokenPlainMessage, armoredSignature, com.proton.gopenpgp.crypto.Crypto.getUnixTime()
)
}
}
@Test
@Ignore("Pending implementation")
fun generate_token_and_signature_org() {
}
}

View File

@ -1,115 +0,0 @@
/*
* Copyright (c) 2020 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail 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.
*
* ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.crypto.factories
import androidx.test.filters.SmallTest
import ch.protonmail.android.api.models.MessageRecipient
import ch.protonmail.android.api.models.SendPreference
import ch.protonmail.android.api.models.enumerations.MIMEType
import ch.protonmail.android.api.models.enumerations.PackageType
import ch.protonmail.android.api.models.factories.MessageSecurityOptions
import ch.protonmail.android.api.models.factories.PackageFactory
import ch.protonmail.android.crypto.AddressCrypto
import ch.protonmail.android.crypto.CipherText
import ch.protonmail.android.data.local.model.Message
import ch.protonmail.android.utils.HTMLToMDConverter
import ch.protonmail.android.utils.base64.Base64Encoder
import com.proton.gopenpgp.crypto.SessionKey
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
import io.mockk.impl.annotations.RelaxedMockK
import io.mockk.mockk
import io.mockk.verify
import me.proton.core.domain.entity.UserId
import me.proton.core.user.domain.entity.AddressId
import kotlin.test.BeforeTest
import kotlin.test.Test
@SmallTest
class PackageFactoryTest {
@MockK
private lateinit var addressCryptoFactory: AddressCrypto.Factory
@RelaxedMockK
private lateinit var base64Encoder: Base64Encoder
@RelaxedMockK
private lateinit var htmlToMDConverter: HTMLToMDConverter
@InjectMockKs
private lateinit var packageFactory: PackageFactory
@BeforeTest
fun setUp() {
MockKAnnotations.init(this)
}
@Test
fun generatePackagesCreatesTopLevelPackageWithDataFromCryptoWhenSendPreferencesForRecipientsAreNotEmpty() {
val addressId = "addressId"
val message = Message(
addressID = addressId,
toList = listOf(MessageRecipient("recipient234", "email823@pm.me")),
messageBody = "Some message body"
)
val preferencesPublicKey = "publicKey"
val preferences = listOf(
SendPreference(
"email823@pm.me",
true,
true,
MIMEType.PLAINTEXT,
preferencesPublicKey,
PackageType.PGP_MIME,
false,
true,
false,
false
)
)
val securityOptions = MessageSecurityOptions("pwd", "hint", 180000L)
val crypto = mockk<AddressCrypto>()
val bodyPlainText = "html converted to plainText"
val keyPackage = "cipherTextKeyPacket".toByteArray()
val cipherText = mockk<CipherText>() {
every { keyPacket } returns keyPackage
every { dataPacket } returns "dataPacket".toByteArray()
}
val currentUsername = "Marino"
val currentUserId = UserId("marino")
every { base64Encoder.encode(any()) } returns "encodedBase64"
every { addressCryptoFactory.create(currentUserId, AddressId(addressId)) } returns crypto
every { htmlToMDConverter.convert(any()) } returns bodyPlainText
every { crypto.encrypt(bodyPlainText, true) } returns cipherText
every { crypto.decryptKeyPacket(keyPackage) } returns "decryptedKeyPackets".toByteArray()
every { crypto.encryptKeyPacket(any(), any()) } returns "encryptedKeyPackets".toByteArray()
every { crypto.getSessionKey(keyPackage) } returns SessionKey("token".toByteArray(), "algorithm")
packageFactory.generatePackages(message, preferences, securityOptions, currentUserId)
verify { crypto.decryptKeyPacket(any()) }
verify { crypto.getSessionKey(any()) }
verify { crypto.encryptKeyPacket(any(), any()) }
}
}

View File

@ -1,144 +0,0 @@
/*
* Copyright (c) 2020 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail 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.
*
* ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.labels.data.mapper
import ch.protonmail.android.labels.data.local.model.LabelEntity
import ch.protonmail.android.labels.domain.model.LabelId
import ch.protonmail.android.labels.domain.model.LabelOrFolderWithChildren
import ch.protonmail.android.labels.domain.model.LabelType
import kotlinx.coroutines.test.runBlockingTest
import me.proton.core.domain.entity.UserId
import me.proton.core.test.kotlin.TestDispatcherProvider
import me.proton.core.util.kotlin.EMPTY_STRING
import org.junit.FixMethodOrder
import org.junit.runners.MethodSorters
import kotlin.system.measureTimeMillis
import kotlin.test.BeforeTest
import kotlin.test.Ignore
import kotlin.test.Test
@Suppress("PrivatePropertyName") // `_` for readability purpose on big numbers
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Ignore("Benchmarks are useful only when observed, not needed to run for every pipeline")
class LabelOrFolderWithChildrenMapperBenchmarks {
private val mapper = LabelOrFolderWithChildrenMapper(TestDispatcherProvider)
private lateinit var data50parents100children: List<LabelEntity>
private lateinit var data200parents800children: List<LabelEntity>
private lateinit var data1_000parents10_000children: List<LabelEntity>
private lateinit var data2_000parents18_000children: List<LabelEntity>
@BeforeTest
fun setupLists() {
fun buildList(parentsCount: Int, childrenCount: Int): List<LabelEntity> {
val parents = 1..parentsCount
val children = parentsCount + 1..childrenCount + parentsCount
val all = parents + children
return parents.map { name -> buildLabelEntity(name.toString()) } +
children.map { name -> buildLabelEntity(name.toString(), parent = all.random().toString()) }
}
data50parents100children = buildList(parentsCount = 50, childrenCount = 100)
data200parents800children = buildList(parentsCount = 200, childrenCount = 800)
data1_000parents10_000children = buildList(parentsCount = 1_000, childrenCount = 10_000)
data2_000parents18_000children = buildList(parentsCount = 10_000, childrenCount = 18_000)
}
@Test
fun test1with50parents100children() = runBlockingTest {
runBenchmark("50-100", data50parents100children)
}
@Test
fun test2with200parents800children() = runBlockingTest {
runBenchmark("200-800", data200parents800children)
}
@Test
fun test3with1_000parents10_000children() = runBlockingTest {
runBenchmark("1.000-10.000", data1_000parents10_000children)
}
@Test
fun test4with2_000parents18_000children() = runBlockingTest {
runBenchmark("2.000-18.000", data2_000parents18_000children)
}
private suspend fun runBenchmark(
@Suppress("unused") traceName: String,
input: List<LabelEntity>,
shouldPrintOutput: Boolean = false
) {
// when
var result: List<LabelOrFolderWithChildren>
val time = measureTimeMillis {
// Debug.startMethodTracing(traceName)
result = mapper.toLabelsAndFoldersWithChildren(input)
// Debug.stopMethodTracing()
}
// then
println(time)
if (shouldPrintOutput) println(result.prettyPrint())
}
private fun buildLabelEntity(
name: String,
type: LabelType = LabelType.FOLDER,
parent: String = EMPTY_STRING
) = LabelEntity(
id = LabelId(name),
userId = UserId("user"),
name = name,
color = EMPTY_STRING,
order = 0,
type = type,
path = EMPTY_STRING,
parentId = parent,
expanded = 0,
sticky = 0,
notify = 0
)
}
fun List<LabelOrFolderWithChildren>.prettyPrint(): String =
joinToString(separator = ",\n") { it.prettyPrint() }
private fun Collection<LabelOrFolderWithChildren>.joinToString(hasParent: Boolean): String {
return if (isEmpty()) {
EMPTY_STRING
} else {
val itemPadding = if (hasParent) " " else " "
val bracketPadding = if (hasParent) " " else ""
" {\n${joinToString(separator = ",\n") { "$itemPadding${it.prettyPrint()}" }}\n$bracketPadding}"
}
}
private fun LabelOrFolderWithChildren.prettyPrint(): String {
return when (this) {
is LabelOrFolderWithChildren.Folder -> {
val name = "name: $name"
val parent = if (parentId == null) EMPTY_STRING else " - parent: $parentId"
"$name$parent${children.joinToString(parentId != null)}"
}
is LabelOrFolderWithChildren.Label -> name
}
}

View File

@ -19,25 +19,14 @@
package ch.protonmail.android.ui.view
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withClassName
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
import ch.protonmail.android.R
import ch.protonmail.android.ui.view.DaysAndHoursPickerView.Companion.MAX_DAYS
import ch.protonmail.android.ui.view.DaysAndHoursPickerView.Companion.MAX_HOURS
import ch.protonmail.android.util.ViewTest
import com.google.android.material.textfield.TextInputEditText
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.launch
import me.proton.core.test.kotlin.CoroutinesTest
import org.hamcrest.Matchers.`is`
import org.hamcrest.core.AllOf
import org.junit.runner.RunWith
import kotlin.test.Test
import kotlin.test.assertEquals
@ -48,112 +37,6 @@ import kotlin.test.assertEquals
@RunWith(AndroidJUnit4ClassRunner::class)
class DaysAndHoursPickerViewTest : ViewTest<DaysAndHoursPickerView>(::DaysAndHoursPickerView), CoroutinesTest {
// Days
@Test
fun daysAreNotChangedIfCorrect() {
// given
val input = 14
// when
testView.set(days = input, hours = 0)
// then
onDaysView().check(matches(withText("14")))
}
@Test
fun daysAreSetToZeroIfBelowZero() {
// given
val input = -14
// when
testView.set(days = input, hours = 0)
// then
onDaysView().check(matches(withText("0")))
}
@Test
fun daysAreSetToMaxIfTooHigh() {
// given
val input = 999
// when
testView.set(days = input, hours = 0)
// then
onDaysView().check(matches(withText("$MAX_DAYS")))
}
@Test
fun daysAreSetToZeroIfInvalidInput() {
// given
val input = "hello"
// when
onDaysView().perform(ViewActions.typeText(input))
// then
onDaysView().check(matches(withText("0")))
}
// Hours
@Test
fun hoursAreNotChangedIfCorrect() {
// given
val input = 14
// when
testView.set(days = 0, hours = input)
// then
onHoursView().check(matches(withText("14")))
}
@Test
fun hoursAreSetToZeroIfBelowZero() {
// given
val input = -14
// when
testView.set(days = 0, hours = input)
// then
onHoursView().check(matches(withText("0")))
}
@Test
fun hoursAreSetToMaxIfTooHigh() {
// given
val input = 999
// when
testView.set(days = 0, hours = input)
// then
onHoursView().check(matches(withText("$MAX_HOURS")))
}
@Test
fun hoursAreSetToZeroIfInvalidInput() {
// given
val input = "hello"
// when
onHoursView().perform(ViewActions.typeText(input))
// then
onHoursView().check(matches(withText("0")))
}
// Callback
@Test
fun callbackIsNotCalledIfSetSameHourOrDay() = coroutinesTest {
@ -207,20 +90,4 @@ class DaysAndHoursPickerViewTest : ViewTest<DaysAndHoursPickerView>(::DaysAndHou
job.cancel()
}
private fun onDaysView(): ViewInteraction =
onView(
AllOf.allOf(
withId(R.id.days_and_hours_picker_days_input),
withClassName(`is`(TextInputEditText::class.qualifiedName))
)
)
private fun onHoursView(): ViewInteraction =
onView(
AllOf.allOf(
withId(R.id.days_and_hours_picker_hours_input),
withClassName(`is`(TextInputEditText::class.qualifiedName))
)
)
}

View File

@ -52,13 +52,6 @@ class SingleLineCollapsedLabelGroupViewTest :
onTestView().check(isGone())
}
@Test
fun whenHasLabelsShouldShowTheView() {
testView.setLabels(LabelList.withThreeItems)
onTestView().check(isVisible())
}
@Test
fun whenHasThreeLabelsShouldShowThemAllWithoutMoreTextView() {
runOnActivityThread {

View File

@ -19,37 +19,15 @@
package ch.protonmail.android.ui.view
import android.graphics.Color
import android.view.View
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
import ch.protonmail.android.labels.domain.model.LabelId
import ch.protonmail.android.domain.entity.Name
import ch.protonmail.android.testAndroidInstrumented.assertion.isGone
import ch.protonmail.android.testAndroidInstrumented.assertion.isVisible
import ch.protonmail.android.testAndroidInstrumented.matcher.withBackgroundColor
import ch.protonmail.android.ui.model.LabelChipUiModel
import ch.protonmail.android.util.ViewTest
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.TypeSafeDiagnosingMatcher
import org.junit.runner.RunWith
import kotlin.test.Test
/**
* Test suite for [SingleLineLabelChipGroupView]
*/
@RunWith(AndroidJUnit4ClassRunner::class)
class SingleLineLabelChipGroupViewTest : ViewTest<SingleLineLabelChipGroupView>(::SingleLineLabelChipGroupView) {
private val testLabelsList = listOf(
LabelChipUiModel(LabelId("a"), Name("first"), Color.RED),
LabelChipUiModel(LabelId("b"), Name("second"), Color.GREEN),
LabelChipUiModel(LabelId("c"), Name("third"), Color.BLUE),
)
@Test
fun viewIsGoneWhenNoLabels() {
@ -60,44 +38,4 @@ class SingleLineLabelChipGroupViewTest : ViewTest<SingleLineLabelChipGroupView>(
onTestView().check(isGone())
}
@Test
fun viewIsVisibleWhenHasLabels() {
// given - when
testView.setLabels(testLabelsList)
// then
onTestView().check(isVisible())
}
@Test
fun firstLabelShowsTheCorrectNameAndColor() {
val chipGroupView = testView
// given
val labels = testLabelsList
val (expectedLabelId, expectedLabelName, expectedLabelColor) = with(labels.first()) {
Triple(id, name.s, checkNotNull(color))
}
// when
chipGroupView.setLabels(labels)
// then
onView(withLabelId(expectedLabelId))
.check(matches(withText(expectedLabelName)))
.check(matches(withBackgroundColor(expectedLabelColor)))
}
private fun withLabelId(labelId: LabelId): Matcher<View> {
return object : TypeSafeDiagnosingMatcher<View>() {
override fun matchesSafely(item: View, mismatchDescription: Description) =
(item as? LabelChipView)?.labelId == labelId
override fun describeTo(description: Description) {
description.appendText("Label id: ${labelId.id}")
}
}
}
}

View File

@ -1,57 +0,0 @@
/*
* Copyright (c) 2020 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail 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.
*
* ProtonMail 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 ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.views.messageDetails
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
import ch.protonmail.android.R
import ch.protonmail.android.testAndroidInstrumented.assertion.isGone
import ch.protonmail.android.testAndroidInstrumented.assertion.isVisible
import ch.protonmail.android.util.ViewTest
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4ClassRunner::class)
class MessageDetailsHeaderViewTest : ViewTest<MessageDetailsHeaderView>(::MessageDetailsHeaderView) {
@Test
fun shouldHideCollapsedMessageViews() {
runOnActivityThread {
testView.showCollapsedMessageViews()
testView.hideCollapsedMessageViews()
}
onCollapsedMessageView().check(isGone())
}
@Test
fun shouldShowCollapsedMessageViews() {
runOnActivityThread {
testView.hideCollapsedMessageViews()
testView.showCollapsedMessageViews()
}
onCollapsedMessageView().check(isVisible())
}
private fun onCollapsedMessageView(): ViewInteraction = onView(withId(R.id.collapsedMessageViews))
}