Skip to content

Commit 128aaa2

Browse files
Merge pull request #2 from lorenzofelletti/newver
* Added the possibility to dynamically change the dispatcher entries * Added some unit tests
2 parents 8492365 + 583f402 commit 128aaa2

File tree

7 files changed

+257
-29
lines changed

7 files changed

+257
-29
lines changed

permissions/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ dependencies {
4646
testImplementation 'junit:junit:4.13.2'
4747
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
4848
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
49+
50+
testImplementation 'org.mockito:mockito-core:2.23.0'
51+
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
52+
testImplementation "androidx.test:core:1.5.0"
53+
54+
testImplementation 'com.google.truth:truth:1.1.3'
4955
}
5056

5157
publishing {

permissions/src/main/java/com/lorenzofelletti/permissions/PermissionManager.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ import com.lorenzofelletti.permissions.dispatcher.dsl.PermissionDispatcherDsl
2424
* @param activity The [Activity] that needs to manage the permissions
2525
*/
2626
class PermissionManager(val activity: Activity) {
27-
private lateinit var requestResultsDispatcher: RequestResultsDispatcher
27+
lateinit var dispatcher: RequestResultsDispatcher
28+
private set
2829

2930
/**
3031
* Builds a [RequestResultsDispatcher] object that is used to dispatch the results of the
@@ -34,7 +35,7 @@ class PermissionManager(val activity: Activity) {
3435
*/
3536
@PermissionDispatcherDsl
3637
fun buildRequestResultsDispatcher(init: RequestResultsDispatcher.() -> Unit) {
37-
requestResultsDispatcher = RequestResultsDispatcher(this).apply(init)
38+
dispatcher = RequestResultsDispatcher(this).apply(init)
3839
}
3940

4041
/**
@@ -49,7 +50,7 @@ class PermissionManager(val activity: Activity) {
4950
* @param requestCode The request code associated to the permissions
5051
*/
5152
fun checkRequestAndDispatch(requestCode: Int, comingFromRationale: Boolean = false) {
52-
val permissions = requestResultsDispatcher.getPermissions(requestCode)
53+
val permissions = dispatcher.getPermissions(requestCode)
5354
?: throw UnhandledRequestCodeException(requestCode)
5455
val permissionsNotGranted = permissions.filter { permission ->
5556
ActivityCompat.checkSelfPermission(
@@ -60,7 +61,7 @@ class PermissionManager(val activity: Activity) {
6061

6162
if (permissionsNotGranted.isEmpty()) {
6263
// All permissions are granted
63-
requestResultsDispatcher.getOnGranted(requestCode)?.invoke()
64+
dispatcher.getOnGranted(requestCode)?.invoke()
6465
} else {
6566
// Some permissions are not granted
6667
val shouldShowRationale = permissionsNotGranted.any { permission ->
@@ -76,7 +77,7 @@ class PermissionManager(val activity: Activity) {
7677
}
7778

7879
private fun dispatchRationale(permissionsNotGranted: Array<out String>, requestCode: Int) {
79-
val toInvoke = requestResultsDispatcher.getOnShowRationale(requestCode) ?: fun(
80+
val toInvoke = dispatcher.getOnShowRationale(requestCode) ?: fun(
8081
_: List<String>,
8182
requestCode: Int
8283
) {
@@ -107,7 +108,7 @@ class PermissionManager(val activity: Activity) {
107108
* @return true if all permissions are granted, false otherwise
108109
*/
109110
fun checkPermissionsGranted(requestCode: Int): Boolean {
110-
val permissions = requestResultsDispatcher.getPermissions(requestCode)
111+
val permissions = dispatcher.getPermissions(requestCode)
111112
?: throw UnhandledRequestCodeException(requestCode)
112113
return checkPermissionsGranted(permissions)
113114
}
@@ -123,7 +124,7 @@ class PermissionManager(val activity: Activity) {
123124
requestCode: Int,
124125
grantResults: IntArray,
125126
) {
126-
requestResultsDispatcher.dispatchAction(requestCode, grantResults)?.invoke()
127+
dispatcher.dispatchAction(requestCode, grantResults)?.invoke()
127128
}
128129

129130
/**

permissions/src/main/java/com/lorenzofelletti/permissions/dispatcher/DispatcherEntry.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import com.lorenzofelletti.permissions.dispatcher.dsl.PermissionDispatcherDsl
1414
*/
1515
class DispatcherEntry(
1616
private val manager: PermissionManager,
17-
private val requestCode: Int
17+
val requestCode: Int
1818
) : PermissionDispatcher() {
1919
/**
2020
* The permissions associated to this entry

permissions/src/main/java/com/lorenzofelletti/permissions/dispatcher/RequestResultsDispatcher.kt

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package com.lorenzofelletti.permissions.dispatcher
22

3-
import android.app.Activity
4-
import android.app.AlertDialog
53
import android.content.pm.PackageManager
64
import com.lorenzofelletti.permissions.PermissionManager
7-
import com.lorenzofelletti.permissions.dispatcher.DispatcherEntry.Companion.rationale
85
import com.lorenzofelletti.permissions.dispatcher.dsl.PermissionDispatcher
96
import com.lorenzofelletti.permissions.dispatcher.dsl.PermissionDispatcherDsl
107

118
/**
129
* A dispatcher for the results of permission requests.
1310
*/
1411
class RequestResultsDispatcher(private val manager: PermissionManager) : PermissionDispatcher() {
15-
private val entries: MutableMap<Int, DispatcherEntry> = mutableMapOf()
12+
/** Maps the entries of the dispatcher with the request codes. */
13+
var entries: MutableMap<Int, DispatcherEntry> = mutableMapOf()
14+
private set
1615

1716
fun dispatchAction(requestCode: Int, grantResults: IntArray): (() -> Unit)? =
1817
when (checkGrantResults(grantResults)) {
@@ -55,5 +54,79 @@ class RequestResultsDispatcher(private val manager: PermissionManager) : Permiss
5554
) {
5655
entries[requestCode] = DispatcherEntry(manager, requestCode).apply(init)
5756
}
57+
58+
/**
59+
* Removes an entry from the dispatcher.
60+
*
61+
* @param requestCode The request code of the entry to be removed
62+
*/
63+
@PermissionDispatcherDsl
64+
fun RequestResultsDispatcher.removeEntry(requestCode: Int) {
65+
entries.remove(requestCode)
66+
}
67+
68+
/**
69+
* Removes an entry from the dispatcher.
70+
*
71+
* @param entry The entry to be removed
72+
*/
73+
@PermissionDispatcherDsl
74+
fun RequestResultsDispatcher.removeEntry(entry: DispatcherEntry) {
75+
entries.remove(entry.requestCode)
76+
}
77+
78+
/**
79+
* Adds a new entry to the dispatcher if it doesn't already exist.
80+
*
81+
* @param entry The entry to be added
82+
*/
83+
@PermissionDispatcherDsl
84+
fun RequestResultsDispatcher.addEntry(entry: DispatcherEntry) {
85+
if (entries[entry.requestCode] == null) {
86+
entries[entry.requestCode] = entry
87+
}
88+
}
89+
90+
/**
91+
* Adds a new entry to the dispatcher if it doesn't already exist.
92+
*
93+
* @param requestCode The request code associated to the entry
94+
* @param init A lambda that initializes the entry
95+
*/
96+
@PermissionDispatcherDsl
97+
fun RequestResultsDispatcher.addEntry(requestCode: Int, init: DispatcherEntry.() -> Unit) {
98+
if (entries[requestCode] == null) {
99+
entries[requestCode] = DispatcherEntry(manager, requestCode).apply(init)
100+
}
101+
}
102+
103+
/**
104+
* Replaces an entry in the dispatcher if present, otherwise adds it.
105+
*
106+
* @param entry The entry to be replaced or added
107+
*/
108+
@PermissionDispatcherDsl
109+
fun RequestResultsDispatcher.replaceEntry(entry: DispatcherEntry) {
110+
entries[entry.requestCode] = entry
111+
}
112+
113+
/**
114+
* Replaces an entry in the dispatcher if present, otherwise adds it.
115+
*
116+
* @param requestCode The request code associated to the entry
117+
* @param init A lambda that initializes the entry
118+
*/
119+
@PermissionDispatcherDsl
120+
fun RequestResultsDispatcher.replaceEntry(requestCode: Int, init: DispatcherEntry.() -> Unit) {
121+
entries[requestCode] = DispatcherEntry(manager, requestCode).apply(init)
122+
}
123+
124+
/**
125+
* Removes all entries from the dispatcher.
126+
*/
127+
@PermissionDispatcherDsl
128+
fun RequestResultsDispatcher.clearEntries() {
129+
entries.clear()
130+
}
58131
}
59132
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.lorenzofelletti.permissions
2+
3+
import android.app.Activity
4+
import com.lorenzofelletti.permissions.dispatcher.DispatcherEntry
5+
import com.lorenzofelletti.permissions.dispatcher.DispatcherEntry.Companion.doOnDenied
6+
import com.lorenzofelletti.permissions.dispatcher.DispatcherEntry.Companion.doOnGranted
7+
import org.junit.Before
8+
import org.junit.Test
9+
import org.junit.runner.RunWith
10+
import org.mockito.Mockito.mock
11+
import org.mockito.junit.MockitoJUnitRunner
12+
13+
@RunWith(MockitoJUnitRunner::class)
14+
class DispatcherEntryTest {
15+
private lateinit var permissionManager: PermissionManager
16+
17+
@Before
18+
fun setUp() {
19+
val mockActivity = mock(Activity::class.java)
20+
permissionManager = PermissionManager(mockActivity)
21+
}
22+
23+
@Test
24+
fun `test do on granted`() {
25+
var testVar = 0
26+
val entry = DispatcherEntry(permissionManager, 0)
27+
28+
entry.doOnGranted { testVar = 1 }
29+
30+
entry.onGranted()
31+
32+
assert(testVar == 1)
33+
}
34+
35+
@Test
36+
fun `test do on denied`() {
37+
var testVar = 0
38+
val entry = DispatcherEntry(permissionManager, 0)
39+
40+
entry.doOnDenied { testVar = 1 }
41+
42+
entry.onDenied()
43+
44+
assert(testVar == 1)
45+
}
46+
}

permissions/src/test/java/com/lorenzofelletti/permissions/ExampleUnitTest.kt

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package com.lorenzofelletti.permissions
2+
3+
import android.app.Activity
4+
import android.content.pm.PackageManager
5+
import com.lorenzofelletti.permissions.dispatcher.DispatcherEntry
6+
import com.lorenzofelletti.permissions.dispatcher.DispatcherEntry.Companion.checkPermissions
7+
import com.lorenzofelletti.permissions.dispatcher.DispatcherEntry.Companion.doOnGranted
8+
import com.lorenzofelletti.permissions.dispatcher.RequestResultsDispatcher
9+
import com.lorenzofelletti.permissions.dispatcher.RequestResultsDispatcher.Companion.addEntry
10+
import com.lorenzofelletti.permissions.dispatcher.RequestResultsDispatcher.Companion.removeEntry
11+
import com.lorenzofelletti.permissions.dispatcher.RequestResultsDispatcher.Companion.replaceEntry
12+
import com.lorenzofelletti.permissions.dispatcher.RequestResultsDispatcher.Companion.withRequestCode
13+
import org.junit.Before
14+
import org.junit.Test
15+
import org.junit.runner.RunWith
16+
import org.mockito.Mockito.mock
17+
import org.mockito.junit.MockitoJUnitRunner
18+
19+
@RunWith(MockitoJUnitRunner::class)
20+
class RequestResultsDispatcherTest {
21+
private lateinit var permissionManager: PermissionManager
22+
private lateinit var dispatcher: RequestResultsDispatcher
23+
24+
@Before
25+
fun setUp() {
26+
val mockActivity = mock(Activity::class.java)
27+
permissionManager = PermissionManager(mockActivity)
28+
29+
permissionManager.buildRequestResultsDispatcher {}
30+
31+
dispatcher = permissionManager.dispatcher
32+
}
33+
34+
@Test
35+
fun `test add entry`() {
36+
val dispatcher = RequestResultsDispatcher(permissionManager)
37+
val entry = DispatcherEntry(permissionManager, 0)
38+
39+
dispatcher.addEntry(entry)
40+
41+
assert(dispatcher.entries.size == 1)
42+
}
43+
44+
@Test
45+
fun `test add entry declarative`() {
46+
permissionManager.dispatcher.addEntry(0) {}
47+
48+
assert(dispatcher.entries.size == 1)
49+
}
50+
51+
@Test
52+
fun `test remove entry`() {
53+
val dispatcher = RequestResultsDispatcher(permissionManager)
54+
val entry = DispatcherEntry(permissionManager, 0)
55+
56+
dispatcher.addEntry(entry)
57+
dispatcher.removeEntry(entry)
58+
59+
assert(dispatcher.entries.isEmpty())
60+
}
61+
62+
@Test
63+
fun `test remove entry by request code`() {
64+
val dispatcher = permissionManager.dispatcher
65+
val entry = DispatcherEntry(permissionManager, 0)
66+
67+
dispatcher.addEntry(entry)
68+
dispatcher.removeEntry(0)
69+
70+
assert(dispatcher.entries.isEmpty())
71+
}
72+
73+
@Test
74+
fun `test replace on existing entry`() {
75+
var testVar = 0
76+
77+
val permissionManager = permissionManagerWithEntryZero()
78+
79+
permissionManager.dispatcher.replaceEntry(0) {
80+
checkPermissions(arrayOf("permission1"))
81+
doOnGranted { testVar = 2 }
82+
}
83+
84+
permissionManager.dispatcher.dispatchAction(
85+
0,
86+
intArrayOf(PackageManager.PERMISSION_GRANTED)
87+
)?.invoke()
88+
89+
assert(testVar == 2)
90+
}
91+
92+
@Test
93+
fun `test dispatch on granted`() {
94+
var testVar = 0
95+
val entry = DispatcherEntry(permissionManager, 0)
96+
97+
entry.doOnGranted { testVar = 1 }
98+
99+
dispatcher.addEntry(entry)
100+
dispatcher.dispatchAction(
101+
0,
102+
arrayOf(PackageManager.PERMISSION_GRANTED).toIntArray()
103+
)?.invoke()
104+
105+
assert(testVar == 1)
106+
}
107+
108+
private fun permissionManagerWithEntryZero(): PermissionManager {
109+
val permissionManager = PermissionManager(mock(Activity::class.java))
110+
permissionManager.buildRequestResultsDispatcher {
111+
withRequestCode(0) {
112+
checkPermissions(arrayOf("permission0"))
113+
doOnGranted { }
114+
}
115+
}
116+
117+
return permissionManager
118+
}
119+
}

0 commit comments

Comments
 (0)