-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #33 from ably-labs/19-fetch-room
[ECO-4936] Implement the ability to fetch a room
- Loading branch information
Showing
12 changed files
with
308 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import Ably | ||
|
||
/** | ||
The error domain used for the ``Ably.ARTErrorInfo`` error instances thrown by the Ably Chat SDK. | ||
See ``ErrorCode`` for the possible ``ARTErrorInfo.code`` values. | ||
*/ | ||
public let errorDomain = "AblyChatErrorDomain" | ||
|
||
/** | ||
The error codes for errors in the ``errorDomain`` error domain. | ||
*/ | ||
public enum ErrorCode: Int { | ||
/// ``Rooms.get(roomID:options:)`` was called with a different set of room options than was used on a previous call. You must first release the existing room instance using ``Rooms.release(roomID:)``. | ||
/// | ||
/// TODO this code is a guess, revisit in https://github.com/ably-labs/ably-chat-swift/issues/32 | ||
case inconsistentRoomOptions = 1 | ||
|
||
/// The ``ARTErrorInfo.statusCode`` that should be returned for this error. | ||
internal var statusCode: Int { | ||
// TODO: These are currently a guess, revisit in https://github.com/ably-labs/ably-chat-swift/issues/32 | ||
switch self { | ||
case .inconsistentRoomOptions: | ||
400 | ||
} | ||
} | ||
} | ||
|
||
/** | ||
The errors thrown by the Chat SDK. | ||
This type exists in addition to ``ErrorCode`` to allow us to attach metadata which can be incorporated into the error’s `localizedDescription`. | ||
*/ | ||
internal enum ChatError { | ||
case inconsistentRoomOptions(requested: RoomOptions, existing: RoomOptions) | ||
|
||
/// The ``ARTErrorInfo.code`` that should be returned for this error. | ||
internal var code: ErrorCode { | ||
switch self { | ||
case .inconsistentRoomOptions: | ||
.inconsistentRoomOptions | ||
} | ||
} | ||
|
||
/// The ``ARTErrorInfo.localizedDescription`` that should be returned for this error. | ||
internal var localizedDescription: String { | ||
switch self { | ||
case let .inconsistentRoomOptions(requested, existing): | ||
"Rooms.get(roomID:options:) was called with a different set of room options than was used on a previous call. You must first release the existing room instance using Rooms.release(roomID:). Requested options: \(requested), existing options: \(existing)" | ||
} | ||
} | ||
} | ||
|
||
internal extension ARTErrorInfo { | ||
convenience init(chatError: ChatError) { | ||
var userInfo: [String: Any] = [:] | ||
// TODO: copied and pasted from implementation of -[ARTErrorInfo createWithCode:status:message:requestId:] because there’s no way to pass domain; revisit in https://github.com/ably-labs/ably-chat-swift/issues/32. Also the ARTErrorInfoStatusCode variable in ably-cocoa is not public. | ||
userInfo["ARTErrorInfoStatusCode"] = chatError.code.statusCode | ||
userInfo[NSLocalizedDescriptionKey] = chatError.localizedDescription | ||
|
||
self.init( | ||
domain: errorDomain, | ||
code: chatError.code.rawValue, | ||
userInfo: userInfo | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,42 @@ | ||
import Ably | ||
|
||
public protocol Rooms: AnyObject, Sendable { | ||
func get(roomID: String, options: RoomOptions) throws -> any Room | ||
func get(roomID: String, options: RoomOptions) async throws -> any Room | ||
func release(roomID: String) async throws | ||
var clientOptions: ClientOptions { get } | ||
} | ||
|
||
internal actor DefaultRooms: Rooms { | ||
/// Exposed so that we can test it. | ||
internal nonisolated let realtime: RealtimeClient | ||
internal nonisolated let clientOptions: ClientOptions | ||
|
||
/// The set of rooms, keyed by room ID. | ||
private var rooms: [String: DefaultRoom] = [:] | ||
|
||
internal init(realtime: RealtimeClient, clientOptions: ClientOptions) { | ||
self.realtime = realtime | ||
self.clientOptions = clientOptions | ||
} | ||
|
||
internal func get(roomID: String, options: RoomOptions) throws -> any Room { | ||
// CHA-RC1b | ||
if let existingRoom = rooms[roomID] { | ||
if existingRoom.options != options { | ||
throw ARTErrorInfo( | ||
chatError: .inconsistentRoomOptions(requested: options, existing: existingRoom.options) | ||
) | ||
} | ||
|
||
return existingRoom | ||
} else { | ||
let room = DefaultRoom(realtime: realtime, roomID: roomID, options: options) | ||
rooms[roomID] = room | ||
return room | ||
} | ||
} | ||
|
||
internal func release(roomID _: String) async throws { | ||
fatalError("Not yet implemented") | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
@testable import AblyChat | ||
import XCTest | ||
|
||
class DefaultChatClientTests: XCTestCase { | ||
func test_init_withoutClientOptions() { | ||
// Given: An instance of DefaultChatClient is created with nil clientOptions | ||
let client = DefaultChatClient(realtime: MockRealtime.create(), clientOptions: nil) | ||
|
||
// Then: It uses the default client options | ||
let defaultOptions = ClientOptions() | ||
XCTAssertTrue(client.clientOptions.isEqualForTestPurposes(defaultOptions)) | ||
} | ||
|
||
func test_rooms() throws { | ||
// Given: An instance of DefaultChatClient | ||
let realtime = MockRealtime.create() | ||
let options = ClientOptions() | ||
let client = DefaultChatClient(realtime: realtime, clientOptions: options) | ||
|
||
// Then: Its `rooms` property returns an instance of DefaultRooms with the same realtime client and client options | ||
let rooms = client.rooms | ||
|
||
let defaultRooms = try XCTUnwrap(rooms as? DefaultRooms) | ||
XCTAssertIdentical(defaultRooms.realtime, realtime) | ||
XCTAssertTrue(defaultRooms.clientOptions.isEqualForTestPurposes(options)) | ||
} | ||
} |
Oops, something went wrong.