Skip to content

Commit

Permalink
feat: add message history (#278)
Browse files Browse the repository at this point in the history
* feat: add message history

* fix: check length of map instead of nil equality
  • Loading branch information
shaljam authored May 24, 2024
1 parent 7307355 commit 3104c7e
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 0 deletions.
68 changes: 68 additions & 0 deletions message_history.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package stream_chat

import (
"context"
"encoding/json"
"errors"
"net/http"
"time"
)

type QueryMessageHistoryRequest struct {
Filter map[string]any `json:"filter"`
Sort []*SortOption `json:"sort,omitempty"`

Limit int `json:"limit,omitempty"`
Next string `json:"next,omitempty"`
Prev string `json:"prev,omitempty"`
}

type MessageHistoryEntry struct {
MessageID string `json:"message_id"`
MessageUpdatedByID string `json:"message_updated_by_id"`
MessageUpdatedAt time.Time `json:"message_updated_at"`

Text string `json:"text"`
Attachments []*Attachment `json:"attachments"`
ExtraData map[string]interface{} `json:"-"`
}

var _ json.Unmarshaler = (*MessageHistoryEntry)(nil)
var _ json.Marshaler = (*MessageHistoryEntry)(nil)

type messageHistoryJson MessageHistoryEntry

func (m *MessageHistoryEntry) UnmarshalJSON(data []byte) error {
var m2 messageHistoryJson
if err := json.Unmarshal(data, &m2); err != nil {
return err
}
*m = MessageHistoryEntry(m2)

if err := json.Unmarshal(data, &m.ExtraData); err != nil {
return err
}
removeFromMap(m.ExtraData, *m)
return nil
}

func (m MessageHistoryEntry) MarshalJSON() ([]byte, error) {
return addToMapAndMarshal(m.ExtraData, messageHistoryJson(m))
}

type QueryMessageHistoryResponse struct {
MessageHistory []*MessageHistoryEntry `json:"message_history"`

Next *string `json:"next,omitempty"`
Prev *string `json:"prev,omitempty"`
Response
}

func (c *Client) QueryMessageHistory(ctx context.Context, request QueryMessageHistoryRequest) (*QueryMessageHistoryResponse, error) {
if len(request.Filter) == 0 {
return nil, errors.New("you need specify one filter at least")
}
var resp QueryMessageHistoryResponse
err := c.makeRequest(ctx, http.MethodPost, "messages/history", nil, request, &resp)
return &resp, err
}
90 changes: 90 additions & 0 deletions message_history_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package stream_chat

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestMessageHistory(t *testing.T) {
client := initClient(t)
users := randomUsers(t, client, 2)
user1 := users[0]
user2 := users[1]

ch := initChannel(t, client, user1.ID)

ctx := context.Background()
initialText := "initial text"
customField := "custom_field"
initialCustomFieldValue := "custom value"
// send a message with initial text
response, err := ch.SendMessage(ctx, &Message{Text: initialText, ExtraData: map[string]interface{}{customField: initialCustomFieldValue}}, user1.ID)
require.NoError(t, err)
message := response.Message

updatedText1 := "updated text"
updatedCustomFieldValue := "updated custom value"
// update the message by user1
_, err = client.UpdateMessage(ctx, &Message{Text: updatedText1, ExtraData: map[string]interface{}{customField: updatedCustomFieldValue}, UserID: user1.ID}, message.ID)
assert.NoError(t, err)

updatedText2 := "updated text 2"
// update the message by user2
_, err = client.UpdateMessage(ctx, &Message{Text: updatedText2, UserID: user2.ID}, message.ID)
assert.NoError(t, err)

t.Run("test query", func(t *testing.T) {
req := QueryMessageHistoryRequest{
Filter: map[string]interface{}{
"message_id": message.ID,
},
}
messageHistoryResponse, err := client.QueryMessageHistory(ctx, req)
assert.NoError(t, err)
assert.NotNil(t, messageHistoryResponse)

history := messageHistoryResponse.MessageHistory
assert.Equal(t, 2, len(history))

firstUpdate := history[1]
assert.Equal(t, initialText, firstUpdate.Text)
assert.Equal(t, user1.ID, firstUpdate.MessageUpdatedByID)
assert.Equal(t, initialCustomFieldValue, firstUpdate.ExtraData[customField].(string))

secondUpdate := history[0]
assert.Equal(t, updatedText1, secondUpdate.Text)
assert.Equal(t, user2.ID, secondUpdate.MessageUpdatedByID)
assert.Equal(t, updatedCustomFieldValue, secondUpdate.ExtraData[customField].(string))
})

t.Run("test sorting", func(t *testing.T) {
sortedHistoryQueryRequest := QueryMessageHistoryRequest{
Filter: map[string]interface{}{
"message_id": message.ID,
},
Sort: []*SortOption{
{
Field: "message_updated_at",
Direction: 1,
},
},
}
sortedHistoryResponse, err := client.QueryMessageHistory(ctx, sortedHistoryQueryRequest)
assert.NoError(t, err)
assert.NotNil(t, sortedHistoryResponse)

sortedHistory := sortedHistoryResponse.MessageHistory
assert.Equal(t, 2, len(sortedHistory))

firstUpdate := sortedHistory[0]
assert.Equal(t, initialText, firstUpdate.Text)
assert.Equal(t, user1.ID, firstUpdate.MessageUpdatedByID)

secondUpdate := sortedHistory[1]
assert.Equal(t, updatedText1, secondUpdate.Text)
assert.Equal(t, user2.ID, secondUpdate.MessageUpdatedByID)
})
}

0 comments on commit 3104c7e

Please sign in to comment.