Delete temporary created files.
This commit is contained in:
parent
0c841442d9
commit
585b6a94f3
10 changed files with 328 additions and 89 deletions
|
|
@ -22,6 +22,7 @@ import androidx.core.net.toUri
|
|||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import io.element.android.libraries.androidutils.file.TemporaryUriDeleter
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
||||
|
|
@ -43,6 +44,7 @@ class EditUserProfilePresenter @AssistedInject constructor(
|
|||
private val matrixClient: MatrixClient,
|
||||
private val mediaPickerProvider: PickerProvider,
|
||||
private val mediaPreProcessor: MediaPreProcessor,
|
||||
private val temporaryUriDeleter: TemporaryUriDeleter,
|
||||
permissionsPresenterFactory: PermissionsPresenter.Factory,
|
||||
) : Presenter<EditUserProfileState> {
|
||||
private val cameraPermissionPresenter: PermissionsPresenter = permissionsPresenterFactory.create(android.Manifest.permission.CAMERA)
|
||||
|
|
@ -59,10 +61,20 @@ class EditUserProfilePresenter @AssistedInject constructor(
|
|||
var userAvatarUri by rememberSaveable { mutableStateOf(matrixUser.avatarUrl?.let { Uri.parse(it) }) }
|
||||
var userDisplayName by rememberSaveable { mutableStateOf(matrixUser.displayName) }
|
||||
val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker(
|
||||
onResult = { uri -> if (uri != null) userAvatarUri = uri }
|
||||
onResult = { uri ->
|
||||
if (uri != null) {
|
||||
temporaryUriDeleter.delete(userAvatarUri)
|
||||
userAvatarUri = uri
|
||||
}
|
||||
}
|
||||
)
|
||||
val galleryImagePicker = mediaPickerProvider.registerGalleryImagePicker(
|
||||
onResult = { uri -> if (uri != null) userAvatarUri = uri }
|
||||
onResult = { uri ->
|
||||
if (uri != null) {
|
||||
temporaryUriDeleter.delete(userAvatarUri)
|
||||
userAvatarUri = uri
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
val avatarActions by remember(userAvatarUri) {
|
||||
|
|
@ -96,7 +108,10 @@ class EditUserProfilePresenter @AssistedInject constructor(
|
|||
pendingPermissionRequest = true
|
||||
cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions)
|
||||
}
|
||||
AvatarAction.Remove -> userAvatarUri = null
|
||||
AvatarAction.Remove -> {
|
||||
temporaryUriDeleter.delete(userAvatarUri)
|
||||
userAvatarUri = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import app.cash.molecule.RecompositionMode
|
|||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.androidutils.file.TemporaryUriDeleter
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
|
|
@ -29,6 +30,9 @@ import io.element.android.libraries.permissions.test.FakePermissionsPresenterFac
|
|||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.consumeItemsUntilPredicate
|
||||
import io.element.android.tests.testutils.consumeItemsUntilTimeout
|
||||
import io.element.android.tests.testutils.fake.FakeTemporaryUriDeleter
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import io.element.android.tests.testutils.lambda.value
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
|
|
@ -73,12 +77,14 @@ class EditUserProfilePresenterTest {
|
|||
matrixClient: MatrixClient = FakeMatrixClient(),
|
||||
matrixUser: MatrixUser = aMatrixUser(),
|
||||
permissionsPresenter: PermissionsPresenter = FakePermissionsPresenter(),
|
||||
temporaryUriDeleter: TemporaryUriDeleter = FakeTemporaryUriDeleter(),
|
||||
): EditUserProfilePresenter {
|
||||
return EditUserProfilePresenter(
|
||||
matrixClient = matrixClient,
|
||||
matrixUser = matrixUser,
|
||||
mediaPickerProvider = fakePickerProvider,
|
||||
mediaPreProcessor = fakeMediaPreProcessor,
|
||||
temporaryUriDeleter = temporaryUriDeleter,
|
||||
permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionsPresenter),
|
||||
)
|
||||
}
|
||||
|
|
@ -107,7 +113,12 @@ class EditUserProfilePresenterTest {
|
|||
@Test
|
||||
fun `present - updates state in response to changes`() = runTest {
|
||||
val user = aMatrixUser(id = A_USER_ID.value, displayName = "Name", avatarUrl = AN_AVATAR_URL)
|
||||
val presenter = createEditUserProfilePresenter(matrixUser = user)
|
||||
val presenter = createEditUserProfilePresenter(
|
||||
matrixUser = user,
|
||||
temporaryUriDeleter = FakeTemporaryUriDeleter(
|
||||
deleteCallback = { assertThat(it).isEqualTo(userAvatarUri) }
|
||||
),
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -136,7 +147,12 @@ class EditUserProfilePresenterTest {
|
|||
fun `present - obtains avatar uris from gallery`() = runTest {
|
||||
val user = aMatrixUser(id = A_USER_ID.value, displayName = "Name", avatarUrl = AN_AVATAR_URL)
|
||||
fakePickerProvider.givenResult(anotherAvatarUri)
|
||||
val presenter = createEditUserProfilePresenter(matrixUser = user)
|
||||
val presenter = createEditUserProfilePresenter(
|
||||
matrixUser = user,
|
||||
temporaryUriDeleter = FakeTemporaryUriDeleter(
|
||||
deleteCallback = { assertThat(it).isEqualTo(userAvatarUri) }
|
||||
),
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -154,9 +170,13 @@ class EditUserProfilePresenterTest {
|
|||
val user = aMatrixUser(id = A_USER_ID.value, displayName = "Name", avatarUrl = AN_AVATAR_URL)
|
||||
fakePickerProvider.givenResult(anotherAvatarUri)
|
||||
val fakePermissionsPresenter = FakePermissionsPresenter()
|
||||
val deleteCallback = lambdaRecorder<Uri?, Unit> {}
|
||||
val presenter = createEditUserProfilePresenter(
|
||||
matrixUser = user,
|
||||
permissionsPresenter = fakePermissionsPresenter,
|
||||
temporaryUriDeleter = FakeTemporaryUriDeleter(
|
||||
deleteCallback = deleteCallback,
|
||||
),
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -177,6 +197,10 @@ class EditUserProfilePresenterTest {
|
|||
stateWithNewAvatar.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
||||
val stateWithNewAvatar2 = awaitItem()
|
||||
assertThat(stateWithNewAvatar2.userAvatarUrl).isEqualTo(userAvatarUri)
|
||||
deleteCallback.assertions().isCalledExactly(2).withSequence(
|
||||
listOf(value(userAvatarUri)),
|
||||
listOf(value(anotherAvatarUri)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -184,7 +208,13 @@ class EditUserProfilePresenterTest {
|
|||
fun `present - updates save button state`() = runTest {
|
||||
val user = aMatrixUser(id = A_USER_ID.value, displayName = "Name", avatarUrl = AN_AVATAR_URL)
|
||||
fakePickerProvider.givenResult(userAvatarUri)
|
||||
val presenter = createEditUserProfilePresenter(matrixUser = user)
|
||||
val deleteCallback = lambdaRecorder<Uri?, Unit> {}
|
||||
val presenter = createEditUserProfilePresenter(
|
||||
matrixUser = user,
|
||||
temporaryUriDeleter = FakeTemporaryUriDeleter(
|
||||
deleteCallback = deleteCallback
|
||||
),
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -210,6 +240,10 @@ class EditUserProfilePresenterTest {
|
|||
awaitItem().apply {
|
||||
assertThat(saveButtonEnabled).isFalse()
|
||||
}
|
||||
deleteCallback.assertions().isCalledExactly(2).withSequence(
|
||||
listOf(value(userAvatarUri)),
|
||||
listOf(value(null)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -217,7 +251,13 @@ class EditUserProfilePresenterTest {
|
|||
fun `present - updates save button state when initial values are null`() = runTest {
|
||||
val user = aMatrixUser(id = A_USER_ID.value, displayName = "Name", avatarUrl = null)
|
||||
fakePickerProvider.givenResult(userAvatarUri)
|
||||
val presenter = createEditUserProfilePresenter(matrixUser = user)
|
||||
val deleteCallback = lambdaRecorder<Uri?, Unit> {}
|
||||
val presenter = createEditUserProfilePresenter(
|
||||
matrixUser = user,
|
||||
temporaryUriDeleter = FakeTemporaryUriDeleter(
|
||||
deleteCallback = deleteCallback
|
||||
),
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -243,6 +283,10 @@ class EditUserProfilePresenterTest {
|
|||
awaitItem().apply {
|
||||
assertThat(saveButtonEnabled).isFalse()
|
||||
}
|
||||
deleteCallback.assertions().isCalledExactly(2).withSequence(
|
||||
listOf(value(null)),
|
||||
listOf(value(userAvatarUri)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -252,7 +296,10 @@ class EditUserProfilePresenterTest {
|
|||
val user = aMatrixUser(id = A_USER_ID.value, displayName = "Name", avatarUrl = AN_AVATAR_URL)
|
||||
val presenter = createEditUserProfilePresenter(
|
||||
matrixClient = matrixClient,
|
||||
matrixUser = user
|
||||
matrixUser = user,
|
||||
temporaryUriDeleter = FakeTemporaryUriDeleter(
|
||||
deleteCallback = { assertThat(it).isEqualTo(userAvatarUri) }
|
||||
),
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -318,7 +365,10 @@ class EditUserProfilePresenterTest {
|
|||
givenPickerReturnsFile()
|
||||
val presenter = createEditUserProfilePresenter(
|
||||
matrixClient = matrixClient,
|
||||
matrixUser = user
|
||||
matrixUser = user,
|
||||
temporaryUriDeleter = FakeTemporaryUriDeleter(
|
||||
deleteCallback = { assertThat(it).isEqualTo(userAvatarUri) }
|
||||
),
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -337,7 +387,10 @@ class EditUserProfilePresenterTest {
|
|||
val user = aMatrixUser(id = A_USER_ID.value, displayName = "Name", avatarUrl = AN_AVATAR_URL)
|
||||
val presenter = createEditUserProfilePresenter(
|
||||
matrixClient = matrixClient,
|
||||
matrixUser = user
|
||||
matrixUser = user,
|
||||
temporaryUriDeleter = FakeTemporaryUriDeleter(
|
||||
deleteCallback = { assertThat(it).isEqualTo(userAvatarUri) }
|
||||
),
|
||||
)
|
||||
fakePickerProvider.givenResult(anotherAvatarUri)
|
||||
fakeMediaPreProcessor.givenResult(Result.failure(Throwable("Oh no")))
|
||||
|
|
@ -403,7 +456,13 @@ class EditUserProfilePresenterTest {
|
|||
}
|
||||
|
||||
private suspend fun saveAndAssertFailure(matrixUser: MatrixUser, matrixClient: MatrixClient, event: EditUserProfileEvents) {
|
||||
val presenter = createEditUserProfilePresenter(matrixUser = matrixUser, matrixClient = matrixClient)
|
||||
val presenter = createEditUserProfilePresenter(
|
||||
matrixUser = matrixUser,
|
||||
matrixClient = matrixClient,
|
||||
temporaryUriDeleter = FakeTemporaryUriDeleter(
|
||||
deleteCallback = { assertThat(it).isEqualTo(userAvatarUri) }
|
||||
),
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue