Skip to content

Commit 78c26eb

Browse files
authored
Group Admin Permissions (#182)
1 parent a59fe92 commit 78c26eb

File tree

4 files changed

+84
-14
lines changed

4 files changed

+84
-14
lines changed

library/src/androidTest/java/org/xmtp/android/library/GroupTest.kt

+66-8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import org.xmtp.android.library.codecs.ReactionSchema
1717
import org.xmtp.android.library.messages.PrivateKey
1818
import org.xmtp.android.library.messages.PrivateKeyBuilder
1919
import org.xmtp.android.library.messages.walletAddress
20+
import uniffi.xmtpv3.GroupPermissions
2021

2122
@RunWith(AndroidJUnit4::class)
2223
class GroupTest {
@@ -57,9 +58,63 @@ class GroupTest {
5758
}
5859

5960
@Test
60-
fun testCanCreateAGroup() {
61-
val group = boClient.conversations.newGroup(listOf(alix.walletAddress))
62-
assert(group.id.isNotEmpty())
61+
fun testCanCreateAGroupWithDefaultPermissions() {
62+
val boGroup = boClient.conversations.newGroup(listOf(alix.walletAddress))
63+
runBlocking { alixClient.conversations.syncGroups() }
64+
val alixGroup = alixClient.conversations.listGroups().first()
65+
assert(boGroup.id.isNotEmpty())
66+
assert(alixGroup.id.isNotEmpty())
67+
68+
alixGroup.addMembers(listOf(caro.walletAddress))
69+
runBlocking { boGroup.sync() }
70+
assertEquals(alixGroup.memberAddresses().size, 3)
71+
assertEquals(boGroup.memberAddresses().size, 3)
72+
73+
alixGroup.removeMembers(listOf(caro.walletAddress))
74+
runBlocking { boGroup.sync() }
75+
assertEquals(alixGroup.memberAddresses().size, 2)
76+
assertEquals(boGroup.memberAddresses().size, 2)
77+
78+
boGroup.addMembers(listOf(caro.walletAddress))
79+
runBlocking { alixGroup.sync() }
80+
assertEquals(alixGroup.memberAddresses().size, 3)
81+
assertEquals(boGroup.memberAddresses().size, 3)
82+
}
83+
84+
@Test
85+
fun testCanCreateAGroupWithAdminPermissions() {
86+
val boGroup = boClient.conversations.newGroup(
87+
listOf(alix.walletAddress),
88+
permissions = GroupPermissions.GROUP_CREATOR_IS_ADMIN
89+
)
90+
runBlocking { alixClient.conversations.syncGroups() }
91+
val alixGroup = alixClient.conversations.listGroups().first()
92+
assert(boGroup.id.isNotEmpty())
93+
assert(alixGroup.id.isNotEmpty())
94+
95+
boGroup.addMembers(listOf(caro.walletAddress))
96+
runBlocking { alixGroup.sync() }
97+
assertEquals(alixGroup.memberAddresses().size, 3)
98+
assertEquals(boGroup.memberAddresses().size, 3)
99+
100+
assertThrows(XMTPException::class.java) {
101+
alixGroup.removeMembers(listOf(caro.walletAddress))
102+
}
103+
runBlocking { boGroup.sync() }
104+
assertEquals(alixGroup.memberAddresses().size, 3)
105+
assertEquals(boGroup.memberAddresses().size, 3)
106+
107+
boGroup.removeMembers(listOf(caro.walletAddress))
108+
runBlocking { alixGroup.sync() }
109+
assertEquals(alixGroup.memberAddresses().size, 2)
110+
assertEquals(boGroup.memberAddresses().size, 2)
111+
112+
assertThrows(XMTPException::class.java) {
113+
alixGroup.addMembers(listOf(caro.walletAddress))
114+
}
115+
runBlocking { boGroup.sync() }
116+
assertEquals(alixGroup.memberAddresses().size, 2)
117+
assertEquals(boGroup.memberAddresses().size, 2)
63118
}
64119

65120
@Test
@@ -241,22 +296,25 @@ class GroupTest {
241296
@Test
242297
fun testCanStreamGroupMessages() = kotlinx.coroutines.test.runTest {
243298
val group = boClient.conversations.newGroup(listOf(alix.walletAddress.lowercase()))
299+
alixClient.conversations.syncGroups()
300+
val alixGroup = alixClient.conversations.listGroups().first()
244301
group.streamMessages().test {
245-
group.send("hi")
302+
alixGroup.send("hi")
246303
assertEquals("hi", awaitItem().body)
247-
group.send("hi again")
304+
alixGroup.send("hi again")
248305
assertEquals("hi again", awaitItem().body)
249306
}
250307
}
251308

252309
@Test
253310
fun testCanStreamDecryptedGroupMessages() = kotlinx.coroutines.test.runTest {
254311
val group = boClient.conversations.newGroup(listOf(alix.walletAddress))
255-
312+
alixClient.conversations.syncGroups()
313+
val alixGroup = alixClient.conversations.listGroups().first()
256314
group.streamDecryptedMessages().test {
257-
group.send("hi")
315+
alixGroup.send("hi")
258316
assertEquals("hi", awaitItem().encodedContent.content.toStringUtf8())
259-
group.send("hi again")
317+
alixGroup.send("hi again")
260318
assertEquals("hi again", awaitItem().encodedContent.content.toStringUtf8())
261319
}
262320
}

library/src/main/java/org/xmtp/android/library/Client.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -566,8 +566,7 @@ class Client() {
566566

567567
fun canMessage(addresses: List<String>): Boolean {
568568
return runBlocking {
569-
libXMTPClient != null && !libXMTPClient!!.canMessage(addresses.map { it })
570-
.contains(false)
569+
libXMTPClient != null && !libXMTPClient!!.canMessage(addresses).contains(false)
571570
}
572571
}
573572

library/src/main/java/org/xmtp/android/library/Conversations.kt

+6-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import uniffi.xmtpv3.FfiConversationCallback
3939
import uniffi.xmtpv3.FfiConversations
4040
import uniffi.xmtpv3.FfiGroup
4141
import uniffi.xmtpv3.FfiListConversationsOptions
42+
import uniffi.xmtpv3.GroupPermissions
4243
import java.util.Date
4344
import kotlin.time.Duration.Companion.nanoseconds
4445
import kotlin.time.DurationUnit
@@ -91,7 +92,10 @@ data class Conversations(
9192
)
9293
}
9394

94-
fun newGroup(accountAddresses: List<String>): Group {
95+
fun newGroup(
96+
accountAddresses: List<String>,
97+
permissions: GroupPermissions = GroupPermissions.EVERYONE_IS_ADMIN,
98+
): Group {
9599
if (accountAddresses.isEmpty()) {
96100
throw XMTPException("Cannot start an empty group chat.")
97101
}
@@ -105,7 +109,7 @@ data class Conversations(
105109
}
106110

107111
val group = runBlocking {
108-
libXMTPConversations?.createGroup(accountAddresses, permissions = null)
112+
libXMTPConversations?.createGroup(accountAddresses, permissions = permissions)
109113
?: throw XMTPException("Client does not support Groups")
110114
}
111115
return Group(client, group)

library/src/main/java/org/xmtp/android/library/Group.kt

+11-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import uniffi.xmtpv3.FfiGroup
1515
import uniffi.xmtpv3.FfiListMessagesOptions
1616
import uniffi.xmtpv3.FfiMessage
1717
import uniffi.xmtpv3.FfiMessageCallback
18+
import java.lang.Exception
1819
import java.util.Date
1920
import kotlin.time.Duration.Companion.nanoseconds
2021
import kotlin.time.DurationUnit
@@ -133,11 +134,19 @@ class Group(val client: Client, private val libXMTPGroup: FfiGroup) {
133134
}
134135

135136
fun addMembers(addresses: List<String>) {
136-
runBlocking { libXMTPGroup.addMembers(addresses) }
137+
try {
138+
runBlocking { libXMTPGroup.addMembers(addresses) }
139+
} catch (e: Exception) {
140+
throw XMTPException("User does not have permissions", e)
141+
}
137142
}
138143

139144
fun removeMembers(addresses: List<String>) {
140-
runBlocking { libXMTPGroup.removeMembers(addresses) }
145+
try {
146+
runBlocking { libXMTPGroup.removeMembers(addresses) }
147+
} catch (e: Exception) {
148+
throw XMTPException("User does not have permissions", e)
149+
}
141150
}
142151

143152
fun memberAddresses(): List<String> {

0 commit comments

Comments
 (0)