Skip to content

Commit b446205

Browse files
feat: add support for unread counts endpoints (#265)
* 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
1 parent 4d0ec56 commit b446205

File tree

3 files changed

+167
-1
lines changed

3 files changed

+167
-1
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
strategy:
1717
max-parallel: 1
1818
matrix:
19-
goVer: ['1.17', '1.18']
19+
goVer: ['1.17', '1.18', '1.19', '1.20', '1.21', '1.22']
2020
steps:
2121
- uses: actions/checkout@v3
2222

unread_counts.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package stream_chat
2+
3+
import (
4+
"context"
5+
"net/http"
6+
"net/url"
7+
"time"
8+
)
9+
10+
type UnreadCountsChannel struct {
11+
ChannelID string `json:"channel_id"`
12+
UnreadCount int `json:"unread_count"`
13+
LastRead time.Time `json:"last_read"`
14+
}
15+
16+
type UnreadCountsChannelType struct {
17+
ChannelType string `json:"channel_type"`
18+
ChannelCount int `json:"channel_count"`
19+
UnreadCount int `json:"unread_count"`
20+
}
21+
22+
type UnreadCountsThread struct {
23+
UnreadCount int `json:"unread_count"`
24+
LastRead time.Time `json:"last_read"`
25+
LastReadMessageID string `json:"last_read_message_id"`
26+
ParentMessageID string `json:"parent_message_id"`
27+
}
28+
29+
type UnreadCountsResponse struct {
30+
TotalUnreadCount int `json:"total_unread_count"`
31+
TotalUnreadThreadsCount int `json:"total_unread_threads_count"`
32+
Channels []UnreadCountsChannel `json:"channels"`
33+
ChannelType []UnreadCountsChannelType `json:"channel_type"`
34+
Threads []UnreadCountsThread `json:"threads"`
35+
Response
36+
}
37+
38+
func (c *Client) UnreadCounts(ctx context.Context, userID string) (*UnreadCountsResponse, error) {
39+
var resp UnreadCountsResponse
40+
err := c.makeRequest(ctx, http.MethodGet, "unread", url.Values{"user_id": []string{userID}}, nil, &resp)
41+
return &resp, err
42+
}
43+
44+
type UnreadCountsBatchResponse struct {
45+
CountsByUser map[string]*UnreadCountsResponse `json:"counts_by_user"`
46+
Response
47+
}
48+
49+
func (c *Client) UnreadCountsBatch(ctx context.Context, userIDs []string) (*UnreadCountsBatchResponse, error) {
50+
var resp UnreadCountsBatchResponse
51+
err := c.makeRequest(ctx, http.MethodPost, "unread_batch", nil, map[string][]string{"user_ids": userIDs}, &resp)
52+
return &resp, err
53+
}

unread_counts_test.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package stream_chat
2+
3+
import (
4+
"context"
5+
"strings"
6+
"testing"
7+
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestUnreadCounts(t *testing.T) {
12+
c := initClient(t)
13+
user := randomUser(t, c)
14+
ch := initChannel(t, c, user.ID)
15+
16+
ctx := context.Background()
17+
msg := &Message{Text: "test message"}
18+
randSender := randomString(5)
19+
var messageID string
20+
for i := 0; i < 5; i++ {
21+
resp, err := ch.SendMessage(ctx, msg, randSender)
22+
require.NoError(t, err)
23+
messageID = resp.Message.ID
24+
}
25+
26+
resp, err := c.UnreadCounts(ctx, user.ID)
27+
require.NoError(t, err)
28+
require.Equal(t, 5, resp.TotalUnreadCount)
29+
require.Equal(t, 1, len(resp.Channels))
30+
require.Equal(t, ch.CID, resp.Channels[0].ChannelID)
31+
require.Equal(t, 5, resp.Channels[0].UnreadCount)
32+
require.Equal(t, 1, len(resp.ChannelType))
33+
require.Equal(t, strings.Split(ch.CID, ":")[0], resp.ChannelType[0].ChannelType)
34+
require.Equal(t, 5, resp.ChannelType[0].UnreadCount)
35+
36+
// test unread threads
37+
threadMsg := &Message{Text: "test thread", ParentID: messageID}
38+
_, err = ch.SendMessage(ctx, threadMsg, user.ID)
39+
require.NoError(t, err)
40+
_, err = ch.SendMessage(ctx, threadMsg, randSender)
41+
require.NoError(t, err)
42+
43+
resp, err = c.UnreadCounts(ctx, user.ID)
44+
require.NoError(t, err)
45+
require.Equal(t, 1, resp.TotalUnreadThreadsCount)
46+
require.Equal(t, 1, len(resp.Threads))
47+
require.Equal(t, messageID, resp.Threads[0].ParentMessageID)
48+
}
49+
50+
func TestUnreadCountsBatch(t *testing.T) {
51+
c := initClient(t)
52+
user1 := randomUser(t, c)
53+
user2 := randomUser(t, c)
54+
ch := initChannel(t, c, user1.ID, user2.ID)
55+
56+
ctx := context.Background()
57+
msg := &Message{Text: "test message"}
58+
randSender := randomString(5)
59+
var messageID string
60+
for i := 0; i < 5; i++ {
61+
resp, err := ch.SendMessage(ctx, msg, randSender)
62+
require.NoError(t, err)
63+
messageID = resp.Message.ID
64+
}
65+
66+
nonexistant := randomString(5)
67+
resp, err := c.UnreadCountsBatch(ctx, []string{user1.ID, user2.ID, nonexistant})
68+
require.NoError(t, err)
69+
require.Equal(t, 2, len(resp.CountsByUser))
70+
require.Contains(t, resp.CountsByUser, user1.ID)
71+
require.Contains(t, resp.CountsByUser, user2.ID)
72+
require.NotContains(t, resp.CountsByUser, nonexistant)
73+
74+
// user 1 counts
75+
require.Equal(t, 5, resp.CountsByUser[user1.ID].TotalUnreadCount)
76+
require.Equal(t, 1, len(resp.CountsByUser[user1.ID].Channels))
77+
require.Equal(t, ch.CID, resp.CountsByUser[user1.ID].Channels[0].ChannelID)
78+
require.Equal(t, 5, resp.CountsByUser[user1.ID].Channels[0].UnreadCount)
79+
require.Equal(t, 1, len(resp.CountsByUser[user1.ID].ChannelType))
80+
require.Equal(t, strings.Split(ch.CID, ":")[0], resp.CountsByUser[user1.ID].ChannelType[0].ChannelType)
81+
require.Equal(t, 5, resp.CountsByUser[user1.ID].ChannelType[0].UnreadCount)
82+
83+
// user 2 counts
84+
require.Equal(t, 5, resp.CountsByUser[user2.ID].TotalUnreadCount)
85+
require.Equal(t, 1, len(resp.CountsByUser[user2.ID].Channels))
86+
require.Equal(t, ch.CID, resp.CountsByUser[user2.ID].Channels[0].ChannelID)
87+
require.Equal(t, 5, resp.CountsByUser[user2.ID].Channels[0].UnreadCount)
88+
require.Equal(t, 1, len(resp.CountsByUser[user2.ID].ChannelType))
89+
require.Equal(t, strings.Split(ch.CID, ":")[0], resp.CountsByUser[user2.ID].ChannelType[0].ChannelType)
90+
require.Equal(t, 5, resp.CountsByUser[user2.ID].ChannelType[0].UnreadCount)
91+
92+
// test unread threads
93+
threadMsg := &Message{Text: "test thread", ParentID: messageID}
94+
_, err = ch.SendMessage(ctx, threadMsg, user1.ID)
95+
require.NoError(t, err)
96+
_, err = ch.SendMessage(ctx, threadMsg, user2.ID)
97+
require.NoError(t, err)
98+
_, err = ch.SendMessage(ctx, threadMsg, randSender)
99+
require.NoError(t, err)
100+
101+
resp, err = c.UnreadCountsBatch(ctx, []string{user1.ID, user2.ID, nonexistant})
102+
require.NoError(t, err)
103+
104+
// user 1 thread counts
105+
require.Equal(t, 1, resp.CountsByUser[user1.ID].TotalUnreadThreadsCount)
106+
require.Equal(t, 1, len(resp.CountsByUser[user1.ID].Threads))
107+
require.Equal(t, messageID, resp.CountsByUser[user1.ID].Threads[0].ParentMessageID)
108+
109+
// user 2 thread counts
110+
require.Equal(t, 1, resp.CountsByUser[user2.ID].TotalUnreadThreadsCount)
111+
require.Equal(t, 1, len(resp.CountsByUser[user2.ID].Threads))
112+
require.Equal(t, messageID, resp.CountsByUser[user2.ID].Threads[0].ParentMessageID)
113+
}

0 commit comments

Comments
 (0)