From 35b4ba9a929d72340b5cb8195f5ffcc0a4d22270 Mon Sep 17 00:00:00 2001 From: Antti Kupila Date: Tue, 10 Sep 2024 10:22:35 +0300 Subject: [PATCH] feat: add support for querying deactivated users --- query.go | 30 +++++++++++++++++++----------- query_test.go | 39 ++++++++++++++++++++++++++++++--------- user_test.go | 50 ++++++++++++++++++++++++++++++++------------------ 3 files changed, 81 insertions(+), 38 deletions(-) diff --git a/query.go b/query.go index adfbd434..f166d5a9 100644 --- a/query.go +++ b/query.go @@ -32,11 +32,12 @@ type queryRequest struct { State bool `json:"state"` Presence bool `json:"presence"` - UserID string `json:"user_id,omitempty"` - Limit int `json:"limit,omitempty"` - Offset int `json:"offset,omitempty"` - MemberLimit *int `json:"member_limit,omitempty"` - MessageLimit *int `json:"message_limit,omitempty"` + UserID string `json:"user_id,omitempty"` + Limit int `json:"limit,omitempty"` + Offset int `json:"offset,omitempty"` + MemberLimit *int `json:"member_limit,omitempty"` + MessageLimit *int `json:"message_limit,omitempty"` + IncludeDeactivatedUsers bool `json:"include_deactivated_users,omitempty"` FilterConditions map[string]interface{} `json:"filter_conditions,omitempty"` Sort []*SortOption `json:"sort,omitempty"` @@ -58,19 +59,26 @@ type FlagReport struct { UpdatedAt time.Time `json:"updated_at"` } +type QueryUsersOptions struct { + QueryOption + + IncludeDeactivatedUsers bool `json:"include_deactivated_users"` +} + type QueryUsersResponse struct { Users []*User `json:"users"` Response } -// QueryUsers returns list of users that match QueryOption. +// QueryUsers returns list of users that match QueryUsersOptions. // If any number of SortOption are set, result will be sorted by field and direction in the order of sort options. -func (c *Client) QueryUsers(ctx context.Context, q *QueryOption, sorters ...*SortOption) (*QueryUsersResponse, error) { +func (c *Client) QueryUsers(ctx context.Context, q *QueryUsersOptions, sorters ...*SortOption) (*QueryUsersResponse, error) { qp := queryRequest{ - FilterConditions: q.Filter, - Limit: q.Limit, - Offset: q.Offset, - Sort: sorters, + FilterConditions: q.Filter, + Limit: q.Limit, + Offset: q.Offset, + IncludeDeactivatedUsers: q.IncludeDeactivatedUsers, + Sort: sorters, } data, err := json.Marshal(&qp) diff --git a/query_test.go b/query_test.go index 5ca4045a..3c646301 100644 --- a/query_test.go +++ b/query_test.go @@ -14,7 +14,7 @@ func TestClient_QueryUsers(t *testing.T) { c := initClient(t) ctx := context.Background() - const n = 4 + const n = 5 ids := make([]string, n) t.Cleanup(func() { for _, id := range ids { @@ -32,25 +32,30 @@ func TestClient_QueryUsers(t *testing.T) { time.Sleep(200 * time.Millisecond) } + _, err := c.DeactivateUser(ctx, ids[n-1]) + require.NoError(t, err) + t.Parallel() t.Run("Query all", func(tt *testing.T) { - results, err := c.QueryUsers(ctx, &QueryOption{ - Filter: map[string]interface{}{ - "id": map[string]interface{}{ - "$in": ids, + results, err := c.QueryUsers(ctx, &QueryUsersOptions{ + QueryOption: QueryOption{ + Filter: map[string]interface{}{ + "id": map[string]interface{}{ + "$in": ids, + }, }, }, }) require.NoError(tt, err) - require.Len(tt, results.Users, len(ids)) + require.Len(tt, results.Users, len(ids)-1) }) t.Run("Query with offset/limit", func(tt *testing.T) { offset := 1 - results, err := c.QueryUsers(ctx, - &QueryOption{ + results, err := c.QueryUsers(ctx, &QueryUsersOptions{ + QueryOption: QueryOption{ Filter: map[string]interface{}{ "id": map[string]interface{}{ "$in": ids, @@ -59,7 +64,7 @@ func TestClient_QueryUsers(t *testing.T) { Offset: offset, Limit: 2, }, - ) + }) require.NoError(tt, err) require.Len(tt, results.Users, 2) @@ -67,6 +72,22 @@ func TestClient_QueryUsers(t *testing.T) { require.Equal(tt, results.Users[0].ID, ids[offset]) require.Equal(tt, results.Users[1].ID, ids[offset+1]) }) + + t.Run("Query with deactivated", func(tt *testing.T) { + results, err := c.QueryUsers(ctx, &QueryUsersOptions{ + QueryOption: QueryOption{ + Filter: map[string]interface{}{ + "id": map[string]interface{}{ + "$in": ids, + }, + }, + }, + IncludeDeactivatedUsers: true, + }) + + require.NoError(tt, err) + require.Len(tt, results.Users, len(ids)) + }) } func TestClient_QueryChannels(t *testing.T) { diff --git a/user_test.go b/user_test.go index d8d37bc6..c9b55d8c 100644 --- a/user_test.go +++ b/user_test.go @@ -17,9 +17,11 @@ func TestClient_MuteUser(t *testing.T) { _, err := c.MuteUser(ctx, randomUser(t, c).ID, user.ID) require.NoError(t, err, "MuteUser should not return an error") - resp, err := c.QueryUsers(ctx, &QueryOption{ - Filter: map[string]interface{}{ - "id": map[string]string{"$eq": user.ID}, + resp, err := c.QueryUsers(ctx, &QueryUsersOptions{ + QueryOption: QueryOption{ + Filter: map[string]interface{}{ + "id": map[string]string{"$eq": user.ID}, + }, }, }) @@ -38,9 +40,11 @@ func TestClient_MuteUser(t *testing.T) { _, err = c.MuteUser(ctx, randomUser(t, c).ID, user.ID, MuteWithExpiration(60)) require.NoError(t, err, "MuteUser should not return an error") - resp, err = c.QueryUsers(ctx, &QueryOption{ - Filter: map[string]interface{}{ - "id": map[string]string{"$eq": user.ID}, + resp, err = c.QueryUsers(ctx, &QueryUsersOptions{ + QueryOption: QueryOption{ + Filter: map[string]interface{}{ + "id": map[string]string{"$eq": user.ID}, + }, }, }) @@ -65,9 +69,11 @@ func TestClient_MuteUsers(t *testing.T) { _, err := c.MuteUsers(ctx, targetIDs, user.ID, MuteWithExpiration(60)) require.NoError(t, err, "MuteUsers should not return an error") - resp, err := c.QueryUsers(ctx, &QueryOption{ - Filter: map[string]interface{}{ - "id": map[string]string{"$eq": user.ID}, + resp, err := c.QueryUsers(ctx, &QueryUsersOptions{ + QueryOption: QueryOption{ + Filter: map[string]interface{}{ + "id": map[string]string{"$eq": user.ID}, + }, }, }) @@ -80,6 +86,7 @@ func TestClient_MuteUsers(t *testing.T) { assert.NotEmpty(t, mute.Expires, "mute should have Expires") } } + func TestClient_BlockUsers(t *testing.T) { c := initClient(t) ctx := context.Background() @@ -90,9 +97,11 @@ func TestClient_BlockUsers(t *testing.T) { _, err := c.BlockUser(ctx, blockedUser.ID, blockingUser.ID) require.NoError(t, err, "BlockUser should not return an error") - resp, err := c.QueryUsers(ctx, &QueryOption{ - Filter: map[string]interface{}{ - "id": map[string]string{"$eq": blockingUser.ID}, + resp, err := c.QueryUsers(ctx, &QueryUsersOptions{ + QueryOption: QueryOption{ + Filter: map[string]interface{}{ + "id": map[string]string{"$eq": blockingUser.ID}, + }, }, }) @@ -103,6 +112,7 @@ func TestClient_BlockUsers(t *testing.T) { require.Equal(t, users[0].BlockedUserIDs[0], blockedUser.ID) } + func TestClient_UnblockUsersGetBlockedUsers(t *testing.T) { c := initClient(t) ctx := context.Background() @@ -113,9 +123,11 @@ func TestClient_UnblockUsersGetBlockedUsers(t *testing.T) { _, err := c.BlockUser(ctx, blockedUser.ID, blockingUser.ID) require.NoError(t, err, "BlockUser should not return an error") - resp, err := c.QueryUsers(ctx, &QueryOption{ - Filter: map[string]interface{}{ - "id": map[string]string{"$eq": blockingUser.ID}, + resp, err := c.QueryUsers(ctx, &QueryUsersOptions{ + QueryOption: QueryOption{ + Filter: map[string]interface{}{ + "id": map[string]string{"$eq": blockingUser.ID}, + }, }, }) @@ -132,9 +144,11 @@ func TestClient_UnblockUsersGetBlockedUsers(t *testing.T) { _, err = c.UnblockUser(ctx, blockedUser.ID, blockingUser.ID) require.NoError(t, err, "UnblockUser should not return an error") - resp, err = c.QueryUsers(ctx, &QueryOption{ - Filter: map[string]interface{}{ - "id": map[string]string{"$eq": blockingUser.ID}, + resp, err = c.QueryUsers(ctx, &QueryUsersOptions{ + QueryOption: QueryOption{ + Filter: map[string]interface{}{ + "id": map[string]string{"$eq": blockingUser.ID}, + }, }, })