Skip to content

Commit

Permalink
Refactoring for "test__023__Presence__Channel_state_change_side_effec…
Browse files Browse the repository at this point in the history
…ts..." test.

Now similar to https://github.com/ably/ably-js/blob/main/test/realtime/presence.test.js#L1908-L2043 it uses additional client to generate leave event (which makes sence).
  • Loading branch information
maratal committed May 28, 2023
1 parent 9239d33 commit 9243472
Showing 1 changed file with 57 additions and 37 deletions.
94 changes: 57 additions & 37 deletions Test/Tests/RealtimeClientPresenceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -745,86 +745,106 @@ class RealtimeClientPresenceTests: XCTestCase {
}
}

func test__023__Presence__Channel_state_change_side_effects__channel_enters_the_SUSPENDED_state__should_maintain_the_PresenceMap_and_any_members_present_before_and_after_the_sync_should_not_emit_presence_events() throws {
func test__023__Presence__Channel_state_change_side_effects__channel_enters_the_SUSPENDED_state__members_map_is_preserved_and_only_members_that_changed_between_ATTACHED_states_should_result_in_presence_events() throws {
let test = Test()
let options = try AblyTests.commonAppSetup(for: test)
let channelName = test.uniqueChannelName()

var clientMembers: ARTRealtime?
clientMembers = AblyTests.addMembersSequentiallyToChannel(channelName, members: 3, options: options)
defer { clientMembers?.dispose(); clientMembers?.close() }

options.clientId = "tester"
let clientMembers = AblyTests.addMembersSequentiallyToChannel(channelName, members: 2, options: options)
defer { clientMembers.dispose(); clientMembers.close() }

options.clientId = "leaves"
let leavesClient = AblyTests.newRealtime(options).client
defer { leavesClient.dispose(); leavesClient.close() }

options.clientId = "main"
options.tokenDetails = try getTestTokenDetails(for: test, key: options.key!, clientId: options.clientId, ttl: 5.0)
let client = AblyTests.newRealtime(options).client
defer { client.dispose(); client.close() }
let channel = client.channels.get(channelName)
waitUntil(timeout: testTimeout) { done in
let partialDone = AblyTests.splitDone(3, done: done)
channel.presence.enter(nil) { error in
let mainClient = AblyTests.newRealtime(options).client
defer { mainClient.dispose(); mainClient.close() }

let leavesChannel = leavesClient.channels.get(channelName)
let mainChannel = mainClient.channels.get(channelName)

waitUntil(timeout: testTimeout.multiplied(by: 9)) { done in
let partialDone = AblyTests.splitDone(5, done: done)
mainChannel.presence.enter(nil) { error in
XCTAssertNil(error)
partialDone()
}
channel.presence.get { members, error in
leavesChannel.presence.enter(nil) { error in
XCTAssertNil(error)
partialDone()
}
mainChannel.presence.get { members, error in
XCTAssertNil(error)
if let members {
XCTAssertEqual(members.count, 3)
XCTAssertEqual(members.count, 3) // "user1", "user2", "leaves"
} else {
XCTFail("Expected members to be non-nil")
}
partialDone()
}
channel.presence.subscribe(.enter) { message in
if message.clientId == "tester" {
channel.presence.unsubscribe()
mainChannel.presence.subscribe { message in
if message.clientId == "main" {
XCTAssertEqual(message.action, ARTPresenceAction.enter)
mainChannel.presence.unsubscribe()
partialDone()
}
else if message.clientId == "leaves" {
XCTAssertEqual(message.action, ARTPresenceAction.present) // .enter was replaced by .present (RTP2d)
partialDone()
}
}
}

var presenceEvents = [ARTPresenceMessage]()
waitUntil(timeout: testTimeout) { done in
let partialDone = AblyTests.splitDone(4, done: done)
channel.presence.subscribe { presence in
XCTAssertEqual(presence.action, ARTPresenceAction.leave)
XCTAssertEqual(presence.clientId, "tester")
partialDone()
}
channel.once(.suspended) { _ in
channel.internalSync { _internal in
XCTAssertEqual(_internal.presenceMap.members.count, 4)
XCTAssertEqual(_internal.presenceMap.localMembers.count, 1)
mainChannel.presence.subscribe { presence in
presenceEvents += [presence]
delay(1) {
partialDone() // Wait a bit to make sure we don't receive any other presence messages
}
partialDone()
}
channel.once(.attached) { stateChange in
XCTAssertNil(stateChange.reason)
channel.presence.leave(nil) { error in
mainChannel.once(.suspended) { _ in
mainChannel.internalSync { _internal in
XCTAssertEqual(_internal.presenceMap.members.count, 4) // "main", "user1", "user2", "leaves"
XCTAssertEqual(_internal.presenceMap.localMembers.count, 1) // "main"
}
leavesChannel.presence.leave(nil) { error in
XCTAssertNil(error)
partialDone()
}
partialDone()
}
channel.internalAsync { _internal in
mainChannel.once(.attached) { stateChange in
XCTAssertNil(stateChange.reason)
partialDone()
}
mainChannel.internalAsync { _internal in
_internal.setSuspended(.init(state: .ok))
}
}
XCTAssertEqual(presenceEvents.count, 1)
XCTAssertEqual(presenceEvents[0].action, ARTPresenceAction.leave)
XCTAssertEqual(presenceEvents[0].clientId, "leaves")

channel.presence.unsubscribe()
mainChannel.presence.unsubscribe()
waitUntil(timeout: testTimeout) { done in
channel.presence.get { members, error in
mainChannel.presence.get { members, error in
XCTAssertNil(error)
guard let members = members else {
fail("Members is nil"); done(); return
}
XCTAssertEqual(members.count, 3)
XCTAssertEqual(members.count, 3) // "main", "user1", "user2"
expect(members).to(allPass { (member: ARTPresenceMessage?) in member!.action != .absent })
done()
}
}

channel.internalSync { _internal in
XCTAssertEqual(_internal.presenceMap.members.count, 3)
expect(_internal.presenceMap.localMembers).to(beEmpty())
mainChannel.internalSync { _internal in
XCTAssertEqual(_internal.presenceMap.members.count, 3) // "main", "user1", "user2"
XCTAssertEqual(_internal.presenceMap.localMembers.count, 1) // "main"
}
}

Expand Down

0 comments on commit 9243472

Please sign in to comment.