Skip to content
This repository has been archived by the owner on Sep 23, 2024. It is now read-only.

Appscope part 2 #261

Merged
merged 3 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import org.mozilla.social.core.data.repository.InstanceRepository
import org.mozilla.social.core.data.repository.MediaRepository
import org.mozilla.social.core.data.repository.OauthRepository
import org.mozilla.social.core.data.repository.RecommendationRepository
import org.mozilla.social.core.data.repository.ReportRepository
import org.mozilla.social.core.data.repository.SearchRepository
import org.mozilla.social.core.data.repository.StatusRepository
import org.mozilla.social.core.data.repository.TimelineRepository
Expand All @@ -25,6 +24,5 @@ fun repositoryModule(isDebug: Boolean) = module {
single { RecommendationRepository(get()) }
single { AppRepository(get()) }
single { InstanceRepository(get()) }
single { ReportRepository(get()) }
includes(networkModule(isDebug))
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import org.mozilla.social.core.data.repository.model.status.toExternalModel
import org.mozilla.social.core.network.MediaApi
import org.mozilla.social.core.network.model.request.NetworkMediaUpdate
import org.mozilla.social.model.Attachment
import java.io.File

Expand All @@ -24,9 +23,4 @@ class MediaRepository internal constructor(
),
description,
).toExternalModel()

suspend fun updateMedia(
mediaId: String,
description: String,
) = mediaApi.updateMedia(mediaId, NetworkMediaUpdate(description))
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,4 @@ class TimelineRepository internal constructor(
)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.mozilla.social.core.domain.account.UnfollowAccount
import org.mozilla.social.core.domain.account.UnmuteAccount
import org.mozilla.social.core.domain.account.UpdateMyAccount
import org.mozilla.social.core.domain.remotemediators.HashTagTimelineRemoteMediator
import org.mozilla.social.core.domain.report.Report

val domainModule = module {
factory { parametersHolder ->
Expand Down Expand Up @@ -77,4 +78,9 @@ val domainModule = module {
accountApi = get(),
socialDatabase = get(),
) }
single { Report(
externalScope = get<AppScope>(),
showSnackbar = get(),
reportApi = get(),
) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.mozilla.social.core.domain.report

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import org.mozilla.social.common.utils.StringFactory
import org.mozilla.social.core.domain.R
import org.mozilla.social.core.navigation.usecases.ShowSnackbar
import org.mozilla.social.core.network.ReportApi
import org.mozilla.social.core.network.model.request.NetworkReportCreate

class Report(
private val externalScope: CoroutineScope,
private val showSnackbar: ShowSnackbar,
private val reportApi: ReportApi,
private val dispatcherIo: CoroutineDispatcher = Dispatchers.IO,
) {

/**
* @throws ReportFailedException if any error occurred
*/
suspend operator fun invoke(
accountId: String,
statusIds: List<String>? = null,
comment: String? = null,
forward: Boolean? = null,
category: String? = null,
ruleViolations: List<Int>? = null,
) = externalScope.async(dispatcherIo) {
try {
reportApi.report(
body = NetworkReportCreate(
accountId = accountId,
statusIds = statusIds,
comment = comment,
forward = forward,
category = category,
ruleViolations = ruleViolations
)
)
} catch (e: Exception) {
showSnackbar(
text = StringFactory.resource(R.string.error_sending_report_toast),
isError = true,
)
throw ReportFailedException(e)
}
}.await()

class ReportFailedException(e: Exception) : Exception(e)
}
1 change: 1 addition & 0 deletions core/domain/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<string name="error_following_account">Error following account</string>
<string name="error_unfollowing_account">Error unfollowing account</string>
<string name="error_deleting_post">Error deleting post</string>
<string name="error_sending_report_toast">Error sending report</string>

<string name="edit_account_save_failed">Failed to save changes</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
Expand Down Expand Up @@ -104,39 +105,31 @@ open class BaseDomainTest {
subjectCallBlock: suspend () -> Unit,
verifyBlock: suspend MockKVerificationScope.() -> Unit,
) = runTest {
val mutex1 = Mutex(locked = true)
val mutex2 = Mutex(locked = true)
val waitToCancel = CompletableDeferred<Unit>()
val waitToFinish = CompletableDeferred<Unit>()

coEvery(delayedCallBlock).coAnswers {
CoroutineScope(Dispatchers.Default).launch {
// we know we've started the subject block, so we can unlock the first mutex
mutex1.unlock()
println("lock 1 unlocked")
delay(100)
// unlock to allow the verify block to run
mutex2.unlock()
println("lock 2 unlocked")
}.join()
println("allow cancel")
waitToCancel.complete(Unit)
println("wait to finish")
waitToFinish.await()
println("finishing subject block")
delayedCallBlockReturnValue
}

val outerJob = CoroutineScope(Dispatchers.Default).launch {
val outerJob = launch {
subjectCallBlock()
}

// lock to make sure we give the subject callback time to start
println("lock 1 locking")
mutex1.lock()
println("wait to cancel")
waitToCancel.await()

println("canceling outer job")
outerJob.cancel()
println("allow finish")
waitToFinish.complete(Unit)

// lock again to make sure our delayed callback has run before we verify
println("lock 2 locking")
mutex2.lock()

// delay to make sure the rest of the subject block has had time to run
delay(50)

println("verify")
coVerify(exactly = 1, verifyBlock = verifyBlock)
}

Expand All @@ -149,23 +142,19 @@ open class BaseDomainTest {
delayedCallBlock: suspend MockKMatcherScope.() -> Any,
subjectCallBlock: suspend () -> Unit,
) = runTest {
val mutex1 = Mutex(locked = true)
val mutex2 = Mutex(locked = true)
val waitToCancel = CompletableDeferred<Unit>()
val waitToFinish = CompletableDeferred<Unit>()

coEvery(delayedCallBlock).coAnswers {
CoroutineScope(Dispatchers.Default).async {
// we know we've started the subject block, so we can unlock the first mutex
mutex1.unlock()
println("lock 1 unlocked")
delay(100)
// unlock to allow the verify block to run
mutex2.unlock()
println("lock 2 unlocked")
throw TestException()
}.await()
println("allow cancel")
waitToCancel.complete(Unit)
println("wait to finish")
waitToFinish.await()
println("finishing subject block")
throw TestException()
}

val outerJob = CoroutineScope(Dispatchers.Default).launch {
val outerJob = launch {
try {
subjectCallBlock()
} catch (e: TestException) {
Expand All @@ -175,19 +164,12 @@ open class BaseDomainTest {
}
}

// lock to make sure we give the subject callback time to start
println("lock 1 locking")
mutex1.lock()

println("wait to cancel")
waitToCancel.await()
println("canceling outer job")
outerJob.cancel()

// lock again to make sure our delayed callback has run before we verify
println("lock 2 locking")
mutex2.lock()

// delay to make sure the rest of the subject block has had time to run
delay(50)
println("test ending")
println("allow finish")
waitToFinish.complete(Unit)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.mozilla.social.core.domain.report

import kotlinx.coroutines.test.TestScope
import org.mozilla.social.core.domain.BaseDomainTest
import kotlin.test.BeforeTest
import kotlin.test.Test

class ReportTest : BaseDomainTest() {

private lateinit var subject: Report

@BeforeTest
fun setup() {
subject = Report(
externalScope = TestScope(testDispatcher),
showSnackbar = showSnackbar,
reportApi = reportApi,
dispatcherIo = testDispatcher,
)
}

@Test
fun testCancelledScope() {
val accountId = "id1"
testOuterScopeCancelled(
delayedCallBlock = {
reportApi.report(any())
},
subjectCallBlock = {
subject(accountId)
},
verifyBlock = {
reportApi.report(any())
}
)
}

@Test
fun testCancelledScopeWithError() {
testOuterScopeCancelledAndInnerException(
delayedCallBlock = {
reportApi.report(any())
},
subjectCallBlock = {
subject("id")
},
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,17 @@ val reportModule = module {
}
viewModel { parametersHolder ->
ReportScreen2ViewModel(
get(),
get(),
get(),
parametersHolder[0],
parametersHolder[1],
parametersHolder[2],
parametersHolder[3],
parametersHolder[4],
parametersHolder[5],
parametersHolder[6],
parametersHolder[7],
parametersHolder[8],
report = get(),
accountRepository = get(),
onClose = parametersHolder[0],
onReportSubmitted = parametersHolder[1],
reportAccountId = parametersHolder[2],
reportAccountHandle = parametersHolder[3],
reportStatusId = parametersHolder[4],
reportType = parametersHolder[5],
checkedInstanceRules = parametersHolder[6],
additionalText = parametersHolder[7],
sendToExternalServer = parametersHolder[8],
)
}
viewModel { parametersHolder ->
Expand Down
Loading