-
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.
It’s unlikely that we’re going to have a working unified test suite before the beta release, so here are some very basic smoke tests just to give us a _little bit_ of confidence that things are kind of working and that we don’t introduce major regressions. Would be good to have a way of separating these from the unit tests so that they don’t slow them down, but can figure that out later; I don’t have loads of time to spend on this at the moment.
- Loading branch information
1 parent
9454e40
commit 1c2bf47
Showing
8 changed files
with
154 additions
and
2 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "Tests/AblyChatTests/ably-common"] | ||
path = Tests/AblyChatTests/ably-common | ||
url = https://github.com/ably/ably-common |
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,2 +1,5 @@ | ||
# Don’t try and format the asset catalogue JSON files, which are managed by Xcode | ||
*.xcassets/ | ||
|
||
# Submodules | ||
Tests/AblyChatTests/ably-common |
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,50 @@ | ||
import Foundation | ||
|
||
/// Provides the ``createAPIKey()`` function to create an API key for the Ably sandbox environment. | ||
enum Sandbox { | ||
private struct TestApp: Codable { | ||
var keys: [Key] | ||
|
||
struct Key: Codable { | ||
var keyStr: String | ||
} | ||
} | ||
|
||
enum Error: Swift.Error { | ||
case badResponseStatus(Int) | ||
} | ||
|
||
private static func loadAppCreationRequestBody() async throws -> Data { | ||
let testAppSetupFileURL = Bundle.module.url( | ||
forResource: "test-app-setup", | ||
withExtension: "json", | ||
subdirectory: "ably-common/test-resources" | ||
)! | ||
|
||
let (data, _) = try await URLSession.shared.data(for: .init(url: testAppSetupFileURL)) | ||
// swiftlint:disable:next force_cast | ||
let dictionary = try JSONSerialization.jsonObject(with: data) as! [String: Any] | ||
return try JSONSerialization.data(withJSONObject: dictionary["post_apps"]!) | ||
} | ||
|
||
static func createAPIKey() async throws -> String { | ||
var request = URLRequest(url: .init(string: "https://sandbox-rest.ably.io/apps")!) | ||
request.httpMethod = "POST" | ||
request.addValue("application/json", forHTTPHeaderField: "Content-Type") | ||
request.httpBody = try await loadAppCreationRequestBody() | ||
|
||
let (data, response) = try await URLSession.shared.data(for: request) | ||
|
||
// swiftlint:disable:next force_cast | ||
let statusCode = (response as! HTTPURLResponse).statusCode | ||
|
||
guard (200 ..< 300).contains(statusCode) else { | ||
throw Error.badResponseStatus(statusCode) | ||
} | ||
|
||
let testApp = try JSONDecoder().decode(TestApp.self, from: data) | ||
|
||
// From JS chat repo at 7985ab7 — "The key we need to use is the one at index 5, which gives enough permissions to interact with Chat and Channels" | ||
return testApp.keys[5].keyStr | ||
} | ||
} |
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,78 @@ | ||
import Ably | ||
import AblyChat | ||
import Testing | ||
|
||
/// Some very basic integration tests, just to check that things are kind of working. | ||
/// | ||
/// It would be nice to give this a time limit, but unfortunately the `timeLimit` trait is only available on iOS 16 etc and above. CodeRabbit suggested writing a timeout function myself and wrapping the contents of the test in it, but I didn’t have time to try understanding its suggested code, so it can wait. | ||
@Suite | ||
struct IntegrationTests { | ||
private static func createSandboxRealtime(apiKey: String) -> ARTRealtime { | ||
let realtimeOptions = ARTClientOptions(key: apiKey) | ||
realtimeOptions.environment = "sandbox" | ||
realtimeOptions.clientId = UUID().uuidString | ||
|
||
return ARTRealtime(options: realtimeOptions) | ||
} | ||
|
||
private static func createSandboxChatClient(apiKey: String) -> DefaultChatClient { | ||
let realtime = createSandboxRealtime(apiKey: apiKey) | ||
return DefaultChatClient(realtime: realtime, clientOptions: nil) | ||
} | ||
|
||
@Test | ||
func basicIntegrationTest() async throws { | ||
let apiKey = try await Sandbox.createAPIKey() | ||
|
||
// (1) Create a couple of chat clients — one for sending and one for receiving | ||
let txClient = Self.createSandboxChatClient(apiKey: apiKey) | ||
let rxClient = Self.createSandboxChatClient(apiKey: apiKey) | ||
|
||
// (2) Fetch a room | ||
let roomID = "basketball" | ||
let txRoom = try await txClient.rooms.get(roomID: roomID, options: .init()) | ||
let rxRoom = try await rxClient.rooms.get(roomID: roomID, options: .init()) | ||
|
||
// (3) Subscribe to room status | ||
let rxRoomStatusSubscription = await rxRoom.onStatusChange(bufferingPolicy: .unbounded) | ||
|
||
// (4) Attach the room so we can receive messages on it | ||
try await rxRoom.attach() | ||
|
||
// (5) Check that we received an ATTACHED status change as a result of attaching the room | ||
_ = try #require(await rxRoomStatusSubscription.first { $0.current == .attached }) | ||
#expect(await rxRoom.status == .attached) | ||
|
||
// (6) Send a message before subscribing to messages, so that later on we can check history works. | ||
|
||
// Create a throwaway subscription and wait for it to receive a message. This is to make sure that rxRoom has seen the message that we send here, so that the first message we receive on the subscription created in (7) is that which we’ll send in (8), and not that which we send here. | ||
let throwawayRxMessageSubscription = try await rxRoom.messages.subscribe(bufferingPolicy: .unbounded) | ||
|
||
// Send the message | ||
let txMessageBeforeRxSubscribe = try await txRoom.messages.send(params: .init(text: "Hello from txRoom, before rxRoom subscribe")) | ||
|
||
// Wait for rxRoom to see the message we just sent | ||
let throwawayRxMessage = try #require(await throwawayRxMessageSubscription.first { _ in true }) | ||
#expect(throwawayRxMessage == txMessageBeforeRxSubscribe) | ||
|
||
// (7) Subscribe to messages | ||
let rxMessageSubscription = try await rxRoom.messages.subscribe(bufferingPolicy: .unbounded) | ||
|
||
// (8) Now that we’re subscribed to messages, send a message on the other client and check that we receive it on the subscription | ||
let txMessageAfterRxSubscribe = try await txRoom.messages.send(params: .init(text: "Hello from txRoom, after rxRoom subscribe")) | ||
let rxMessageFromSubscription = try #require(await rxMessageSubscription.first { _ in true }) | ||
#expect(rxMessageFromSubscription == txMessageAfterRxSubscribe) | ||
|
||
// (9) Fetch historical messages from before subscribing, and check we get txMessageBeforeRxSubscribe | ||
let rxMessagesBeforeSubscribing = try await rxMessageSubscription.getPreviousMessages(params: .init()) | ||
try #require(rxMessagesBeforeSubscribing.items.count == 1) | ||
#expect(rxMessagesBeforeSubscribing.items[0] == txMessageBeforeRxSubscribe) | ||
|
||
// (10) Detach the room | ||
try await rxRoom.detach() | ||
|
||
// (11) Check that we received a DETACHED status change as a result of detaching the room | ||
_ = try #require(await rxRoomStatusSubscription.first { $0.current == .detached }) | ||
#expect(await rxRoom.status == .detached) | ||
} | ||
} |
Submodule ably-common
added at
60fd9c