Updated DeleteAttachmentWorker and test after rebase to hilt branch.

MAILAND-927
This commit is contained in:
Tomasz Giszczak 2020-09-23 16:24:32 +02:00
parent e6075f7b59
commit d9803f595d
4 changed files with 148 additions and 95 deletions

View File

@ -1,76 +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.worker
import android.content.Context
import androidx.test.platform.app.InstrumentationRegistry
import androidx.work.ListenableWorker
import androidx.work.testing.TestListenableWorkerBuilder
import androidx.work.workDataOf
import ch.protonmail.android.attachments.KEY_INPUT_DATA_ATTACHMENT_ID_STRING
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
class DeleteAttachmentWorkerTest {
private lateinit var context: Context
@Before
fun setUp() {
context = InstrumentationRegistry.getInstrumentation().targetContext
}
@Test
fun verifyWorkerFailsWithNoAttachmentIdProvided() {
// given
val worker =
TestListenableWorkerBuilder<DeleteAttachmentWorker>(context).build()
val expected = ListenableWorker.Result.failure(
workDataOf(KEY_WORKER_ERROR_DESCRIPTION to "Cannot delete attachment with an empty id")
)
// when
val result = worker.startWork().get()
// then
assertEquals(expected, result)
}
@Ignore("Ignored until integration of new network module and a way of mocking net calls")
@Test
fun verifyWorkerSucceedsWithStringAttachmentIdProvided() {
// given
val attachemtId = "id232"
val worker = TestListenableWorkerBuilder<DeleteAttachmentWorker>(
context = context,
inputData = workDataOf(KEY_INPUT_DATA_ATTACHMENT_ID_STRING to attachemtId)
).build()
val expected = ListenableWorker.Result.success()
// when
val result = worker.startWork().get()
// then
assertEquals(expected, result)
}
}

View File

@ -82,7 +82,7 @@ import ch.protonmail.android.utils.DownloadUtils;
import ch.protonmail.android.utils.Logger;
import ch.protonmail.android.utils.extensions.TextExtensions;
import ch.protonmail.android.utils.ui.dialogs.DialogUtils;
import dagger.android.AndroidInjection;
import dagger.hilt.android.AndroidEntryPoint;
import kotlin.Unit;
import kotlin.collections.ArraysKt;
import kotlin.collections.CollectionsKt;
@ -91,6 +91,7 @@ import timber.log.Timber;
import static ch.protonmail.android.attachments.ImportAttachmentsWorkerKt.KEY_INPUT_DATA_DELETE_ORIGINAL_FILE_BOOLEAN;
import static ch.protonmail.android.attachments.ImportAttachmentsWorkerKt.KEY_INPUT_DATA_FILE_URIS_STRING_ARRAY;
@AndroidEntryPoint
public class AddAttachmentsActivity extends BaseStoragePermissionActivity implements AttachmentListAdapter.IAttachmentListener {
private static final String TAG_ADD_ATTACHMENTS_ACTIVITY = "AddAttachmentsActivity";
@ -197,7 +198,6 @@ public class AddAttachmentsActivity extends BaseStoragePermissionActivity implem
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
messagesDatabase = MessagesDatabaseFactory.Companion.getInstance(
getApplicationContext()).getDatabase();

View File

@ -20,6 +20,8 @@
package ch.protonmail.android.worker
import android.content.Context
import androidx.hilt.Assisted
import androidx.hilt.work.WorkerInject
import androidx.work.Constraints
import androidx.work.CoroutineWorker
import androidx.work.NetworkType
@ -29,15 +31,14 @@ import androidx.work.WorkManager
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import ch.protonmail.android.api.ProtonMailApiManager
import ch.protonmail.android.api.models.room.messages.MessagesDao
import ch.protonmail.android.api.models.room.messages.MessagesDatabase
import ch.protonmail.android.api.segments.RESPONSE_CODE_ATTACHMENT_DELETE_ID_INVALID
import ch.protonmail.android.attachments.KEY_INPUT_DATA_ATTACHMENT_ID_STRING
import ch.protonmail.android.core.Constants
import ch.protonmail.android.utils.extensions.app
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import me.proton.core.util.kotlin.DispatcherProvider
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Named
internal const val KEY_WORKER_ERROR_DESCRIPTION = "KeyWorkerErrorDescription"
@ -50,18 +51,13 @@ internal const val KEY_WORKER_ERROR_DESCRIPTION = "KeyWorkerErrorDescription"
*
* @see androidx.work.WorkManager
*/
class DeleteAttachmentWorker(context: Context, params: WorkerParameters) :
CoroutineWorker(context, params) {
@Inject
internal lateinit var api: ProtonMailApiManager
@Inject
internal lateinit var messagesDatabase: MessagesDao
init {
context.app.appComponent.inject(this)
}
class DeleteAttachmentWorker @WorkerInject constructor(
@Assisted context: Context,
@Assisted params: WorkerParameters,
private val api: ProtonMailApiManager,
@Named("messages") var messagesDatabase: MessagesDatabase,
private val dispatchers: DispatcherProvider
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
val attachmentId = inputData.getString(KEY_INPUT_DATA_ATTACHMENT_ID_STRING) ?: ""
@ -75,7 +71,7 @@ class DeleteAttachmentWorker(context: Context, params: WorkerParameters) :
Timber.v("Delete attachmentId ID: $attachmentId")
return withContext(Dispatchers.IO) {
return withContext(dispatchers.Io) {
val response = api.deleteAttachment(attachmentId)
if (response.code == Constants.RESPONSE_CODE_OK ||

View File

@ -0,0 +1,133 @@
/*
* 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.worker
import android.content.Context
import androidx.work.ListenableWorker
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import ch.protonmail.android.api.ProtonMailApiManager
import ch.protonmail.android.api.models.ResponseBody
import ch.protonmail.android.api.models.room.messages.Attachment
import ch.protonmail.android.api.models.room.messages.MessagesDao
import ch.protonmail.android.attachments.KEY_INPUT_DATA_ATTACHMENT_ID_STRING
import ch.protonmail.android.core.Constants
import io.mockk.MockKAnnotations
import io.mockk.coEvery
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.impl.annotations.RelaxedMockK
import io.mockk.mockk
import kotlinx.coroutines.test.runBlockingTest
import me.proton.core.test.kotlin.TestDispatcherProvider
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
class DeleteAttachmentWorkerTest {
@RelaxedMockK
private lateinit var context: Context
@RelaxedMockK
private lateinit var parameters: WorkerParameters
@MockK
private lateinit var messagesDb: MessagesDao
@MockK
private lateinit var api: ProtonMailApiManager
private lateinit var worker: DeleteAttachmentWorker
@Before
fun setUp() {
MockKAnnotations.init(this)
worker = DeleteAttachmentWorker(context, parameters, api, messagesDb, TestDispatcherProvider)
}
@Test
fun verifyWorkerFailsWithNoAttachmentIdProvided() {
runBlockingTest {
// given
val expected = ListenableWorker.Result.failure(
workDataOf(KEY_WORKER_ERROR_DESCRIPTION to "Cannot delete attachment with an empty id")
)
// when
val operationResult = worker.doWork()
// then
assertEquals(operationResult, expected)
}
}
@Test
fun verifySuccessResultIsGeneratedWithRequiredParameters() {
runBlockingTest {
// given
val attachmentId = "id232"
val deleteResponse = mockk<ResponseBody> {
every { code } returns Constants.RESPONSE_CODE_OK
}
val attachment = mockk<Attachment>()
val expected = ListenableWorker.Result.success()
every { messagesDb.findAttachmentById(attachmentId) } returns attachment
every { messagesDb.deleteAttachment(attachment) } returns mockk()
every { parameters.inputData } returns
workDataOf(KEY_INPUT_DATA_ATTACHMENT_ID_STRING to attachmentId)
coEvery { api.deleteAttachment(any()) } returns deleteResponse
// when
val operationResult = worker.doWork()
// then
kotlin.test.assertEquals(operationResult, expected)
}
}
@Test
fun verifyFailureResultIsGeneratedWithRequiredParametersButWrongBackendResponse() {
runBlockingTest {
// given
val attachmentId = "id232"
val randomErrorCode = 11212
val deleteResponse = mockk<ResponseBody> {
every { code } returns randomErrorCode
}
val expected = ListenableWorker.Result.failure(
workDataOf(KEY_WORKER_ERROR_DESCRIPTION to "ApiException response code $randomErrorCode")
)
val attachment = mockk<Attachment>()
every { messagesDb.findAttachmentById(attachmentId) } returns attachment
every { messagesDb.deleteAttachment(attachment) } returns mockk()
every { parameters.inputData } returns
workDataOf(KEY_INPUT_DATA_ATTACHMENT_ID_STRING to attachmentId)
coEvery { api.deleteAttachment(any()) } returns deleteResponse
// when
val operationResult = worker.doWork()
// then
kotlin.test.assertEquals(operationResult, expected)
}
}
}