Skip to content

Commit

Permalink
Implement RTP11d. (#636)
Browse files Browse the repository at this point in the history
Fixes #630.
  • Loading branch information
tcard authored Sep 15, 2017
1 parent 03c412b commit 16cc357
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Source/ARTPresenceMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ ART_ASSUME_NONNULL_BEGIN
- (void)onceSyncEnds:(void (^)(__GENERIC(NSArray, ARTPresenceMessage *) *))callback;
- (void)onceSyncFails:(void (^)(ARTErrorInfo *))callback;

- (void)internalAdd:(ARTPresenceMessage *)message;

@end

ART_ASSUME_NONNULL_END
10 changes: 7 additions & 3 deletions Source/ARTRealtimePresence.m
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,17 @@ - (void)get:(ARTRealtimePresenceQuery *)query callback:(void (^)(NSArray<ARTPres

dispatch_async(_queue, ^{
ART_TRY_OR_MOVE_TO_FAILED_START(_channel.realtime) {
[_channel throwOnDisconnectedOrFailed];

switch (_channel.state_nosync) {
case ARTRealtimeChannelFailed:
case ARTRealtimeChannelDetached:
if (callback) callback(nil, [ARTErrorInfo createWithCode:0 message:@"invalid channel state"]);
return;
case ARTRealtimeChannelSuspended:
if (query && !query.waitForSync) {
if (callback) callback(_channel.presenceMap.members.allValues, nil);
return;
}
if (callback) callback(nil, [ARTErrorInfo createWithCode:91005 message:@"presence state is out of sync due to the channel being SUSPENDED"]);
return;
default:
break;
}
Expand Down
76 changes: 76 additions & 0 deletions Spec/RealtimeClientPresence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3430,6 +3430,82 @@ class RealtimeClientPresence: QuickSpec {

expect(channel.state).toEventually(equal(ARTRealtimeChannelState.detached), timeout: testTimeout)
}

// RTP11d
context("If the Channel is in the SUSPENDED state then") {
func getSuspendedChannel() -> (ARTRealtimeChannel, ARTRealtime) {
let options = AblyTests.commonAppSetup()

let client = ARTRealtime(options: options)
let channel = client.channels.get("test")

waitUntil(timeout: testTimeout) { done in
channel.once(.suspended) { _ in
done()
}
client.onSuspended()
}

return (channel, client)
}

for (name, getPresence) in [
("by default", { channel, callback in
channel.presence.get(callback)
}),
("if waitForSync is true", { channel, callback in
let params = ARTRealtimePresenceQuery()
params.waitForSync = true
channel.presence.get(params, callback: callback)
})
] as [(String, (ARTRealtimeChannel, @escaping ([ARTPresenceMessage]?, ARTErrorInfo?) -> Void) -> Void)] {
context(name) {
it("results in an error") {
let (channel, client) = getSuspendedChannel()
defer { client.dispose(); client.close() }

getPresence(channel) { result, err in
expect(result).to(beNil())
expect(err).toNot(beNil())
guard let err = err else {
return
}
expect(err.code).to(equal(91005))
}
}
}
}

context("if waitForSync is false") {
let getParams = ARTRealtimePresenceQuery()
getParams.waitForSync = false

it("returns the members in the current PresenceMap") {
let (channel, client) = getSuspendedChannel()
defer { client.dispose(); client.close() }

var msgs = [String: ARTPresenceMessage]()
for i in 0..<3 {
let msg = ARTPresenceMessage(clientId: "client\(i)", action: .present, connectionId: "foo", id: "foo:0:0")
msgs[msg.clientId!] = msg
channel.presenceMap.internalAdd(msg)
}

channel.presence.get(getParams) { result, err in
expect(err).to(beNil())
expect(result).toNot(beNil())
guard let result = result else {
return
}
var resultByClient = [String: ARTPresenceMessage]()
for msg in result {
resultByClient[msg.clientId ?? "(no clientId)"] = msg
}
expect(resultByClient).to(equal(msgs))
}
}
}
}

// RTP11c
context("Query (set of params)") {
Expand Down

0 comments on commit 16cc357

Please sign in to comment.