Remove the send password (#579)

This commit is contained in:
David Perez
2024-01-11 20:06:30 -06:00
committed by GitHub
parent 2cf011a3d7
commit 4d386e1001
15 changed files with 375 additions and 13 deletions

View File

@@ -70,6 +70,32 @@ class SendsServiceTest : BaseServiceTest() {
val result = sendsService.deleteSend(sendId = "send-id-1")
assertEquals(Unit, result.getOrThrow())
}
@Test
fun `removeSendPassword with success response should return a Success with the correct send`() =
runTest {
server.enqueue(MockResponse().setBody(CREATE_UPDATE_SEND_SUCCESS_JSON))
val result = sendsService.removeSendPassword(sendId = "send-id-1")
assertEquals(
UpdateSendResponseJson.Success(send = createMockSend(number = 1)),
result.getOrThrow(),
)
}
@Suppress("MaxLineLength")
@Test
fun `removeSendPassword with an invalid response should return an Invalid with the correct data`() =
runTest {
server.enqueue(MockResponse().setResponseCode(400).setBody(UPDATE_SEND_INVALID_JSON))
val result = sendsService.removeSendPassword(sendId = "send-id-1")
assertEquals(
UpdateSendResponseJson.Invalid(
message = "You do not have permission to edit this.",
validationErrors = null,
),
result.getOrThrow(),
)
}
}
private const val CREATE_UPDATE_SEND_SUCCESS_JSON = """

View File

@@ -49,6 +49,7 @@ import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockSendView
import com.x8bit.bitwarden.data.vault.manager.VaultLockManager
import com.x8bit.bitwarden.data.vault.repository.model.CreateCipherResult
import com.x8bit.bitwarden.data.vault.repository.model.CreateSendResult
import com.x8bit.bitwarden.data.vault.repository.model.RemovePasswordSendResult
import com.x8bit.bitwarden.data.vault.repository.model.SendData
import com.x8bit.bitwarden.data.vault.repository.model.UpdateCipherResult
import com.x8bit.bitwarden.data.vault.repository.model.UpdateSendResult
@@ -1591,6 +1592,65 @@ class VaultRepositoryTest {
assertEquals(UpdateSendResult.Success(mockSendViewResult), result)
}
@Test
@Suppress("MaxLineLength")
fun `removePasswordSend with sendsService removeSendPassword Error should return RemovePasswordSendResult Error`() =
runTest {
fakeAuthDiskSource.userState = MOCK_USER_STATE
val sendId = "sendId1234"
val mockSendView = createMockSendView(number = 1)
coEvery {
sendsService.removeSendPassword(sendId = sendId)
} returns Throwable("Fail").asFailure()
val result = vaultRepository.removePasswordSend(sendId = sendId)
assertEquals(RemovePasswordSendResult.Error(errorMessage = null), result)
}
@Test
@Suppress("MaxLineLength")
fun `removePasswordSend with sendsService removeSendPassword Success and vaultSdkSource decryptSend Failure should return RemovePasswordSendResult Error`() =
runTest {
fakeAuthDiskSource.userState = MOCK_USER_STATE
val userId = "mockId-1"
val sendId = "sendId1234"
val mockSend = createMockSend(number = 1)
coEvery {
sendsService.removeSendPassword(sendId = sendId)
} returns UpdateSendResponseJson.Success(send = mockSend).asSuccess()
coEvery {
vaultSdkSource.decryptSend(userId = userId, send = createMockSdkSend(number = 1))
} returns Throwable("Fail").asFailure()
coEvery { vaultDiskSource.saveSend(userId = userId, send = mockSend) } just runs
val result = vaultRepository.removePasswordSend(sendId = sendId)
assertEquals(RemovePasswordSendResult.Error(errorMessage = null), result)
}
@Test
@Suppress("MaxLineLength")
fun `removePasswordSend with sendsService removeSendPassword Success should return RemovePasswordSendResult success`() =
runTest {
fakeAuthDiskSource.userState = MOCK_USER_STATE
val userId = "mockId-1"
val sendId = "sendId1234"
val mockSendView = createMockSendView(number = 1)
val mockSend = createMockSend(number = 1)
coEvery {
sendsService.removeSendPassword(sendId = sendId)
} returns UpdateSendResponseJson.Success(send = mockSend).asSuccess()
coEvery {
vaultSdkSource.decryptSend(userId = userId, send = createMockSdkSend(number = 1))
} returns mockSendView.asSuccess()
coEvery { vaultDiskSource.saveSend(userId = userId, send = mockSend) } just runs
val result = vaultRepository.removePasswordSend(sendId = sendId)
assertEquals(RemovePasswordSendResult.Success(mockSendView), result)
}
//region Helper functions
/**

View File

@@ -124,6 +124,24 @@ class AddSendScreenTest : BaseComposeTest() {
.isDisplayed()
}
@Test
fun `overflow remove password button should be hidden when hasPassword is false`() {
mutableStateFlow.value = DEFAULT_STATE.copy(
addSendType = AddSendType.EditItem(sendItemId = "sendId"),
viewState = DEFAULT_VIEW_STATE.copy(
common = DEFAULT_COMMON_STATE.copy(hasPassword = false),
),
)
composeTestRule
.onNodeWithContentDescription("More")
.performClick()
composeTestRule
.onNodeWithText("Remove password")
.assertDoesNotExist()
}
@Test
fun `on overflow remove password button click should send RemovePasswordClick`() {
mutableStateFlow.value = DEFAULT_STATE.copy(
@@ -790,6 +808,7 @@ class AddSendScreenTest : BaseComposeTest() {
deletionDate = ZonedDateTime.parse("2023-10-27T12:00:00Z"),
expirationDate = null,
sendUrl = null,
hasPassword = true,
)
private val DEFAULT_SELECTED_TYPE_STATE = AddSendState.ViewState.Content.SendType.Text(

View File

@@ -12,6 +12,7 @@ import com.x8bit.bitwarden.data.platform.repository.model.Environment
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockSendView
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
import com.x8bit.bitwarden.data.vault.repository.model.CreateSendResult
import com.x8bit.bitwarden.data.vault.repository.model.RemovePasswordSendResult
import com.x8bit.bitwarden.data.vault.repository.model.UpdateSendResult
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
import com.x8bit.bitwarden.ui.platform.base.util.asText
@@ -292,18 +293,127 @@ class AddSendViewModelTest : BaseViewModelTest() {
}
@Test
fun `RemovePasswordClick should send ShowToast`() = runTest {
val viewModel = createViewModel(
state = DEFAULT_STATE.copy(addSendType = AddSendType.EditItem("sendId")),
addSendType = AddSendType.EditItem("sendId"),
)
fun `in add item state, RemovePasswordClick should do nothing`() = runTest {
val viewModel = createViewModel()
viewModel.eventFlow.test {
viewModel.trySendAction(AddSendAction.RemovePasswordClick)
assertEquals(AddSendEvent.ShowToast("Not yet implemented".asText()), awaitItem())
expectNoEvents()
}
}
@Suppress("MaxLineLength")
@Test
fun `in edit item state, RemovePasswordClick vaultRepository removePasswordSend Error without message should show default error dialog`() =
runTest {
val sendId = "mockId-1"
coEvery {
vaultRepository.removePasswordSend(sendId)
} returns RemovePasswordSendResult.Error(errorMessage = null)
val initialState = DEFAULT_STATE.copy(
addSendType = AddSendType.EditItem(sendItemId = sendId),
)
val mockSendView = createMockSendView(number = 1)
every {
mockSendView.toViewState(clock, DEFAULT_ENVIRONMENT_URL)
} returns DEFAULT_VIEW_STATE
mutableSendDataStateFlow.value = DataState.Loaded(mockSendView)
val viewModel = createViewModel(
state = initialState,
addSendType = AddSendType.EditItem(sendItemId = sendId),
)
viewModel.stateFlow.test {
assertEquals(initialState, awaitItem())
viewModel.trySendAction(AddSendAction.RemovePasswordClick)
assertEquals(
initialState.copy(
dialogState = AddSendState.DialogState.Loading(
message = R.string.removing_send_password.asText(),
),
),
awaitItem(),
)
assertEquals(
initialState.copy(
dialogState = AddSendState.DialogState.Error(
title = R.string.an_error_has_occurred.asText(),
message = R.string.generic_error_message.asText(),
),
),
awaitItem(),
)
}
}
@Suppress("MaxLineLength")
@Test
fun `in edit item state, RemovePasswordClick vaultRepository removePasswordSend Error with message should show error dialog with message`() =
runTest {
val sendId = "mockId-1"
val errorMessage = "Fail"
coEvery {
vaultRepository.removePasswordSend(sendId)
} returns RemovePasswordSendResult.Error(errorMessage = errorMessage)
val mockSendView = createMockSendView(number = 1)
every {
mockSendView.toViewState(clock, DEFAULT_ENVIRONMENT_URL)
} returns DEFAULT_VIEW_STATE
mutableSendDataStateFlow.value = DataState.Loaded(mockSendView)
val initialState = DEFAULT_STATE.copy(
addSendType = AddSendType.EditItem(sendItemId = sendId),
)
val viewModel = createViewModel(
state = initialState,
addSendType = AddSendType.EditItem(sendItemId = sendId),
)
viewModel.stateFlow.test {
assertEquals(initialState, awaitItem())
viewModel.trySendAction(AddSendAction.RemovePasswordClick)
assertEquals(
initialState.copy(
dialogState = AddSendState.DialogState.Loading(
message = R.string.removing_send_password.asText(),
),
),
awaitItem(),
)
assertEquals(
initialState.copy(
dialogState = AddSendState.DialogState.Error(
title = R.string.an_error_has_occurred.asText(),
message = errorMessage.asText(),
),
),
awaitItem(),
)
}
}
@Suppress("MaxLineLength")
@Test
fun `in edit item state, RemovePasswordClick vaultRepository removePasswordSend Success should show toast`() =
runTest {
val sendId = "mockId-1"
val mockSendView = createMockSendView(number = 1)
coEvery {
vaultRepository.removePasswordSend(sendId)
} returns RemovePasswordSendResult.Success(mockSendView)
val viewModel = createViewModel(
state = DEFAULT_STATE.copy(addSendType = AddSendType.EditItem(sendItemId = sendId)),
addSendType = AddSendType.EditItem(sendItemId = sendId),
)
viewModel.eventFlow.test {
viewModel.trySendAction(AddSendAction.RemovePasswordClick)
assertEquals(
AddSendEvent.ShowToast(R.string.send_password_removed.asText()),
awaitItem(),
)
}
}
@Test
fun `ShareLinkClick should send ShowToast`() = runTest {
val viewModel = createViewModel(
@@ -605,6 +715,7 @@ class AddSendViewModelTest : BaseViewModelTest() {
deletionDate = ZonedDateTime.parse("2023-11-03T00:00Z"),
expirationDate = null,
sendUrl = null,
hasPassword = false,
)
private val DEFAULT_SELECTED_TYPE_STATE = AddSendState.ViewState.Content.SendType.Text(

View File

@@ -70,6 +70,7 @@ private val DEFAULT_COMMON_STATE = AddSendState.ViewState.Content.Common(
deletionDate = ZonedDateTime.parse("2023-10-27T12:00:00Z"),
expirationDate = ZonedDateTime.parse("2023-10-27T12:00:00Z"),
sendUrl = null,
hasPassword = false,
)
private val DEFAULT_SELECTED_TYPE_STATE = AddSendState.ViewState.Content.SendType.Text(

View File

@@ -60,6 +60,7 @@ private val DEFAULT_COMMON: AddSendState.ViewState.Content.Common =
ZoneOffset.UTC,
),
sendUrl = "www.test.com/mockAccessId-1/mockKey-1",
hasPassword = true,
)
private val DEFAULT_TEXT_TYPE: AddSendState.ViewState.Content.SendType.Text =