Skip to content

Commit

Permalink
Fixes according to review #3
Browse files Browse the repository at this point in the history
  • Loading branch information
jguz-pubnub committed Jan 19, 2024
1 parent db9d96a commit b5798a8
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class PresenceEffectFactory: EffectHandlerFactory {

init(
session: SessionReplaceable,
sessionResponseQueue: DispatchQueue = .global(qos: .default),
sessionResponseQueue: DispatchQueue = .main,
presenceStateContainer: PubNubPresenceStateContainer
) {
self.session = session
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SubscribeEffectFactory: EffectHandlerFactory {

init(
session: SessionReplaceable,
sessionResponseQueue: DispatchQueue = .global(qos: .default),
sessionResponseQueue: DispatchQueue = .main,
messageCache: MessageCache = MessageCache(),
presenceStateContainer: PubNubPresenceStateContainer
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,7 @@ class EventEngineSubscriptionSessionStrategy: SubscriptionSessionStrategy {
if configuration.maintainPresenceState {
presenceStateContainer.removeState(forChannels: channels)
}
sendSubscribeEvent(event: .subscriptionChanged(
channels: newInput.allSubscribedChannelNames,
groups: newInput.allSubscribedGroupNames
))
sendPresenceEvent(event: .left(
channels: channels,
groups: groups
))

// Ensures that local event is emitted before receiving .disconnected connection status
notify {
$0.emit(subscribe: .subscriptionChanged(
.unsubscribed(
Expand All @@ -186,15 +178,21 @@ class EventEngineSubscriptionSessionStrategy: SubscriptionSessionStrategy {
))
)
}
sendSubscribeEvent(event: .subscriptionChanged(
channels: newInput.allSubscribedChannelNames,
groups: newInput.allSubscribedGroupNames
))
sendPresenceEvent(event: .left(
channels: channels,
groups: groups
))
}
}

func unsubscribeAll() {
let currentInput = subscribeEngine.state.input

sendSubscribeEvent(event: .unsubscribeAll)
sendPresenceEvent(event: .leftAll)

// Ensures that local event is emitted before receiving .disconnected connection status
notify {
$0.emit(subscribe: .subscriptionChanged(
.unsubscribed(
Expand All @@ -203,6 +201,9 @@ class EventEngineSubscriptionSessionStrategy: SubscriptionSessionStrategy {
)
))
}

sendSubscribeEvent(event: .unsubscribeAll)
sendPresenceEvent(event: .leftAll)
}
}

Expand Down
206 changes: 116 additions & 90 deletions Tests/PubNubTests/Integration/SubscriptionIntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,106 +15,132 @@ class SubscriptionIntegrationTests: XCTestCase {
let testsBundle = Bundle(for: SubscriptionIntegrationTests.self)
let testChannel = "SwiftSubscriptionITestsChannel"
let configuration = PubNubConfiguration(publishKey: "", subscribeKey: "", userId: UUID().uuidString)

func testSubscribeError() {
let subscribeExpect = expectation(description: "Subscribe Expectation")
let connectingExpect = expectation(description: "Connecting Expectation")
let disconnectedExpect = expectation(description: "Disconnected Expectation")

// Should return subscription key error
let configuration = PubNubConfiguration(publishKey: "", subscribeKey: "", userId: UUID().uuidString)
let pubnub = PubNub(configuration: configuration)

let listener = SubscriptionListener()
listener.didReceiveSubscription = { event in
switch event {
case let .connectionStatusChanged(status):
switch status {
case .connecting:
connectingExpect.fulfill()
case .disconnectedUnexpectedly:
disconnectedExpect.fulfill()
default:
XCTFail("Only should emit these two states")
let configuration = PubNubConfiguration(
publishKey: "",
subscribeKey: "",
userId: UUID().uuidString
)
let eeConfiguration = PubNubConfiguration(
publishKey: "",
subscribeKey: "",
userId: UUID().uuidString,
enableEventEngine: true
)

for config in [configuration, eeConfiguration] {
XCTContext.runActivity(named: "Testing configuration with enableEventEngine=\(config.enableEventEngine)") { _ in
let subscribeExpect = expectation(description: "Subscribe Expectation")
let connectingExpect = expectation(description: "Connecting Expectation")
let disconnectedExpect = expectation(description: "Disconnected Expectation")

// Should return subscription key error
let pubnub = PubNub(configuration: configuration)
let listener = SubscriptionListener()

listener.didReceiveSubscription = { event in
switch event {
case let .connectionStatusChanged(status):
switch status {
case .connecting:
connectingExpect.fulfill()
case .disconnectedUnexpectedly:
disconnectedExpect.fulfill()
default:
XCTFail("Only should emit these two states")
}
case .subscribeError:
subscribeExpect.fulfill() // 8E988B17-C0AA-42F1-A6F9-1461BF51C82C
default:
break
}
}
case .subscribeError:
subscribeExpect.fulfill() // 8E988B17-C0AA-42F1-A6F9-1461BF51C82C
default:
break

pubnub.add(listener)
pubnub.subscribe(to: [testChannel])

wait(for: [subscribeExpect, connectingExpect, disconnectedExpect], timeout: 10.0)
}
}

pubnub.add(listener)
pubnub.subscribe(to: [testChannel])

wait(for: [subscribeExpect, connectingExpect, disconnectedExpect], timeout: 10.0)
}

// swiftlint:disable:next function_body_length cyclomatic_complexity
func testUnsubscribeResubscribe() {
let totalLoops = 10

let subscribeExpect = expectation(description: "Subscribe Expectation")
subscribeExpect.expectedFulfillmentCount = totalLoops
let unsubscribeExpect = expectation(description: "Unsubscribe Expectation")
unsubscribeExpect.expectedFulfillmentCount = totalLoops
let publishExpect = expectation(description: "Publish Expectation")
publishExpect.expectedFulfillmentCount = totalLoops
let connectedExpect = expectation(description: "Connected Expectation")
connectedExpect.expectedFulfillmentCount = totalLoops
let disconnectedExpect = expectation(description: "Disconnected Expectation")
disconnectedExpect.expectedFulfillmentCount = totalLoops

let configuration = PubNubConfiguration(from: testsBundle)
let pubnub = PubNub(configuration: configuration)

var connectedCount = 0

let listener = SubscriptionListener()
listener.didReceiveSubscription = { [unowned self] event in
switch event {
case let .subscriptionChanged(status):
switch status {
case let .subscribed(channels, _):
XCTAssertTrue(channels.contains(where: { $0.id == self.testChannel }))
XCTAssertTrue(pubnub.subscribedChannels.contains(self.testChannel))
subscribeExpect.fulfill()
case let .responseHeader(channels, _, _, next):
XCTAssertTrue(channels.contains(where: { $0.id == self.testChannel }))
XCTAssertEqual(pubnub.previousTimetoken, next?.timetoken)
case let .unsubscribed(channels, _):
XCTAssertTrue(channels.contains(where: { $0.id == self.testChannel }))
XCTAssertFalse(pubnub.subscribedChannels.contains(self.testChannel))
unsubscribeExpect.fulfill()
}
case .messageReceived:
pubnub.unsubscribe(from: [self.testChannel])
publishExpect.fulfill()
case let .connectionStatusChanged(status):
switch status {
case .connected:
pubnub.publish(channel: self.testChannel, message: "Test") { _ in }
connectedCount += 1
connectedExpect.fulfill()
case .disconnected:
// Stop reconneced after N attempts
if connectedCount < totalLoops {
pubnub.subscribe(to: [self.testChannel])
let configurationFromBundle = PubNubConfiguration(
from: testsBundle
)
let configWithEventEngineEnabled = PubNubConfiguration(
publishKey: configurationFromBundle.publishKey,
subscribeKey: configurationFromBundle.subscribeKey,
userId: configurationFromBundle.userId,
enableEventEngine: true
)

for config in [configurationFromBundle, configWithEventEngineEnabled] {
XCTContext.runActivity(named: "Testing configuration with enableEventEngine=\(config.enableEventEngine)") { _ in
let totalLoops = 10
let subscribeExpect = expectation(description: "Subscribe Expectation")
subscribeExpect.expectedFulfillmentCount = totalLoops
let unsubscribeExpect = expectation(description: "Unsubscribe Expectation")
unsubscribeExpect.expectedFulfillmentCount = totalLoops
let publishExpect = expectation(description: "Publish Expectation")
publishExpect.expectedFulfillmentCount = totalLoops
let connectedExpect = expectation(description: "Connected Expectation")
connectedExpect.expectedFulfillmentCount = totalLoops
let disconnectedExpect = expectation(description: "Disconnected Expectation")
disconnectedExpect.expectedFulfillmentCount = totalLoops

let pubnub = PubNub(configuration: config)
var connectedCount = 0

let listener = SubscriptionListener()
listener.didReceiveSubscription = { [unowned self] event in
switch event {
case let .subscriptionChanged(status):
switch status {
case let .subscribed(channels, _):
XCTAssertTrue(channels.contains(where: { $0.id == self.testChannel }))
XCTAssertTrue(pubnub.subscribedChannels.contains(self.testChannel))
subscribeExpect.fulfill()
case let .responseHeader(channels, _, _, next):
XCTAssertTrue(channels.contains(where: { $0.id == self.testChannel }))
XCTAssertEqual(pubnub.previousTimetoken, next?.timetoken)
case let .unsubscribed(channels, _):
XCTAssertTrue(channels.contains(where: { $0.id == self.testChannel }))
XCTAssertFalse(pubnub.subscribedChannels.contains(self.testChannel))
unsubscribeExpect.fulfill()
}
case .messageReceived:
pubnub.unsubscribe(from: [self.testChannel])
publishExpect.fulfill()
case let .connectionStatusChanged(status):
switch status {
case .connected:
pubnub.publish(channel: self.testChannel, message: "Test") { _ in }
connectedCount += 1
connectedExpect.fulfill()
case .disconnected:
// Stop reconneced after N attempts
if connectedCount < totalLoops {
pubnub.subscribe(to: [self.testChannel])
}
disconnectedExpect.fulfill()
default:
break
}
case let .subscribeError(error):
XCTFail("An error was returned: \(error)")
default:
break
}
disconnectedExpect.fulfill()
default:
break
}
case let .subscribeError(error):
XCTFail("An error was returned: \(error)")
default:
break

pubnub.add(listener)
pubnub.subscribe(to: [testChannel])

wait(for: [subscribeExpect, unsubscribeExpect, publishExpect, connectedExpect, disconnectedExpect], timeout: 333.0)
}
}

pubnub.add(listener)
pubnub.subscribe(to: [testChannel])

wait(for: [subscribeExpect, unsubscribeExpect, publishExpect, connectedExpect, disconnectedExpect], timeout: 20.0)
}
}

0 comments on commit b5798a8

Please sign in to comment.