Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Conversations and Contacts actors. #161

Merged
merged 2 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
12 changes: 10 additions & 2 deletions Sources/XMTP/Contacts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation

/// Provides access to contact bundles.
public struct Contacts {
public actor Contacts {
var client: Client

// Save all bundles here
Expand All @@ -17,6 +17,14 @@ public struct Contacts {
// Whether or not we have sent invite/intro to this contact
var hasIntroduced: [String: Bool] = [:]

init(client: Client) {
self.client = client
}

func markIntroduced(_ peerAddress: String, _ isIntroduced: Bool) {
hasIntroduced[peerAddress] = isIntroduced
}

func has(_ peerAddress: String) -> Bool {
return knownBundles[peerAddress] != nil
}
Expand All @@ -25,7 +33,7 @@ public struct Contacts {
return hasIntroduced[peerAddress] != true
}

mutating func find(_ peerAddress: String) async throws -> ContactBundle? {
func find(_ peerAddress: String) async throws -> ContactBundle? {
if let knownBundle = knownBundles[peerAddress] {
return knownBundle
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/XMTP/ConversationV1.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public struct ConversationV1 {
message: msg
)
var envelopes = [messageEnvelope]
if client.contacts.needsIntroduction(peerAddress) && !isEphemeral {
if (await client.contacts.needsIntroduction(peerAddress)) && !isEphemeral {
envelopes.append(contentsOf: [
Envelope(
topic: .userIntro(peerAddress),
Expand All @@ -85,7 +85,7 @@ public struct ConversationV1 {
),
])

client.contacts.hasIntroduced[peerAddress] = true
await client.contacts.markIntroduced(peerAddress, true)
}

return PreparedMessage(envelopes: envelopes)
Expand Down
2 changes: 1 addition & 1 deletion Sources/XMTP/Conversations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public enum ConversationError: Error {
}

/// Handles listing and creating Conversations.
public class Conversations {
public actor Conversations {
var client: Client
var conversationsByTopic: [String: Conversation] = [:]

Expand Down
3 changes: 2 additions & 1 deletion Tests/XMTPTests/ContactsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class ContactsTests: XCTestCase {
XCTAssertEqual(contactBundle.walletAddress, fixtures.bob.walletAddress)
}

XCTAssert(fixtures.aliceClient.contacts.has(fixtures.bob.walletAddress))
let hasContact = await fixtures.aliceClient.contacts.has(fixtures.bob.walletAddress)
XCTAssert(hasContact)
}
}
70 changes: 1 addition & 69 deletions Tests/XMTPTests/ConversationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class ConversationTests: XCTestCase {
expectation1.expectedFulfillmentCount = 2

Task(priority: .userInitiated) {
for try await conversation in bobClient.conversations.stream() {
for try await conversation in await bobClient.conversations.stream() {
expectation1.fulfill()
}
}
Expand Down Expand Up @@ -549,30 +549,6 @@ class ConversationTests: XCTestCase {
XCTAssertEqual("hi", decodedMessage2.body)
}

func testCanSendEncodedContentV1Message() async throws {
try await publishLegacyContact(client: bobClient)
try await publishLegacyContact(client: aliceClient)

guard case let .v1(bobConversation) = try await bobClient.conversations.newConversation(with: alice.address) else {
XCTFail("did not get a v1 conversation for alice")
return
}

guard case let .v1(aliceConversation) = try await aliceClient.conversations.newConversation(with: bob.address) else {
XCTFail("did not get a v1 conversation for alice")
return
}

let encodedContent = try TextCodec().encode(content: "hi")

try await bobConversation.send(encodedContent: encodedContent, options: nil)

let messages = try await aliceConversation.messages()

XCTAssertEqual(1, messages.count)
XCTAssertEqual("hi", try messages[0].content())
}

func testCanSendEncodedContentV2Message() async throws {
guard case let .v2(bobConversation) = try await bobClient.conversations.newConversation(with: alice.address, context: InvitationV1.Context(conversationID: "hi")) else {
XCTFail("did not get a v1 conversation for alice")
Expand All @@ -594,50 +570,6 @@ class ConversationTests: XCTestCase {
XCTAssertEqual("hi", try messages[0].content())
}

func testCanSendGzipCompressedV1Messages() async throws {
try await publishLegacyContact(client: bobClient)
try await publishLegacyContact(client: aliceClient)

guard case let .v1(bobConversation) = try await bobClient.conversations.newConversation(with: alice.address) else {
XCTFail("did not get a v1 conversation for alice")
return
}

guard case let .v1(aliceConversation) = try await aliceClient.conversations.newConversation(with: bob.address) else {
XCTFail("did not get a v1 conversation for alice")
return
}

try await bobConversation.send(content: Array(repeating: "A", count: 1000).joined(), options: .init(compression: .gzip))

let messages = try await aliceConversation.messages()

XCTAssertEqual(1, messages.count)
XCTAssertEqual(Array(repeating: "A", count: 1000).joined(), try messages[0].content())
}

func testCanSendDeflateCompressedV1Messages() async throws {
try await publishLegacyContact(client: bobClient)
try await publishLegacyContact(client: aliceClient)

guard case let .v1(bobConversation) = try await bobClient.conversations.newConversation(with: alice.address) else {
XCTFail("did not get a v1 conversation for alice")
return
}

guard case let .v1(aliceConversation) = try await aliceClient.conversations.newConversation(with: bob.address) else {
XCTFail("did not get a v1 conversation for alice")
return
}

try await bobConversation.send(content: Array(repeating: "A", count: 1000).joined(), options: .init(compression: .deflate))

let messages = try await aliceConversation.messages()

XCTAssertEqual(1, messages.count)
XCTAssertEqual(Array(repeating: "A", count: 1000).joined(), try messages[0].content())
}

func testCanSendGzipCompressedV2Messages() async throws {
guard case let .v2(bobConversation) = try await bobClient.conversations.newConversation(with: alice.address, context: InvitationV1.Context(conversationID: "hi")) else {
XCTFail("did not get a v2 conversation for alice")
Expand Down
4 changes: 2 additions & 2 deletions Tests/XMTPTests/ConversationsTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ConversationsTests: XCTestCase {

let envelope = Envelope(topic: .userIntro(client.address), timestamp: created, message: try Message(v1: message).serializedData())

let conversation = try client.conversations.fromIntro(envelope: envelope)
let conversation = try await client.conversations.fromIntro(envelope: envelope)
XCTAssertEqual(conversation.peerAddress, newWallet.address)
XCTAssertEqual(conversation.createdAt.description, created.description)
}
Expand All @@ -55,7 +55,7 @@ class ConversationsTests: XCTestCase {
let peerAddress = fixtures.alice.walletAddress
let envelope = Envelope(topic: .userInvite(peerAddress), timestamp: created, message: try sealed.serializedData())

let conversation = try client.conversations.fromInvite(envelope: envelope)
let conversation = try await client.conversations.fromInvite(envelope: envelope)
XCTAssertEqual(conversation.peerAddress, newWallet.address)
XCTAssertEqual(conversation.createdAt.description, created.description)
}
Expand Down
4 changes: 2 additions & 2 deletions Tests/XMTPTests/IntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ final class IntegrationTests: XCTestCase {
options: opt
)
// And it uses the saved topic data for the conversation
let aliceConvo2 = alice2.conversations.importTopicData(
let aliceConvo2 = await alice2.conversations.importTopicData(
data: try Xmtp_KeystoreApi_V1_TopicMap.TopicData(serializedData: topicData))
XCTAssertEqual("example.com/alice-bob-1", aliceConvo2.conversationID)

Expand Down Expand Up @@ -520,7 +520,7 @@ final class IntegrationTests: XCTestCase {
expectation1.expectedFulfillmentCount = 2

Task(priority: .userInitiated) {
for try await convo in bobClient.conversations.stream() {
for try await convo in await bobClient.conversations.stream() {
expectation1.fulfill()
}
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/XMTPTests/PaginationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class PaginationTests: XCTestCase {
expectation1.expectedFulfillmentCount = 2

Task(priority: .userInitiated) {
for try await _ in bobClient.conversations.stream() {
for try await _ in await bobClient.conversations.stream() {
print("Got one conversation")
expectation1.fulfill()
}
Expand Down