Skip to content

Commit

Permalink
Consent V3 (#297)
Browse files Browse the repository at this point in the history
* add group functions for setting and getting consent

* update to support V3

* small clean up to set v2 and v3

* add back so v2 also gets it

* add an involved test for members and inboxId and address consnet

* get all the tests passing

* fix up linter

* default to true

* set v2 as well

* clean up the logic

* fix the lint
  • Loading branch information
nplasterer authored Sep 16, 2024
1 parent 42ab04d commit 12a55d8
Show file tree
Hide file tree
Showing 8 changed files with 281 additions and 200 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ class ContactsTest {
val fixtures = fixtures()

val contacts = fixtures.bobClient.contacts
var result = contacts.isAllowed(fixtures.alice.walletAddress)
var result = runBlocking { contacts.isAllowed(fixtures.alice.walletAddress) }

assert(!result)

runBlocking { contacts.allow(listOf(fixtures.alice.walletAddress)) }

result = contacts.isAllowed(fixtures.alice.walletAddress)
result = runBlocking { contacts.isAllowed(fixtures.alice.walletAddress) }
assert(result)
}

Expand All @@ -47,13 +47,13 @@ class ContactsTest {
val fixtures = fixtures()

val contacts = fixtures.bobClient.contacts
var result = contacts.isAllowed(fixtures.alice.walletAddress)
var result = runBlocking { contacts.isAllowed(fixtures.alice.walletAddress) }

assert(!result)

runBlocking { contacts.deny(listOf(fixtures.alice.walletAddress)) }

result = contacts.isDenied(fixtures.alice.walletAddress)
result = runBlocking { contacts.isDenied(fixtures.alice.walletAddress) }
assert(result)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -803,72 +803,73 @@ class ConversationTest {
@Test
@Ignore("TODO: Fix Flaky Test")
fun testCanHaveConsentState() {
val bobConversation =
runBlocking { bobClient.conversations.newConversation(alice.walletAddress, null) }
Thread.sleep(1000)
val isAllowed = bobConversation.consentState() == ConsentState.ALLOWED
// Conversations you start should start as allowed
assertTrue("Bob convo should be allowed", isAllowed)
assertTrue(
"Bob contacts should be allowed",
bobClient.contacts.isAllowed(alice.walletAddress)
)

runBlocking {
bobClient.contacts.deny(listOf(alice.walletAddress))
bobClient.contacts.refreshConsentList()
}
val isDenied = bobConversation.consentState() == ConsentState.DENIED
assertEquals(bobClient.contacts.consentList.entries.size, 1)
assertTrue("Bob Conversation should be denied", isDenied)
val bobConversation =
runBlocking { bobClient.conversations.newConversation(alice.walletAddress, null) }
Thread.sleep(1000)
val isAllowed = bobConversation.consentState() == ConsentState.ALLOWED
// Conversations you start should start as allowed
assertTrue("Bob convo should be allowed", isAllowed)
assertTrue(
"Bob contacts should be allowed",
bobClient.contacts.isAllowed(alice.walletAddress)
)

runBlocking {
bobClient.contacts.deny(listOf(alice.walletAddress))
bobClient.contacts.refreshConsentList()
}
val isDenied = bobConversation.consentState() == ConsentState.DENIED
assertEquals(bobClient.contacts.consentList.entries.size, 1)
assertTrue("Bob Conversation should be denied", isDenied)

val aliceConversation = runBlocking { aliceClient.conversations.list()[0] }
val isUnknown = aliceConversation.consentState() == ConsentState.UNKNOWN
val aliceConversation = runBlocking { aliceClient.conversations.list()[0] }
val isUnknown = aliceConversation.consentState() == ConsentState.UNKNOWN

// Conversations started with you should start as unknown
assertTrue("Alice conversation should be unknown", isUnknown)
// Conversations started with you should start as unknown
assertTrue("Alice conversation should be unknown", isUnknown)

runBlocking { aliceClient.contacts.allow(listOf(bob.walletAddress)) }
runBlocking { aliceClient.contacts.allow(listOf(bob.walletAddress)) }

val isBobAllowed = aliceConversation.consentState() == ConsentState.ALLOWED
assertTrue("Bob should be allowed from alice conversation", isBobAllowed)
val isBobAllowed = aliceConversation.consentState() == ConsentState.ALLOWED
assertTrue("Bob should be allowed from alice conversation", isBobAllowed)

val aliceClient2 = runBlocking { Client().create(aliceWallet) }
val aliceConversation2 = runBlocking { aliceClient2.conversations.list()[0] }
val aliceClient2 = runBlocking { Client().create(aliceWallet) }
val aliceConversation2 = runBlocking { aliceClient2.conversations.list()[0] }

runBlocking { aliceClient2.contacts.refreshConsentList() }
runBlocking { aliceClient2.contacts.refreshConsentList() }

// Allow state should sync across clients
val isBobAllowed2 = aliceConversation2.consentState() == ConsentState.ALLOWED
// Allow state should sync across clients
val isBobAllowed2 = aliceConversation2.consentState() == ConsentState.ALLOWED

assertTrue("Bob should be allowed from conversation 2", isBobAllowed2)
}
assertTrue("Bob should be allowed from conversation 2", isBobAllowed2)
}

@Test
@Ignore("TODO: Fix Flaky Test")
fun testCanHaveImplicitConsentOnMessageSend() {
val bobConversation =
runBlocking { bobClient.conversations.newConversation(alice.walletAddress, null) }
Thread.sleep(1000)
val isAllowed = bobConversation.consentState() == ConsentState.ALLOWED
@Test
@Ignore("TODO: Fix Flaky Test")
fun testCanHaveImplicitConsentOnMessageSend() {
runBlocking {
val bobConversation = bobClient.conversations.newConversation(alice.walletAddress, null)
Thread.sleep(1000)
val isAllowed = bobConversation.consentState() == ConsentState.ALLOWED

// Conversations you start should start as allowed
assertTrue("Bob convo should be allowed", isAllowed)
// Conversations you start should start as allowed
assertTrue("Bob convo should be allowed", isAllowed)

val aliceConversation = runBlocking { aliceClient.conversations.list()[0] }
val isUnknown = aliceConversation.consentState() == ConsentState.UNKNOWN
val aliceConversation = aliceClient.conversations.list()[0]
val isUnknown = aliceConversation.consentState() == ConsentState.UNKNOWN

// Conversations you receive should start as unknown
assertTrue("Alice convo should be unknown", isUnknown)
// Conversations you receive should start as unknown
assertTrue("Alice convo should be unknown", isUnknown)

runBlocking {
aliceConversation.send(content = "hey bob")
aliceClient.contacts.refreshConsentList()
}
val isNowAllowed = aliceConversation.consentState() == ConsentState.ALLOWED
aliceConversation.send(content = "hey bob")
aliceClient.contacts.refreshConsentList()
val isNowAllowed = aliceConversation.consentState() == ConsentState.ALLOWED

// Conversations you send a message to get marked as allowed
assertTrue("Should now be allowed", isNowAllowed)
// Conversations you send a message to get marked as allowed
assertTrue("Should now be allowed", isNowAllowed)
}
}
}

@Test
Expand Down
106 changes: 56 additions & 50 deletions library/src/androidTest/java/org/xmtp/android/library/GroupTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,13 @@ class GroupTest {
assert(boGroup.id.isNotEmpty())
assert(alixGroup.id.isNotEmpty())

assertEquals(boClient.contacts.consentList.groupState(boGroup.id), ConsentState.ALLOWED)
assertEquals(alixClient.contacts.consentList.groupState(alixGroup.id), ConsentState.UNKNOWN)
runBlocking {
assertEquals(boClient.contacts.consentList.groupState(boGroup.id), ConsentState.ALLOWED)
assertEquals(
alixClient.contacts.consentList.groupState(alixGroup.id),
ConsentState.UNKNOWN
)
}

runBlocking {
boGroup.addMembers(listOf(caro.walletAddress))
Expand Down Expand Up @@ -424,12 +429,14 @@ class GroupTest {

@Test
fun testGroupStartsWithAllowedState() {
val group = runBlocking { boClient.conversations.newGroup(listOf(alix.walletAddress)) }
runBlocking { group.send("howdy") }
runBlocking { group.send("gm") }
runBlocking { group.sync() }
assert(boClient.contacts.isGroupAllowed(group.id))
assertEquals(boClient.contacts.consentList.groupState(group.id), ConsentState.ALLOWED)
runBlocking {
val group = boClient.conversations.newGroup(listOf(alix.walletAddress))
group.send("howdy")
group.send("gm")
group.sync()
assert(boClient.contacts.isGroupAllowed(group.id))
assertEquals(boClient.contacts.consentList.groupState(group.id), ConsentState.ALLOWED)
}
}

@Test
Expand Down Expand Up @@ -771,58 +778,57 @@ class GroupTest {
}

@Test
fun testCanAllowGroup() {
val group = runBlocking {
boClient.conversations.newGroup(
listOf(
alix.walletAddress,
caro.walletAddress
fun testGroupConsent() {
runBlocking {
val group =
boClient.conversations.newGroup(
listOf(
alix.walletAddress,
caro.walletAddress
)
)
)
}

var result = boClient.contacts.isGroupAllowed(group.id)
assert(result)
assert(boClient.contacts.isGroupAllowed(group.id))
assertEquals(group.consentState(), ConsentState.ALLOWED)

runBlocking { boClient.contacts.allowGroups(listOf(group.id)) }

result = boClient.contacts.isGroupAllowed(group.id)
assert(result)
}
boClient.contacts.denyGroups(listOf(group.id))
assert(boClient.contacts.isGroupDenied(group.id))
assertEquals(group.consentState(), ConsentState.DENIED)

@Test
fun testCanDenyGroup() {
val group = runBlocking {
boClient.conversations.newGroup(
listOf(
alix.walletAddress,
caro.walletAddress
)
)
group.updateConsentState(ConsentState.ALLOWED)
assert(boClient.contacts.isGroupAllowed(group.id))
assertEquals(group.consentState(), ConsentState.ALLOWED)
}
var result = boClient.contacts.isGroupAllowed(group.id)
assert(result)

runBlocking { boClient.contacts.denyGroups(listOf(group.id)) }

result = boClient.contacts.isGroupDenied(group.id)
assert(result)
}

@Test
fun testCanAllowAndDenyInboxId() {
assert(!boClient.contacts.isInboxAllowed(alixClient.inboxId))
assert(!boClient.contacts.isInboxDenied(alixClient.inboxId))
runBlocking {
val boGroup = boClient.conversations.newGroup(listOf(alix.walletAddress))
assert(!boClient.contacts.isInboxAllowed(alixClient.inboxId))
assert(!boClient.contacts.isInboxDenied(alixClient.inboxId))

runBlocking { boClient.contacts.allowInboxes(listOf(alixClient.inboxId)) }
boClient.contacts.allowInboxes(listOf(alixClient.inboxId))
var alixMember = boGroup.members().firstOrNull { it.inboxId == alixClient.inboxId }
assertEquals(alixMember!!.consentState, ConsentState.ALLOWED)

assert(boClient.contacts.isInboxAllowed(alixClient.inboxId))
assert(!boClient.contacts.isInboxDenied(alixClient.inboxId))
assert(boClient.contacts.isInboxAllowed(alixClient.inboxId))
assert(!boClient.contacts.isInboxDenied(alixClient.inboxId))

runBlocking { boClient.contacts.denyInboxes(listOf(alixClient.inboxId)) }
boClient.contacts.denyInboxes(listOf(alixClient.inboxId))
alixMember = boGroup.members().firstOrNull { it.inboxId == alixClient.inboxId }
assertEquals(alixMember!!.consentState, ConsentState.DENIED)

assert(!boClient.contacts.isInboxAllowed(alixClient.inboxId))
assert(boClient.contacts.isInboxDenied(alixClient.inboxId))
assert(!boClient.contacts.isInboxAllowed(alixClient.inboxId))
assert(boClient.contacts.isInboxDenied(alixClient.inboxId))

boClient.contacts.allow(listOf(alixClient.address))
alixMember = boGroup.members().firstOrNull { it.inboxId == alixClient.inboxId }
assertEquals(alixMember!!.consentState, ConsentState.ALLOWED)
assert(boClient.contacts.isInboxAllowed(alixClient.inboxId))
assert(!boClient.contacts.isInboxDenied(alixClient.inboxId))
assert(boClient.contacts.isAllowed(alixClient.address))
assert(!boClient.contacts.isDenied(alixClient.address))
}
}

@Test
Expand Down Expand Up @@ -872,9 +878,9 @@ class GroupTest {
}
runBlocking { alixClient.conversations.syncGroups() }
val alixGroup: Group = alixClient.findGroup(boGroup.id)!!
assert(!alixClient.contacts.isGroupAllowed(boGroup.id))
runBlocking { assert(!alixClient.contacts.isGroupAllowed(boGroup.id)) }
val preparedMessageId = runBlocking { alixGroup.prepareMessage("Test text") }
assert(alixClient.contacts.isGroupAllowed(boGroup.id))
runBlocking { assert(alixClient.contacts.isGroupAllowed(boGroup.id)) }
assertEquals(alixGroup.messages().size, 1)
assertEquals(alixGroup.messages(deliveryStatus = MessageDeliveryStatus.PUBLISHED).size, 0)
assertEquals(alixGroup.messages(deliveryStatus = MessageDeliveryStatus.UNPUBLISHED).size, 1)
Expand Down
3 changes: 2 additions & 1 deletion library/src/main/java/org/xmtp/android/library/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,10 @@ class Client() {
var logger: XMTPLogger = XMTPLogger()
val libXMTPVersion: String = getVersionInfo()
var installationId: String = ""
private var v3Client: FfiXmtpClient? = null
var v3Client: FfiXmtpClient? = null
var dbPath: String = ""
lateinit var inboxId: String
var hasV2Client: Boolean = true

companion object {
private const val TAG = "Client"
Expand Down
Loading

0 comments on commit 12a55d8

Please sign in to comment.