Skip to content

Commit

Permalink
feat: add support for unread counts endpoints (#265)
Browse files Browse the repository at this point in the history
* feat: add support for unread counts endpoints

* chore: skip batch test for now

* chore: add support for newer go versions

* chore: enable batch test

* fix: check that nonexistant user is not part of response

* fix: add tests for unread threads

* chore: add support for 1.22
  • Loading branch information
JimmyPettersson85 committed Feb 27, 2024
1 parent 4d0ec56 commit b446205
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
max-parallel: 1
matrix:
goVer: ['1.17', '1.18']
goVer: ['1.17', '1.18', '1.19', '1.20', '1.21', '1.22']
steps:
- uses: actions/checkout@v3

Expand Down
53 changes: 53 additions & 0 deletions unread_counts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package stream_chat

import (
"context"
"net/http"
"net/url"
"time"
)

type UnreadCountsChannel struct {
ChannelID string `json:"channel_id"`
UnreadCount int `json:"unread_count"`
LastRead time.Time `json:"last_read"`
}

type UnreadCountsChannelType struct {
ChannelType string `json:"channel_type"`
ChannelCount int `json:"channel_count"`
UnreadCount int `json:"unread_count"`
}

type UnreadCountsThread struct {
UnreadCount int `json:"unread_count"`
LastRead time.Time `json:"last_read"`
LastReadMessageID string `json:"last_read_message_id"`
ParentMessageID string `json:"parent_message_id"`
}

type UnreadCountsResponse struct {
TotalUnreadCount int `json:"total_unread_count"`
TotalUnreadThreadsCount int `json:"total_unread_threads_count"`
Channels []UnreadCountsChannel `json:"channels"`
ChannelType []UnreadCountsChannelType `json:"channel_type"`
Threads []UnreadCountsThread `json:"threads"`
Response
}

func (c *Client) UnreadCounts(ctx context.Context, userID string) (*UnreadCountsResponse, error) {
var resp UnreadCountsResponse
err := c.makeRequest(ctx, http.MethodGet, "unread", url.Values{"user_id": []string{userID}}, nil, &resp)
return &resp, err
}

type UnreadCountsBatchResponse struct {
CountsByUser map[string]*UnreadCountsResponse `json:"counts_by_user"`
Response
}

func (c *Client) UnreadCountsBatch(ctx context.Context, userIDs []string) (*UnreadCountsBatchResponse, error) {
var resp UnreadCountsBatchResponse
err := c.makeRequest(ctx, http.MethodPost, "unread_batch", nil, map[string][]string{"user_ids": userIDs}, &resp)
return &resp, err
}
113 changes: 113 additions & 0 deletions unread_counts_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package stream_chat

import (
"context"
"strings"
"testing"

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

func TestUnreadCounts(t *testing.T) {
c := initClient(t)
user := randomUser(t, c)
ch := initChannel(t, c, user.ID)

ctx := context.Background()
msg := &Message{Text: "test message"}
randSender := randomString(5)
var messageID string
for i := 0; i < 5; i++ {
resp, err := ch.SendMessage(ctx, msg, randSender)
require.NoError(t, err)
messageID = resp.Message.ID
}

resp, err := c.UnreadCounts(ctx, user.ID)
require.NoError(t, err)
require.Equal(t, 5, resp.TotalUnreadCount)
require.Equal(t, 1, len(resp.Channels))
require.Equal(t, ch.CID, resp.Channels[0].ChannelID)
require.Equal(t, 5, resp.Channels[0].UnreadCount)
require.Equal(t, 1, len(resp.ChannelType))
require.Equal(t, strings.Split(ch.CID, ":")[0], resp.ChannelType[0].ChannelType)
require.Equal(t, 5, resp.ChannelType[0].UnreadCount)

// test unread threads
threadMsg := &Message{Text: "test thread", ParentID: messageID}
_, err = ch.SendMessage(ctx, threadMsg, user.ID)
require.NoError(t, err)
_, err = ch.SendMessage(ctx, threadMsg, randSender)
require.NoError(t, err)

resp, err = c.UnreadCounts(ctx, user.ID)
require.NoError(t, err)
require.Equal(t, 1, resp.TotalUnreadThreadsCount)
require.Equal(t, 1, len(resp.Threads))
require.Equal(t, messageID, resp.Threads[0].ParentMessageID)
}

func TestUnreadCountsBatch(t *testing.T) {
c := initClient(t)
user1 := randomUser(t, c)
user2 := randomUser(t, c)
ch := initChannel(t, c, user1.ID, user2.ID)

ctx := context.Background()
msg := &Message{Text: "test message"}
randSender := randomString(5)
var messageID string
for i := 0; i < 5; i++ {
resp, err := ch.SendMessage(ctx, msg, randSender)
require.NoError(t, err)
messageID = resp.Message.ID
}

nonexistant := randomString(5)
resp, err := c.UnreadCountsBatch(ctx, []string{user1.ID, user2.ID, nonexistant})
require.NoError(t, err)
require.Equal(t, 2, len(resp.CountsByUser))
require.Contains(t, resp.CountsByUser, user1.ID)
require.Contains(t, resp.CountsByUser, user2.ID)
require.NotContains(t, resp.CountsByUser, nonexistant)

// user 1 counts
require.Equal(t, 5, resp.CountsByUser[user1.ID].TotalUnreadCount)
require.Equal(t, 1, len(resp.CountsByUser[user1.ID].Channels))
require.Equal(t, ch.CID, resp.CountsByUser[user1.ID].Channels[0].ChannelID)
require.Equal(t, 5, resp.CountsByUser[user1.ID].Channels[0].UnreadCount)
require.Equal(t, 1, len(resp.CountsByUser[user1.ID].ChannelType))
require.Equal(t, strings.Split(ch.CID, ":")[0], resp.CountsByUser[user1.ID].ChannelType[0].ChannelType)
require.Equal(t, 5, resp.CountsByUser[user1.ID].ChannelType[0].UnreadCount)

// user 2 counts
require.Equal(t, 5, resp.CountsByUser[user2.ID].TotalUnreadCount)
require.Equal(t, 1, len(resp.CountsByUser[user2.ID].Channels))
require.Equal(t, ch.CID, resp.CountsByUser[user2.ID].Channels[0].ChannelID)
require.Equal(t, 5, resp.CountsByUser[user2.ID].Channels[0].UnreadCount)
require.Equal(t, 1, len(resp.CountsByUser[user2.ID].ChannelType))
require.Equal(t, strings.Split(ch.CID, ":")[0], resp.CountsByUser[user2.ID].ChannelType[0].ChannelType)
require.Equal(t, 5, resp.CountsByUser[user2.ID].ChannelType[0].UnreadCount)

// test unread threads
threadMsg := &Message{Text: "test thread", ParentID: messageID}
_, err = ch.SendMessage(ctx, threadMsg, user1.ID)
require.NoError(t, err)
_, err = ch.SendMessage(ctx, threadMsg, user2.ID)
require.NoError(t, err)
_, err = ch.SendMessage(ctx, threadMsg, randSender)
require.NoError(t, err)

resp, err = c.UnreadCountsBatch(ctx, []string{user1.ID, user2.ID, nonexistant})
require.NoError(t, err)

// user 1 thread counts
require.Equal(t, 1, resp.CountsByUser[user1.ID].TotalUnreadThreadsCount)
require.Equal(t, 1, len(resp.CountsByUser[user1.ID].Threads))
require.Equal(t, messageID, resp.CountsByUser[user1.ID].Threads[0].ParentMessageID)

// user 2 thread counts
require.Equal(t, 1, resp.CountsByUser[user2.ID].TotalUnreadThreadsCount)
require.Equal(t, 1, len(resp.CountsByUser[user2.ID].Threads))
require.Equal(t, messageID, resp.CountsByUser[user2.ID].Threads[0].ParentMessageID)
}

0 comments on commit b446205

Please sign in to comment.