Skip to content

Commit

Permalink
Adds Update personal message flags for narrow
Browse files Browse the repository at this point in the history
  • Loading branch information
wakumaku committed Jan 27, 2025
1 parent 836037e commit 49432ac
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ Check [/examples](examples) folder.
* Check if messages match a narrow
* Get a message's edit history
* [x] Update personal message flags
* Update personal message flags for narrow
* [x] Update personal message flags for narrow
* [x] Get a message's read receipts
* **Scheduled messages**
* Get scheduled messages
Expand Down
98 changes: 98 additions & 0 deletions messages/update_personal_message_flags_narrow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package messages

import (
"context"
"encoding/json"
"net/http"

"github.com/wakumaku/go-zulip"
"github.com/wakumaku/go-zulip/narrow"
)

type UpdatePersonalMessageFlagsNarrow struct {
zulip.APIResponseBase
updatePersonalMessageFlagsNarrowData
}

type updatePersonalMessageFlagsNarrowData struct {
ProcessedCount int `json:"processed_count"`
UpdatedCount int `json:"updated_count"`
FirstProcessedID int `json:"first_processed_id"`
LastProcessedID int `json:"last_processed_id"`
FoundOldest bool `json:"found_oldest"`
FoundNewest bool `json:"found_newest"`
}

func (g *UpdatePersonalMessageFlagsNarrow) UnmarshalJSON(b []byte) error {
if err := json.Unmarshal(b, &g.APIResponseBase); err != nil {
return err
}

if err := json.Unmarshal(b, &g.updatePersonalMessageFlagsNarrowData); err != nil {
return err
}

return nil
}

type updatePersonalMessageFlagsNarrowOptions struct {
IncludeAnchor struct {
fieldName string
value bool
}
}

type UpdatePersonalMessageFlagsNarrowOption func(*updatePersonalMessageFlagsNarrowOptions)

func UpdatePersonalMessageFlagsNarrowIncludeAnchor() UpdatePersonalMessageFlagsNarrowOption {
return func(o *updatePersonalMessageFlagsNarrowOptions) {
o.IncludeAnchor.fieldName = "include_anchor"
o.IncludeAnchor.value = true
}
}

func (svc *Service) UpdatePersonalMessageFlagsNarrow(
ctx context.Context,
anchor string,
numBefore int,
numAfter int,
narrow narrow.Filter,
op Operation,
flag Flag,
opts ...UpdatePersonalMessageFlagsNarrowOption,
) (*UpdatePersonalMessageFlagsNarrow, error) {
const (
method = http.MethodPost
path = "/api/v1/messages/flags/narrow"
)

narrowJSON, err := json.Marshal(narrow)
if err != nil {
return nil, err
}

msg := map[string]any{
"anchor": anchor,
"num_before": numBefore,
"num_after": numAfter,
"narrow": string(narrowJSON),
"op": op,
"flag": flag,
}

options := updatePersonalMessageFlagsNarrowOptions{}
for _, opt := range opts {
opt(&options)
}

if options.IncludeAnchor.value {
msg[options.IncludeAnchor.fieldName] = options.IncludeAnchor.value
}

resp := UpdatePersonalMessageFlagsNarrow{}
if err := svc.client.DoRequest(ctx, method, path, msg, &resp); err != nil {
return nil, err
}

return &resp, nil
}
55 changes: 55 additions & 0 deletions messages/update_personal_message_flags_narrow_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package messages_test

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"github.com/wakumaku/go-zulip/messages"
"github.com/wakumaku/go-zulip/narrow"
)

func TestUpdatePersonalMessageFlagsNarrow(t *testing.T) {
client := createMockClient(`{
"first_processed_id": 35,
"found_newest": true,
"found_oldest": false,
"last_processed_id": 55,
"msg": "",
"processed_count": 11,
"result": "success",
"updated_count": 8
}`)

msgSvc := messages.NewService(client)

resp, err := msgSvc.UpdatePersonalMessageFlagsNarrow(
context.Background(),
"anchor",
10,
10,
narrow.NewFilter().Add(narrow.New(narrow.Channel, "Denmark")),
messages.OperationAdd,
messages.FlagRead,
messages.UpdatePersonalMessageFlagsNarrowIncludeAnchor(),
)
assert.NoError(t, err)
assert.Equal(t, 35, resp.FirstProcessedID)
assert.Equal(t, 55, resp.LastProcessedID)
assert.Equal(t, 11, resp.ProcessedCount)
assert.Equal(t, 8, resp.UpdatedCount)
assert.True(t, resp.FoundNewest)
assert.False(t, resp.FoundOldest)

// validate payload
expedtedParams := map[string]interface{}{
"anchor": "anchor",
"num_before": 10,
"num_after": 10,
"narrow": `[{"operator":"channel","operand":"Denmark","negated":false}]`,
"op": messages.OperationAdd,
"flag": messages.FlagRead,
"include_anchor": true,
}
assert.Equal(t, expedtedParams, client.(*mockClient).paramsSent)
}
20 changes: 20 additions & 0 deletions test/integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,26 @@ func TestIntegrationSuite(t *testing.T) {
assert.GreaterOrEqual(t, len(respGetMessageReceipts.UserIDs), 1) // one read receipt
assert.Contains(t, respGetMessageReceipts.UserIDs, userAID) // User A has read the message

// Admin marks the message as read but applying a narrow
markAsReadNarrow := narrow.NewFilter().
Add(narrow.New(narrow.Id, respCreatePrivateChat.ID)). // the message ID
Add(narrow.New(narrow.Operator("is"), narrow.Operand("private"))). // private messages
Add(narrow.New(narrow.DmIncluding, narrow.Operand(userAID))) // including User A in the conversation

respMarkAsReadNarrow, err := adminMsgSvc.UpdatePersonalMessageFlagsNarrow(ctx, "newest", 1, 1,
markAsReadNarrow, messages.OperationAdd, messages.FlagRead)
assert.NoError(t, err)
assert.Equal(t, respMarkAsReadNarrow.HTTPCode(), http.StatusOK)
assert.Equal(t, respMarkAsReadNarrow.Result(), zulip.ResultSuccess)

// User B gets the receipts again and should find Admin's ID
respGetMessageReceipts, err = userBMsgSvc.GetMessagesReadReceipts(ctx, respCreatePrivateChat.ID)
assert.NoError(t, err)
assert.Equal(t, respGetMessageReceipts.HTTPCode(), http.StatusOK)
assert.Equal(t, respGetMessageReceipts.Result(), zulip.ResultSuccess)
assert.GreaterOrEqual(t, len(respGetMessageReceipts.UserIDs), 2) // two read receipts
assert.Contains(t, respGetMessageReceipts.UserIDs, userAID) // User A has read the message

// UserA gets its own information
userAUserSvc := users.NewService(userA)
respGetUserMe, err := userAUserSvc.GetUserMe(ctx)
Expand Down

0 comments on commit 49432ac

Please sign in to comment.