Skip to content

Commit

Permalink
Fix permission result deferred never completing when results are empty (
Browse files Browse the repository at this point in the history
#10)

* Complete deffered exceptionally when permission result cannot be returned

* Add tests

* Fix tests
  • Loading branch information
NeriusZar authored Jan 12, 2023
1 parent 3bcd1c4 commit 766ccc6
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 41 deletions.
34 changes: 24 additions & 10 deletions library/src/main/java/com/vinted/coper/CoperFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -155,21 +155,32 @@ internal class CoperFragment : Fragment() {
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
onRequestPermissionResult(permissions.toList(), grantResults.toList(), requestCode)
}

internal fun onRequestPermissionResult(
permissions: List<String>,
permissionsResult: List<Int>,
requestCode: Int
) {
if (requestCode != REQUEST_CODE) {
Log.e(TAG, "Permissions result came with not Coper request code: $requestCode")
val message = "Permissions result came with not Coper request code: $requestCode"
Log.e(TAG, message)
permissionRequestState?.deferred?.completeExceptionally(
PermissionRequestCancelException(message)
)
return
}
if (permissions.isEmpty() && grantResults.isEmpty()) {
Log.i(TAG, "Permissions result and permissions came empty")

if (permissions.isEmpty() && permissionsResult.isEmpty()) {
val message = "Permissions result and permissions came empty"
Log.i(TAG, message)
permissionRequestState?.deferred?.completeExceptionally(
PermissionRequestCancelException(message)
)
return
}
onRequestPermissionResult(permissions.toList(), grantResults.toList())
}

internal fun onRequestPermissionResult(
permissions: List<String>,
permissionsResult: List<Int>
) {
val permissionRequestState = permissionRequestState
if (permissionRequestState == null) {
Log.e(TAG, "Something went wrong with permission request state")
Expand All @@ -181,6 +192,9 @@ internal class CoperFragment : Fragment() {
val message = "Permissions ($permissionsInResult) result came not as requested " +
"($currentRequestedPermissions)"
Log.e(TAG, message)
permissionRequestState.deferred.completeExceptionally(
PermissionRequestCancelException(message)
)
return
}
if (permissionsResult.size != permissions.size) {
Expand Down Expand Up @@ -242,6 +256,6 @@ internal class CoperFragment : Fragment() {

companion object {
private const val TAG = "CoperFragment"
private const val REQUEST_CODE = 11111
internal const val REQUEST_CODE = 11111
}
}
112 changes: 81 additions & 31 deletions library/src/test/java/com/vinted/coper/CoperImplTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class CoperImplTest {
)

val response = executePermissionRequest(
permissions = listOf(permissionName),
permissionsToRequest = listOf(permissionName),
permissionResult = listOf(PermissionChecker.PERMISSION_DENIED)
)

Expand All @@ -153,7 +153,7 @@ class CoperImplTest {
)

val response = executePermissionRequest(
permissions = listOf(permissionPermanently, permissionRationale),
permissionsToRequest = listOf(permissionPermanently, permissionRationale),
permissionResult = listOf(
PermissionChecker.PERMISSION_DENIED,
PermissionChecker.PERMISSION_DENIED
Expand Down Expand Up @@ -185,7 +185,7 @@ class CoperImplTest {
mockCheckPermissions(permissionGranted, PackageManager.PERMISSION_DENIED)

val response = executePermissionRequest(
permissions = listOf(permissionGranted, permissionDenied),
permissionsToRequest = listOf(permissionGranted, permissionDenied),
permissionResult = listOf(
PermissionChecker.PERMISSION_GRANTED,
PermissionChecker.PERMISSION_DENIED
Expand All @@ -208,7 +208,7 @@ class CoperImplTest {
mockCheckPermissions(permissionName, PackageManager.PERMISSION_DENIED)

val response = executePermissionRequest(
permissions = listOf(permissionName),
permissionsToRequest = listOf(permissionName),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED)
)

Expand All @@ -226,7 +226,7 @@ class CoperImplTest {
mockCheckPermissions(secondPermission, PackageManager.PERMISSION_DENIED)

val response = executePermissionRequest(
permissions = listOf(
permissionsToRequest = listOf(
firstPermission,
secondPermission
),
Expand All @@ -250,7 +250,7 @@ class CoperImplTest {
mockCheckPermissions(secondPermission, PackageManager.PERMISSION_DENIED)

val response = executePermissionRequest(
permissions = listOf(
permissionsToRequest = listOf(
firstPermission,
secondPermission
),
Expand Down Expand Up @@ -282,7 +282,7 @@ class CoperImplTest {
mockCheckPermissions(secondPermission, PackageManager.PERMISSION_DENIED)

val response = executePermissionRequest(
permissions = listOf(
permissionsToRequest = listOf(
firstPermission,
secondPermission
),
Expand Down Expand Up @@ -310,13 +310,13 @@ class CoperImplTest {

val response1Job = async {
executePermissionRequest(
permissions = listOf(firstPermission),
permissionsToRequest = listOf(firstPermission),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED)
)
}
val response2Job = async {
executePermissionRequest(
permissions = listOf(secondPermission),
permissionsToRequest = listOf(secondPermission),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED)
)
}
Expand All @@ -343,14 +343,14 @@ class CoperImplTest {

val response1Job = async {
executePermissionRequest(
permissions = listOf(firstPermission),
permissionsToRequest = listOf(firstPermission),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED),
coperImplReference = firstCoperReference
)
}
val response2Job = async {
executePermissionRequest(
permissions = listOf(secondPermission),
permissionsToRequest = listOf(secondPermission),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED),
coperImplReference = secondCoperReference
)
Expand All @@ -373,11 +373,11 @@ class CoperImplTest {
mockCheckPermissions(secondPermission, PackageManager.PERMISSION_DENIED)

val response1 = executePermissionRequest(
permissions = listOf(firstPermission),
permissionsToRequest = listOf(firstPermission),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED)
)
val response2 = executePermissionRequest(
permissions = listOf(secondPermission),
permissionsToRequest = listOf(secondPermission),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED)
)

Expand Down Expand Up @@ -453,7 +453,7 @@ class CoperImplTest {
withContext(Dispatchers.IO) {
executePermissionRequest(
coperImplReference = fixture,
permissions = listOf("test"),
permissionsToRequest = listOf("test"),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED)
)
}
Expand All @@ -467,7 +467,7 @@ class CoperImplTest {

runBlocking {
executePermissionRequest(
permissions = emptyList(),
permissionsToRequest = emptyList(),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED)
)
}
Expand Down Expand Up @@ -528,7 +528,8 @@ class CoperImplTest {
activity.recreate()
fragment.onRequestPermissionResult(
permissions = listOf(permission),
permissionsResult = listOf(PermissionChecker.PERMISSION_GRANTED)
permissionsResult = listOf(PermissionChecker.PERMISSION_GRANTED),
requestCode = CoperFragment.REQUEST_CODE
)
val result = job.await()

Expand Down Expand Up @@ -568,7 +569,8 @@ class CoperImplTest {
).then {
fragment.onRequestPermissionResult(
permissions = listOf("test"),
permissionsResult = listOf(PermissionChecker.PERMISSION_GRANTED)
permissionsResult = listOf(PermissionChecker.PERMISSION_GRANTED),
requestCode = CoperFragment.REQUEST_CODE
)
}

Expand Down Expand Up @@ -605,13 +607,13 @@ class CoperImplTest {
mockCheckPermissions(permission, PermissionChecker.PERMISSION_DENIED)
val responseAsync1 = async {
executePermissionRequest(
permissions = listOf(permission),
permissionsToRequest = listOf(permission),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED)
)
}
val responseAsync2 = async {
executePermissionRequest(
permissions = listOf(permission),
permissionsToRequest = listOf(permission),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED)
)
}
Expand All @@ -633,13 +635,13 @@ class CoperImplTest {

val responseAsync1 = async {
executePermissionRequest(
permissions = listOf(firstPermission),
permissionsToRequest = listOf(firstPermission),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED)
)
}
val responseAsync2 = async {
executePermissionRequest(
permissions = listOf(secondPermission),
permissionsToRequest = listOf(secondPermission),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED)
)
}
Expand Down Expand Up @@ -670,7 +672,8 @@ class CoperImplTest {
permissionsResult = listOf(
PermissionChecker.PERMISSION_GRANTED,
PermissionChecker.PERMISSION_GRANTED
)
),
requestCode = CoperFragment.REQUEST_CODE
)
}

Expand Down Expand Up @@ -752,7 +755,7 @@ class CoperImplTest {

requests.add(async {
executePermissionRequest(
permissions = listOf(permission),
permissionsToRequest = listOf(permission),
permissionResult = listOf(PermissionChecker.PERMISSION_GRANTED)
)
})
Expand Down Expand Up @@ -793,18 +796,62 @@ class CoperImplTest {
assertFalse(isCancelled)
}

@Test(expected = IllegalStateException::class)
fun request_permissionRequestReturnsEmptyResults_throwException() {
runBlocking {
val permissionName = "interrupted_permission"

executePermissionRequest(
permissionsToRequest = listOf(permissionName),
permissionsInResults = emptyList(),
permissionResult = emptyList()
)
}
}

@Test(expected = IllegalStateException::class)
fun request_permissionRequestReturnsDifferentPermissions_throwException() {
runBlocking {
val requestedPermission = "requested_permission"
val resultedPermission = "resulted_permission"

executePermissionRequest(
permissionsToRequest = listOf(requestedPermission),
permissionsInResults = listOf(requestedPermission),
permissionResult = emptyList()
)
}
}

@Test(expected = IllegalStateException::class)
fun request_requestCodeIsNotOfCoperFragment_throwException() {
runBlocking {
val requestedPermission = "requested_permission"

executePermissionRequest(
permissionsToRequest = listOf(requestedPermission),
permissionResult = listOf(PermissionChecker.PERMISSION_DENIED),
requestCode = 0
)
}
}

private suspend fun executePermissionRequest(
permissions: List<String>,
permissionsToRequest: List<String>,
permissionResult: List<Int>,
coperImplReference: CoperImpl = fixture
coperImplReference: CoperImpl = fixture,
permissionsInResults: List<String>? = null,
requestCode: Int = CoperFragment.REQUEST_CODE,
): PermissionResult {
return coroutineScope {
stubRequestPermission(
coperFragment = coperImplReference.getFragmentSafely(),
permissions = permissions,
permissionResults = permissionResult
permissions = permissionsToRequest,
permissionResults = permissionResult,
permissionsInResults = permissionsInResults,
requestCode = requestCode
)
coperImplReference.request(*permissions.toTypedArray())
coperImplReference.request(*permissionsToRequest.toTypedArray())
}
}

Expand All @@ -829,7 +876,9 @@ class CoperImplTest {
private fun stubRequestPermission(
coperFragment: CoperFragment,
permissions: List<String>,
permissionResults: List<Int>
permissionResults: List<Int>,
permissionsInResults: List<String>? = null,
requestCode: Int = CoperFragment.REQUEST_CODE
) {
whenever(
coperFragment.requestPermissions(
Expand All @@ -838,8 +887,9 @@ class CoperImplTest {
)
).then {
coperFragment.onRequestPermissionResult(
permissions = permissions,
permissionsResult = permissionResults
permissions = permissionsInResults ?: permissions,
permissionsResult = permissionResults,
requestCode = requestCode
)
}
}
Expand Down

0 comments on commit 766ccc6

Please sign in to comment.