Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ECO-4962] feat: add ChatApi implementation #9

Merged
merged 2 commits into from
Sep 5, 2024

Conversation

ttypic
Copy link
Collaborator

@ttypic ttypic commented Sep 3, 2024

Resolves #8

Created basic ChatApi implementation to perform REST request to the Chat Backend

Summary by CodeRabbit

  • New Features

    • Introduced a ChatApi class for streamlined interaction with chat services, including message retrieval, sending, and occupancy information.
    • Added support for handling paginated data with a new PaginatedResult interface.
    • Enhanced JSON handling capabilities with the addition of the Gson library.
  • Improvements

    • Enhanced configurability of complexity analysis by excluding test directories from checks.
  • Bug Fixes

    • Adjusted dependency configurations to optimize library exposure and functionality.
  • Tests

    • Added a comprehensive suite of unit tests for the ChatApi class to ensure expected behavior.

Copy link

coderabbitai bot commented Sep 3, 2024

Walkthrough

The changes introduce a new ChatApi class designed for interacting with a chat service, featuring methods for retrieving messages, sending messages, and checking occupancy. Additionally, the project enhances its dependency management by incorporating Gson for JSON processing, along with new testing libraries. A new interface for managing paginated results has also been established, improving the overall structure and functionality of the codebase.

Changes

File Change Summary
chat-android/build.gradle.kts Changed ably.android dependency from implementation to api and added gson, mockk, and coroutine.test dependencies.
chat-android/src/main/java/com/ably/chat/ChatApi.kt Introduced ChatApi class with methods for message retrieval, sending, and occupancy.
chat-android/src/main/java/com/ably/chat/PaginatedResult.kt Added PaginatedResult interface and extension function for handling paginated results.
chat-android/src/test/java/com/ably/chat/ChatApiTest.kt Introduced unit tests for ChatApi methods.
gradle/libs.versions.toml Introduced Gson, MockK, and Coroutine library dependency versions for JSON handling and testing.
detekt.yml Added excludes property to ignore test directories in complexity checks.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ChatApi
    participant RealtimeClient
    participant Server

    User->>ChatApi: getMessages(roomId, params)
    ChatApi->>RealtimeClient: fetchMessages(roomId, params)
    RealtimeClient->>Server: HTTP GET /messages
    Server-->>RealtimeClient: return messages
    RealtimeClient-->>ChatApi: messages
    ChatApi-->>User: return messages
Loading
sequenceDiagram
    participant User
    participant ChatApi
    participant RealtimeClient
    participant Server

    User->>ChatApi: sendMessage(roomId, params)
    ChatApi->>RealtimeClient: sendMessage(roomId, params)
    RealtimeClient->>Server: HTTP POST /messages
    Server-->>RealtimeClient: return response
    RealtimeClient-->>ChatApi: response
    ChatApi-->>User: return response
Loading

Assessment against linked issues

Objective Addressed Explanation
Implement ChatApi (ECO-4962)

🐰 In the meadow, I hop with glee,
New ChatApi brings joy to me!
Messages sent and received with grace,
With Gson's help, we quicken the pace.
Test cases added, all snug and tight,
Hooray for the code, it feels just right! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

/**
* Represents the result of a paginated query.
*/
interface PaginatedResult<T> {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use lightweight version of PaginatedResult, not sure we actually need first() and isLast() methods

Created basic ChatApi implementation to perform REST request to the Chat Backend
@ttypic ttypic force-pushed the ECO-4962/chat-api-implementation branch from 08ad21b to 727b8d2 Compare September 3, 2024 12:26
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 6b55e22 and 727b8d2.

Files selected for processing (6)
  • chat-android/build.gradle.kts (1 hunks)
  • chat-android/src/main/java/com/ably/chat/ChatApi.kt (1 hunks)
  • chat-android/src/main/java/com/ably/chat/ErrorCodes.kt (1 hunks)
  • chat-android/src/main/java/com/ably/chat/Message.kt (2 hunks)
  • chat-android/src/main/java/com/ably/chat/PaginatedResult.kt (1 hunks)
  • gradle/libs.versions.toml (2 hunks)
Files skipped from review due to trivial changes (1)
  • chat-android/src/main/java/com/ably/chat/Message.kt
Additional comments not posted (11)
chat-android/build.gradle.kts (2)

38-38: LGTM!

The code change is approved. The addition of the gson library for JSON handling aligns with the AI-generated summary.


37-37: Verify the impact of changing the dependency configuration from implementation to api.

Changing the dependency configuration from implementation to api for libs.ably.android will expose the library's public APIs to other modules. This might have implications on the visibility and encapsulation of the library.

Run the following script to verify the usage of the ably.android library in the codebase:

Verification successful

No direct usage of ably.android found in the codebase.

The change from implementation to api for libs.ably.android does not currently impact the codebase, as there are no direct usages of the library in the Kotlin files. Future development might be affected if other modules start using it.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the `ably.android` library in the codebase.

# Test: Search for the usage of the `ably.android` library. Expect: Only intended usage.
rg --type kotlin -A 5 $'import com\.ably\.android'

Length of output: 51


Script:

#!/bin/bash
# Description: Search for any usage of the `ably.android` library in the codebase, including indirect usage or different import patterns.

# Test: Search for any reference to `ably.android` in the codebase.
rg --type kotlin -A 5 'ably\.android'

Length of output: 424

chat-android/src/main/java/com/ably/chat/PaginatedResult.kt (5)

14-14: The existing comment has been addressed as the first() and isLast() methods are not included in the PaginatedResult interface.


14-32: LGTM!

The PaginatedResult interface is well-defined and provides the necessary functionality for paginated results.


34-35: LGTM!

The toPaginatedResult function is correctly implemented and handles the null case appropriately.


37-44: LGTM!

The EmptyPaginatedResult class is correctly implemented and serves as a placeholder for empty paginated results.


46-66: LGTM!

The AsyncPaginatedResultWrapper class is correctly implemented and provides a convenient way to wrap an AsyncHttpPaginatedResponse and expose it as a PaginatedResult<T>.

gradle/libs.versions.toml (1)

17-17: LGTM!

The changes to add the Gson library dependency are approved. The dependency is correctly defined in the [versions] and [libraries] sections of the gradle/libs.versions.toml file.

Gson is a widely used library for handling JSON serialization and deserialization in Java and Android projects. Including it as a dependency is a common practice and does not raise any concerns.

Also applies to: 40-40

chat-android/src/main/java/com/ably/chat/ChatApi.kt (3)

22-38: LGTM!

The code changes are approved.


40-61: LGTM!

The code changes are approved.


63-70: LGTM!

The code changes are approved.

@ttypic ttypic changed the base branch from fix/add-missing-interface to main September 3, 2024 13:19
params = params.toParams(),
) {
Message(
timeserial = it.asJsonObject.get("timeserial").asString,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need something here to validate that the response returned is valid in structure?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question! @AndyTWF what do you think we should do if we got invalid JSON object? Should we throw AblyException with 500 code?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think that's wise - it should never happen, but I'd much prefer we shout loudly about something not being as we expect than let it slip by and have unintended side-effects.

Per Simon's spec suggestion for protocol v3, we should silently ignore stuff we aren't expecting!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added explicit validation and couple of unit tests that check we are silently ignore stuff we aren't expecting and if response is invalid or required fields are missing it will throw AblyException

@ttypic ttypic force-pushed the ECO-4962/chat-api-implementation branch from f96899d to 9d3656c Compare September 4, 2024 14:16
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 727b8d2 and 9d3656c.

Files selected for processing (6)
  • chat-android/build.gradle.kts (1 hunks)
  • chat-android/src/main/java/com/ably/chat/ChatApi.kt (1 hunks)
  • chat-android/src/main/java/com/ably/chat/PaginatedResult.kt (1 hunks)
  • chat-android/src/test/java/com/ably/chat/ChatApiTest.kt (1 hunks)
  • detekt.yml (1 hunks)
  • gradle/libs.versions.toml (2 hunks)
Files skipped from review as they are similar to previous changes (4)
  • chat-android/build.gradle.kts
  • chat-android/src/main/java/com/ably/chat/ChatApi.kt
  • chat-android/src/main/java/com/ably/chat/PaginatedResult.kt
  • gradle/libs.versions.toml
Additional comments not posted (6)
chat-android/src/test/java/com/ably/chat/ChatApiTest.kt (5)

21-59: LGTM!

The test function is well-written and tests the expected behavior of the getMessages function.


61-83: LGTM!

The test function is well-written and tests the expected behavior of the getMessages function.


85-118: LGTM!

The test function is well-written and tests the expected behavior of the sendMessage function.


120-141: LGTM!

The test function is well-written and tests the expected behavior of the sendMessage function.


143-163: LGTM!

The test function is well-written and tests the expected behavior of the getOccupancy function.

detekt.yml (1)

151-151: LGTM!

The code changes are approved. Excluding test directories from the StringLiteralDuplication check is a good practice as test code often contains duplicated string literals for test data setup.

@ttypic ttypic force-pushed the ECO-4962/chat-api-implementation branch 2 times, most recently from 806da45 to 86da17b Compare September 4, 2024 16:32
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9d3656c and 86da17b.

Files selected for processing (6)
  • chat-android/build.gradle.kts (1 hunks)
  • chat-android/src/main/java/com/ably/chat/ChatApi.kt (1 hunks)
  • chat-android/src/main/java/com/ably/chat/PaginatedResult.kt (1 hunks)
  • chat-android/src/test/java/com/ably/chat/ChatApiTest.kt (1 hunks)
  • detekt.yml (1 hunks)
  • gradle/libs.versions.toml (2 hunks)
Files skipped from review as they are similar to previous changes (3)
  • chat-android/src/main/java/com/ably/chat/ChatApi.kt
  • chat-android/src/main/java/com/ably/chat/PaginatedResult.kt
  • chat-android/src/test/java/com/ably/chat/ChatApiTest.kt
Additional comments not posted (9)
chat-android/build.gradle.kts (4)

37-37: LGTM!

The code changes are approved.


38-38: LGTM!

The code changes are approved.


41-41: LGTM!

The code changes are approved.


42-42: LGTM!

The code changes are approved.

gradle/libs.versions.toml (4)

17-17: LGTM!

The version declaration for the Gson library is approved.


18-18: LGTM!

The version declaration for the MockK library is approved.


19-19: LGTM!

The version declaration for the Coroutine library is approved.


42-42: LGTM!

The library definitions for Gson, MockK, and Coroutine libraries are approved. They correctly reference the corresponding version declarations.

Also applies to: 44-44, 46-47

detekt.yml (1)

151-151: LGTM!

The code changes are approved:

  • Correctly adds the excludes property under the StringLiteralDuplication rule in the complexity section.
  • Follows the YAML syntax.
  • Excludes common test directories from the StringLiteralDuplication rule, which is a good practice as test code often contains duplicated string literals.
  • Covers test directories across different platforms (Android, common, JVM, JS, iOS).

@ttypic ttypic force-pushed the ECO-4962/chat-api-implementation branch from 86da17b to 5c3bcaf Compare September 4, 2024 16:40
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 86da17b and 5c3bcaf.

Files selected for processing (6)
  • chat-android/build.gradle.kts (1 hunks)
  • chat-android/src/main/java/com/ably/chat/ChatApi.kt (1 hunks)
  • chat-android/src/main/java/com/ably/chat/PaginatedResult.kt (1 hunks)
  • chat-android/src/test/java/com/ably/chat/ChatApiTest.kt (1 hunks)
  • detekt.yml (1 hunks)
  • gradle/libs.versions.toml (2 hunks)
Files skipped from review as they are similar to previous changes (4)
  • chat-android/build.gradle.kts
  • chat-android/src/main/java/com/ably/chat/ChatApi.kt
  • chat-android/src/main/java/com/ably/chat/PaginatedResult.kt
  • chat-android/src/test/java/com/ably/chat/ChatApiTest.kt
Additional comments not posted (5)
gradle/libs.versions.toml (4)

17-17: LGTM!

The version declaration for the Gson library is approved.


18-18: LGTM!

The version declaration for the MockK library is approved.


19-19: LGTM!

The version declaration for the Coroutine library is approved.


42-42: LGTM!

The library declarations for Gson, MockK, and Coroutine libraries are approved. They match the corresponding version references.

Also applies to: 44-44, 46-47

detekt.yml (1)

151-151: LGTM!

The code changes are approved. Excluding test directories from the StringLiteralDuplication rule is a good practice.

}

fun <T> AsyncHttpPaginatedResponse?.toPaginatedResult(transform: (JsonElement) -> T): PaginatedResult<T> =
this?.let { AsyncPaginatedResultWrapper(it, transform) } ?: EmptyPaginatedResult()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when would EmptyPaginatedResult() get returned?

Copy link
Collaborator Author

@ttypic ttypic Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now when there is no body, core Java SDK return null. I don't like this because we already return container, that can be empty, so I return EmptyPaginatedResult instead. For end user there is no difference between empty list and empty body, the same behavior we have in js.

The other case is when we invoke next() and hasNext() is false. I personally would throw exception in this case, but decided not to do this, because we don't throw exception in core SDK, and silently return null. Once again don't want to return null, because you definitely don't want to do null-checks here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting - I personally think returning null makes more sense when looking at the code but I am coming from an optional-centric (and crazy) language in Swift. This will likely be one of the points in which we deviate between Kotlin and Swift due to platform best practices

Copy link
Collaborator Author

@ttypic ttypic Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it's Kotlin best practice, the best practice probably would be throwing exceptions, but I decide to silence them as Ably Java does. This will be an extremely small change.

And about optional-centricity: from the SDK user’s perspective, I personally don’t think PaginatedResult#next() should return a nullable result, both for Swift and Kotlin—I’ve never seen this before, except in Ably Java. :) Users will have to handle this nullability on their own, but there is no reason for that.

This commit adds validation for incoming JSONs from the Chat Backend. If any required fields are missing or have the wrong type, a bad request exception will be thrown on the SDK side.
@ttypic ttypic force-pushed the ECO-4962/chat-api-implementation branch from 5c3bcaf to 783cd4a Compare September 5, 2024 12:14
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 5c3bcaf and 783cd4a.

Files selected for processing (6)
  • chat-android/build.gradle.kts (1 hunks)
  • chat-android/src/main/java/com/ably/chat/ChatApi.kt (1 hunks)
  • chat-android/src/main/java/com/ably/chat/PaginatedResult.kt (1 hunks)
  • chat-android/src/test/java/com/ably/chat/ChatApiTest.kt (1 hunks)
  • detekt.yml (1 hunks)
  • gradle/libs.versions.toml (2 hunks)
Files skipped from review due to trivial changes (1)
  • chat-android/build.gradle.kts
Files skipped from review as they are similar to previous changes (4)
  • chat-android/src/main/java/com/ably/chat/ChatApi.kt
  • chat-android/src/main/java/com/ably/chat/PaginatedResult.kt
  • chat-android/src/test/java/com/ably/chat/ChatApiTest.kt
  • gradle/libs.versions.toml
Additional comments not posted (1)
detekt.yml (1)

151-151: Approve the exclusion of test directories from complexity checks.

The addition of the excludes property under the complexity section is a good practice as it helps focus complexity analysis on production code, avoiding unnecessary complexity checks on test code. The directories specified (**/test/**, **/androidTest/**, **/commonTest/**, **/jvmTest/**, **/jsTest/**, **/iosTest/**) are typical for Kotlin projects and cover a comprehensive range of test directories across different platforms and test environments.

@ttypic ttypic merged commit 0e0a264 into main Sep 5, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement ChatApi
3 participants