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-5196] Message edit/delete #100

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

Conversation

sacOO7
Copy link
Contributor

@sacOO7 sacOO7 commented Feb 4, 2025

TODO's

  • Implement message edit and delete
  • Add relevant tests for the same.
    Update public doc/ README for usage of messages edit/delete ( will be done as a part of web docs )

Summary by CodeRabbit

  • New Features

    • Users can now update and delete messages, offering greater control over chat content.
    • Messages include additional details like version and timestamp to improve tracking.
    • Real-time interactions have been refined with enhanced reactions, presence, occupancy, and typing indicators.
  • Chores

    • Upgraded the underlying chat library for improved performance and reliability.

Copy link

coderabbitai bot commented Feb 4, 2025

Walkthrough

This pull request refines chat message handling by updating the ChatApi logic, enhancing message construction, and improving error management. New methods to update and delete messages have been added, and the Message data class now includes versioning, timestamp, and operational details. The EventTypes definitions have been updated for consistent naming, and the Messages interface now supports update and delete operations. Several tests and integration suites have been revised or added to validate these changes, while metadata handling has been refined and the ably library version has been upgraded.

Changes

File Path(s) Change Summary
chat-android/src/main/java/com/ably/chat/ChatApi.kt Refactored message creation and retrieval in getMessages; added updateMessage and deleteMessage methods; simplified sendMessage and updated error handling.
.../EventTypes.kt Renamed PubSubMessageNames to PubSubEventName and ChatMessage to CHAT_MESSAGE; added messageActionToEventType mapping.
.../Message.kt Added properties version, timestamp, and operation; introduced toMessageOperation functions with enhanced documentation.
.../Messages.kt Extended interface with update and delete methods; updated the send and subscribe methods to handle message updates/deletes and event mapping.
.../Metadata.kt & .../OperationMetadata.kt Changed Metadata alias from JsonElement to JsonObject; added new OperationMetadata alias for operation details.
.../Room.kt & .../RoomReactions.kt Removed file-level suppressions; updated reactions subscription to extract metadata as a JSON object.
Test Files (various files under chat-android/src/test/java/com/ably/chat/ and subdirectories) Updated unit tests to include new message properties; added integration tests for connection, messages, occupancy, presence, reactions, room lifecycle, and typing; removed deprecated SandboxTest.kt.
example/src/main/java/com/ably/chat/example/MainActivity.kt Updated preview function to include version and timestamp properties in the Message object.
gradle/libs.versions.toml Upgraded the ably library version from 1.2.48 to 1.2.49.

Sequence Diagram(s)

sequenceDiagram
    participant C as Client
    participant API as ChatApi
    participant S as Server
    C->>API: updateMessage(message, params)
    API->>S: Send update request (JSON with version, timestamp, operation)
    S-->>API: Updated message details
    API->>C: Return updated Message
Loading
sequenceDiagram
    participant C as Client
    participant API as ChatApi
    participant S as Server
    C->>API: deleteMessage(message, params)
    API->>S: Send delete request (JSON with version, timestamp, operation)
    S-->>API: Deleted message details
    API->>C: Return deleted Message
Loading

Possibly related PRs

Suggested reviewers

  • ttypic

Poem

I'm a hopping rabbit, code in stride,
Updating messages with a joyful pride.
New methods bloom like carrots fresh and bright,
In tests and flows, everything feels just right.
With every bug undone and each feature in view,
I celebrate these changes — a bunny's breakthrough! 🐰


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>, please review it.
    • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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.

@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 4, 2025 12:07 Inactive
- Updated usages across roomreactions, messages and chatAPI to use JsonObject
@sacOO7 sacOO7 force-pushed the feature/message-edit-update branch from 2883beb to 8cf8d51 Compare February 4, 2025 12:22
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 4, 2025 12:24 Inactive
1. Added separate typealias for OperationMetadata
2. Defined messages operation param data classes, UpdateMessageParams and DeleteMessageParams
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 6, 2025 12:53 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 6, 2025 13:26 Inactive
1. Updated Messages interface, added methods for message update and delete
@sacOO7 sacOO7 force-pushed the feature/message-edit-update branch from c9c1c98 to d78946f Compare February 6, 2025 13:31
@sacOO7 sacOO7 changed the title [ECO-5196] Message edit/update [ECO-5196] Message edit/delete Feb 6, 2025
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 6, 2025 13:33 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 11, 2025 06:10 Inactive
1. Added new fields version, timestamp and operation
2. Added method to decode JsonObject into Message.Operation
3. Updated/fixed tests accordingly
@sacOO7 sacOO7 force-pushed the feature/message-edit-update branch from bfade60 to d36ac65 Compare February 11, 2025 13:03
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 11, 2025 13:06 Inactive
- Added impl for updateMessage anddeleteMessage
- Added missing impl. for message update and delete
- Refactored relevant code to have support for message update and delete actions
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 12, 2025 07:45 Inactive
… tests

- Added map for messageActionToEventType, used the same for emitting
related message create, update and delete events
- Refactored SandboxTest.kt, moved all of tests under `integration` package.
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 13, 2025 12:07 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 13, 2025 13:30 Inactive
@sacOO7 sacOO7 force-pushed the feature/message-edit-update branch from 8db641b to 44cd11b Compare February 13, 2025 13:38
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 13, 2025 13:40 Inactive
@sacOO7 sacOO7 force-pushed the feature/message-edit-update branch from 44cd11b to a5bb0fc Compare February 14, 2025 09:00
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 14, 2025 09:02 Inactive
@sacOO7 sacOO7 force-pushed the feature/message-edit-update branch from a5bb0fc to 5abc0bb Compare February 14, 2025 11:15
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 14, 2025 11:17 Inactive
- Renamed message edit/delete description param to opDescription
- Updated response fields for send and update message
- Refactored tests for sending and retriving message history
- Added test for updating a sent message
- Added test for deleting a sent message
@sacOO7 sacOO7 force-pushed the feature/message-edit-update branch from 5abc0bb to b20593e Compare February 14, 2025 11:30
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 14, 2025 11:33 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/100/dokka February 14, 2025 12:47 Inactive
1. Refactored spec annotations for messages according to spec
2. Removed unnecessary send param validation not needed as per spec
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: 2

🧹 Nitpick comments (12)
chat-android/src/test/java/com/ably/chat/integration/ConnectionIntegrationTest.kt (2)

13-29: Consider enhancing test coverage and robustness.

While the basic connection flow is tested, consider these improvements:

  1. Add timeout to prevent test hanging if connection never succeeds
  2. Add verification of initial Connecting status
  3. Add cleanup in an @After method
  4. Add test cases for connection failures

Here's a suggested implementation:

+    private lateinit var chatClient: ChatClient
+
     @Test
     fun `should observe connection status`() = runTest {
-        val chatClient = sandbox.createSandboxChatClient()
+        chatClient = sandbox.createSandboxChatClient()
+        assertEquals(ConnectionStatus.Connecting, chatClient.connection.status)
         val connectionStatusChange = CompletableDeferred<ConnectionStatusChange>()
         chatClient.connection.onStatusChange {
             if (it.current == ConnectionStatus.Connected) connectionStatusChange.complete(it)
         }
         assertEquals(
             ConnectionStatusChange(
                 current = ConnectionStatus.Connected,
                 previous = ConnectionStatus.Connecting,
                 error = null,
                 retryIn = 0,
             ),
-            connectionStatusChange.await(),
+            withTimeout(5000) { connectionStatusChange.await() },
         )
     }
+
+    @After
+    fun tearDown() {
+        if (::chatClient.isInitialized) {
+            runBlocking { chatClient.close() }
+        }
+    }
+
+    @Test
+    fun `should handle connection failure`() = runTest {
+        // Add test for connection failure scenario
+    }

31-39: Add sandbox cleanup and error handling.

Consider adding cleanup and error handling to prevent resource leaks and improve test reliability.

Here's a suggested implementation:

     companion object {
         private lateinit var sandbox: Sandbox

         @JvmStatic
         @BeforeClass
         fun setUp() = runTest {
-            sandbox = Sandbox.createInstance()
+            try {
+                sandbox = Sandbox.createInstance()
+            } catch (e: Exception) {
+                throw IllegalStateException("Failed to create sandbox instance", e)
+            }
         }
+
+        @JvmStatic
+        @AfterClass
+        fun tearDown() = runTest {
+            if (::sandbox.isInitialized) {
+                sandbox.cleanup()
+            }
+        }
     }
chat-android/src/test/java/com/ably/chat/integration/RoomIntegrationTest.kt (2)

18-71: Consider adding error case validations.

The helper methods thoroughly validate successful state transitions. However, consider adding test cases for:

  • Network failures during state transitions
  • Concurrent state change operations
  • Invalid state transitions

73-95: Consider using deterministic room IDs for tests.

Using UUID.randomUUID() for room IDs could make tests non-deterministic and harder to debug. Consider using fixed test IDs or a deterministic sequence.

Example approach:

-val room1 = chatClient.rooms.get(UUID.randomUUID().toString())
+val room1 = chatClient.rooms.get("test-room-1")
-val room2 = chatClient.rooms.get(UUID.randomUUID().toString())
+val room2 = chatClient.rooms.get("test-room-2")
chat-android/src/test/java/com/ably/chat/integration/TypingIntegrationTest.kt (2)

15-34: Consider enhancing test coverage and resource cleanup.

While the basic typing indication test is well-implemented, consider the following improvements:

  1. Add cleanup in a @After block to release resources.
  2. Add test cases for typing timeout and explicit stop scenarios.
  3. Extract the timeout value to a named constant for better maintainability.

Here's a suggested implementation:

+    private companion object {
+        private const val TYPING_TIMEOUT_MS = 10_000
+    }

     @Test
     fun `should return typing indication for client`() = runTest {
         val chatClient1 = sandbox.createSandboxChatClient("client1")
         val chatClient2 = sandbox.createSandboxChatClient("client2")
         val roomId = UUID.randomUUID().toString()
-        val roomOptions = RoomOptions(typing = TypingOptions(timeoutMs = 10_000))
+        val roomOptions = RoomOptions(typing = TypingOptions(timeoutMs = TYPING_TIMEOUT_MS))
         val chatClient1Room = chatClient1.rooms.get(roomId, roomOptions)
         chatClient1Room.attach()
         val chatClient2Room = chatClient2.rooms.get(roomId, roomOptions)
         chatClient2Room.attach()

         val deferredValue = CompletableDeferred<TypingEvent>()
         chatClient2Room.typing.subscribe {
             deferredValue.complete(it)
         }
         chatClient1Room.typing.start()
         val typingEvent = deferredValue.await()
         assertEquals(setOf("client1"), typingEvent.currentlyTyping)
         assertEquals(setOf("client1"), chatClient2Room.typing.get())
+
+        // Cleanup
+        chatClient1Room.detach()
+        chatClient2Room.detach()
     }

+    @Test
+    fun `should handle typing timeout`() = runTest {
+        // Similar setup...
+        chatClient1Room.typing.start()
+        delay(TYPING_TIMEOUT_MS + 100)
+        assertTrue(chatClient2Room.typing.get().isEmpty())
+    }
+
+    @Test
+    fun `should handle explicit typing stop`() = runTest {
+        // Similar setup...
+        chatClient1Room.typing.start()
+        chatClient1Room.typing.stop()
+        assertTrue(chatClient2Room.typing.get().isEmpty())
+    }

36-44: Consider adding cleanup and error handling for sandbox.

The setup is good, but consider adding:

  1. An @AfterClass method to clean up the sandbox instance.
  2. Error handling for sandbox creation.

Here's a suggested implementation:

     companion object {
         private lateinit var sandbox: Sandbox

         @JvmStatic
         @BeforeClass
         fun setUp() = runTest {
-            sandbox = Sandbox.createInstance()
+            try {
+                sandbox = Sandbox.createInstance()
+            } catch (e: Exception) {
+                throw IllegalStateException("Failed to create sandbox instance", e)
+            }
         }
+
+        @JvmStatic
+        @AfterClass
+        fun tearDown() = runTest {
+            if (::sandbox.isInitialized) {
+                sandbox.cleanup()
+            }
+        }
     }
chat-android/src/test/java/com/ably/chat/integration/ReactionsIntegrationTest.kt (1)

16-34: Add test coverage for error cases and edge scenarios.

While the happy path is covered, consider adding tests for:

  • Reaction to non-existent messages
  • Multiple reactions
  • Invalid reaction types
  • Room detachment during reaction
chat-android/src/test/java/com/ably/chat/integration/OccupancyIntegrationTest.kt (1)

17-31: Add test coverage for multi-client scenarios.

Consider adding tests for:

  • Multiple clients joining/leaving
  • Concurrent occupancy changes
  • Client disconnection scenarios
chat-android/src/test/java/com/ably/chat/integration/PresenceIntegrationTest.kt (1)

22-30: Add test coverage for presence updates and data.

While basic presence is tested, consider adding tests for:

  • Presence updates with data
  • Multiple clients entering/leaving
  • Error cases (e.g., entering twice)
  • Connection loss scenarios
chat-android/src/main/java/com/ably/chat/Message.kt (1)

100-119: Consider adding null safety for JSON property access.

The JSON property access could be made safer using getAsString() with null checks.

-        operation.clientId = jsonObject.get("clientId").asString
+        jsonObject.get("clientId")?.let {
+            operation.clientId = it.getAsString()
+        }
chat-android/src/test/java/com/ably/chat/MessagesTest.kt (1)

252-252: Consider adding timestamp to buildDummyPubSubMessage.

While version is added to the dummy message, timestamp should also be included for consistency.

 version = "abcdefghij@1672531200000-123"
+timestamp = 1000L
chat-android/src/test/java/com/ably/chat/integration/MessagesIntegrationTest.kt (1)

65-88: Reduce code duplication in assertions.

The message field assertions are duplicated across tests. Consider extracting these into a helper method to improve maintainability.

+private fun assertMessageFields(expected: Message, actual: Message) {
+    assertEquals(expected.serial, actual.serial)
+    assertEquals(expected.clientId, actual.clientId)
+    assertEquals(expected.roomId, actual.roomId)
+    assertEquals(expected.text, actual.text)
+    assertEquals(expected.createdAt, actual.createdAt)
+    assertEquals(expected.metadata.toString(), actual.metadata.toString())
+    assertEquals(expected.headers, actual.headers)
+    assertEquals(expected.action, actual.action)
+    assertEquals(expected.version, actual.version)
+    assertEquals(expected.timestamp, actual.timestamp)
+    assertEquals(expected.operation, actual.operation)
+}

Then use it in your tests:

assertMessageFields(sentMessage, receivedMessage)

Also applies to: 116-139

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 71b20c4 and 97e05c1.

📒 Files selected for processing (21)
  • chat-android/src/main/java/com/ably/chat/ChatApi.kt (3 hunks)
  • chat-android/src/main/java/com/ably/chat/EventTypes.kt (2 hunks)
  • chat-android/src/main/java/com/ably/chat/Message.kt (3 hunks)
  • chat-android/src/main/java/com/ably/chat/Messages.kt (9 hunks)
  • chat-android/src/main/java/com/ably/chat/Metadata.kt (2 hunks)
  • chat-android/src/main/java/com/ably/chat/OperationMetadata.kt (1 hunks)
  • chat-android/src/main/java/com/ably/chat/Room.kt (0 hunks)
  • chat-android/src/main/java/com/ably/chat/RoomReactions.kt (1 hunks)
  • chat-android/src/test/java/com/ably/chat/ChatApiTest.kt (3 hunks)
  • chat-android/src/test/java/com/ably/chat/MessagesTest.kt (4 hunks)
  • chat-android/src/test/java/com/ably/chat/SandboxTest.kt (0 hunks)
  • chat-android/src/test/java/com/ably/chat/integration/ConnectionIntegrationTest.kt (1 hunks)
  • chat-android/src/test/java/com/ably/chat/integration/MessagesIntegrationTest.kt (1 hunks)
  • chat-android/src/test/java/com/ably/chat/integration/OccupancyIntegrationTest.kt (1 hunks)
  • chat-android/src/test/java/com/ably/chat/integration/PresenceIntegrationTest.kt (1 hunks)
  • chat-android/src/test/java/com/ably/chat/integration/ReactionsIntegrationTest.kt (1 hunks)
  • chat-android/src/test/java/com/ably/chat/integration/RoomIntegrationTest.kt (2 hunks)
  • chat-android/src/test/java/com/ably/chat/integration/Sandbox.kt (1 hunks)
  • chat-android/src/test/java/com/ably/chat/integration/TypingIntegrationTest.kt (1 hunks)
  • example/src/main/java/com/ably/chat/example/MainActivity.kt (1 hunks)
  • gradle/libs.versions.toml (1 hunks)
💤 Files with no reviewable changes (2)
  • chat-android/src/main/java/com/ably/chat/Room.kt
  • chat-android/src/test/java/com/ably/chat/SandboxTest.kt
✅ Files skipped from review due to trivial changes (2)
  • gradle/libs.versions.toml
  • chat-android/src/test/java/com/ably/chat/integration/Sandbox.kt
🧰 Additional context used
🧠 Learnings (4)
chat-android/src/test/java/com/ably/chat/integration/ReactionsIntegrationTest.kt (1)
Learnt from: sacOO7
PR: ably/ably-chat-kotlin#66
File: chat-android/src/test/java/com/ably/chat/RoomReactionsTest.kt:44-50
Timestamp: 2024-11-28T11:08:42.524Z
Learning: The test cases for verifying behavior when the room is not in the ATTACHED state are covered in `chat-android/src/test/java/com/ably/chat/room/RoomEnsureAttachedTest.kt`.
chat-android/src/test/java/com/ably/chat/integration/OccupancyIntegrationTest.kt (2)
Learnt from: sacOO7
PR: ably/ably-chat-kotlin#66
File: chat-android/src/test/java/com/ably/chat/OccupancyTest.kt:20-31
Timestamp: 2024-11-28T11:12:06.843Z
Learning: In `OccupancyTest.kt`, additional room state initialization using `setState` is unnecessary for testing occupancy functionality, as the specification doesn't require it.
Learnt from: sacOO7
PR: ably/ably-chat-kotlin#66
File: chat-android/src/main/java/com/ably/chat/Occupancy.kt:145-145
Timestamp: 2024-11-28T11:11:20.423Z
Learning: In `chat-android/src/main/java/com/ably/chat/Occupancy.kt`, within the `DefaultOccupancy` class, when methods use `room.chatApi`, which utilizes the REST API, there's no need to call `room.ensureAttached()` before performing the operation.
chat-android/src/test/java/com/ably/chat/integration/PresenceIntegrationTest.kt (1)
Learnt from: sacOO7
PR: ably/ably-chat-kotlin#66
File: chat-android/src/test/java/com/ably/chat/PresenceTest.kt:33-33
Timestamp: 2024-11-28T11:08:38.559Z
Learning: The `RoomEnsureAttachedTest.kt` file contains tests that verify room operations are only performed when the room is in the `ATTACHED` state, including scenarios where operations fail when the room is not attached, succeed when it is attached, and proper error handling for invalid room states.
chat-android/src/test/java/com/ably/chat/integration/RoomIntegrationTest.kt (1)
Learnt from: sacOO7
PR: ably/ably-chat-kotlin#66
File: chat-android/src/test/java/com/ably/chat/RoomReactionsTest.kt:44-50
Timestamp: 2024-11-28T11:08:42.524Z
Learning: The test cases for verifying behavior when the room is not in the ATTACHED state are covered in `chat-android/src/test/java/com/ably/chat/room/RoomEnsureAttachedTest.kt`.
🔇 Additional comments (35)
chat-android/src/test/java/com/ably/chat/integration/ConnectionIntegrationTest.kt (1)

1-10: LGTM! Well-organized imports.

The imports are clean and appropriate for the test requirements.

chat-android/src/test/java/com/ably/chat/integration/RoomIntegrationTest.kt (2)

1-1: LGTM! Package organization aligns with test purpose.

The move to the integration package better reflects the integration test nature of this class, and the new imports support the lifecycle management functionality.

Also applies to: 8-9


97-105: Verify test isolation with shared sandbox.

Moving sandbox to a companion object with @BeforeClass means it's shared across all test methods. This could lead to state leakage between tests. Consider:

  1. Using @Before instead to create a fresh sandbox for each test
  2. Adding explicit cleanup in @After or @AfterClass
  3. Documenting why sharing the sandbox is safe
chat-android/src/test/java/com/ably/chat/integration/TypingIntegrationTest.kt (1)

1-13: LGTM! Well-organized imports and clear class structure.

The imports are specific and necessary for the test implementation, showing good organization.

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

38-53: Consider null handling for the "operation" field.

Using getAsJsonObject("operation") may throw if the field is absent or not a valid JSON object. If partial data is possible, consider a safer approach or clarify via documentation that the field's absence is invalid.


60-86: Initialization of version and timestamp looks consistent.

Assigning version = serial and timestamp = createdAt for newly sent messages aligns with the system’s creation flow. No further issues identified here.


89-117: Revisit setting clientId = clientId when updating the message.

While ensuring the local client is the one performing the update, overwriting the original message’s clientId might risk confusion if the updating user differs from the original sender. Confirm that this behavior is desired.


119-147: Delete flow is coherent and consistent.

Soft-delete semantics, building a new Message with MESSAGE_DELETE action, versioning, and timestamp are logically sound. No additional concerns.


158-158: Empty response error handling is consistent with other endpoints.

Throwing a serverError on an empty occupancy response matches prior patterns for consistency.

chat-android/src/main/java/com/ably/chat/Messages.kt (15)

63-63: Documentation annotation looks fine.
No material change or issue identified.


73-88: Well-documented update method.
The explanatory comment clarifies usage and behavior thoroughly.


89-97: Method signature for update is consistent with the new API.
No issues found.


98-117: Clear and concise delete method documentation.
Describes soft delete behavior thoroughly.


222-228: SendMessageParams.toJsonObject() is straightforward and readable.
Implementation follows established patterns.


230-255: UpdateMessageParams and conversion to JSON appear correct.
Captures text, headers, and optional description/metadata accurately.


259-275: DeleteMessageParams logic is clear.
Allows flexible fields for the delete action.


367-368: Event mapping logic is clear.
Throws an error for unknown actions, preventing silent failures.


378-383: Inclusion of new fields in Message is consistent.
version, timestamp, and operation align with the rest of the update/delete flow.


387-387: Subscription with CHAT_MESSAGE is aligned with new naming.
No observed hazards.


399-399: Unsubscription logic updated to match new event name.
No issues identified.


413-418: Send method delegates to ChatApi appropriately.
Implementation is concise and consistent.


419-426: Validation: Ensure overwritten clientId is correct.

As in ChatApi.updateMessage, confirm that referencing the local clientId is intended rather than preserving the original author’s.


435-442: Delete method usage matches the ChatApi.
Implementation is straightforward, no further issues.


472-472: Metadata extraction remains consistent with existing logic.
No concerns about handling this optional field.

chat-android/src/main/java/com/ably/chat/OperationMetadata.kt (1)

1-11: Introduction of OperationMetadata is well-scoped.
Using a typealias for string-based metadata clarifies usage.

chat-android/src/main/java/com/ably/chat/Metadata.kt (1)

3-3: LGTM! Type alias change improves type safety.

The change from JsonElement to JsonObject ensures metadata is always a structured object, which is more appropriate for message operations.

Also applies to: 18-18

chat-android/src/test/java/com/ably/chat/integration/PresenceIntegrationTest.kt (1)

13-19: LGTM! Empty presence test is well structured.

The test correctly verifies initial empty presence state.

chat-android/src/main/java/com/ably/chat/EventTypes.kt (2)

22-24: LGTM! Improved naming conventions.

The renaming of PubSubMessageNames to PubSubEventName and ChatMessage to CHAT_MESSAGE follows Kotlin naming conventions for constants.


45-49: LGTM! Well-structured mapping for message actions.

The internal mapping provides a type-safe way to convert between MessageAction and MessageEventType, which is essential for the new message editing/deletion functionality.

chat-android/src/main/java/com/ably/chat/Message.kt (1)

82-97: LGTM! Well-documented message versioning properties.

The new properties (version, timestamp, operation) are well-documented and properly aligned with the specs. The nullable operation with default null is appropriate as it's only needed for update/delete actions.

chat-android/src/test/java/com/ably/chat/ChatApiTest.kt (2)

36-37: LGTM! Comprehensive test coverage for new properties.

The test cases properly validate the new version and timestamp properties in the message response.

Also applies to: 55-56


109-112: Consider adding test cases for operation property.

While version and timestamp are tested, there are no test cases for the new operation property during message updates/deletes.

Would you like me to help generate additional test cases for the operation property?

chat-android/src/test/java/com/ably/chat/MessagesTest.kt (1)

79-80: LGTM! Consistent test coverage across test classes.

The test assertions for version and timestamp are consistent with ChatApiTest.kt and use realistic values.

Also applies to: 142-143

example/src/main/java/com/ably/chat/example/MainActivity.kt (1)

324-325: LGTM!

The new properties version and timestamp are correctly added to the Message object in the preview function, with appropriate values for testing purposes.

chat-android/src/test/java/com/ably/chat/integration/MessagesIntegrationTest.kt (1)

144-198: Add edge case tests for message updates.

The update test only covers the happy path. Consider adding tests for:

  • Updating a non-existent message
  • Updating a deleted message
  • Concurrent updates to the same message

@sacOO7
Copy link
Contributor Author

sacOO7 commented Feb 14, 2025

@coderabbitai resolve

Copy link

coderabbitai bot commented Feb 14, 2025

✅ Actions performed

Comments resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

[Messages] message delete feature [Messages] message edit/update feature
1 participant