Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 23 additions & 33 deletions projects/activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -214,6 +213,18 @@ type ActivityListRequestFilters struct {
// share an identifier.
ItemIDs []int64

// ProjectIDs filters activities by the projects they belong to. The
// project-scoped route takes its project from the path and ignores this
// filter.
ProjectIDs []int64

// UserIDs filters activities by the users that created them.
UserIDs []int64

// ExcludeUserIDs filters out activities created by these users. Pass the
// logged-in user's identifier to drop their own activity from the feed.
ExcludeUserIDs []int64

// OrderBy is the field to sort the results by. Use the ActivityOrderBy
// constants. The endpoint defaults to date.
OrderBy ActivityOrderBy
Expand Down Expand Up @@ -243,38 +254,17 @@ type ActivityListRequestFilters struct {

func (a ActivityListRequestFilters) apply(req *http.Request) {
query := req.URL.Query()
if !a.StartDate.IsZero() {
query.Set("startDate", a.StartDate.Format(time.RFC3339))
}
if !a.EndDate.IsZero() {
query.Set("endDate", a.EndDate.Format(time.RFC3339))
}
if len(a.LogItemTypes) > 0 {
logItemTypes := make([]string, len(a.LogItemTypes))
for i, logType := range a.LogItemTypes {
logItemTypes[i] = string(logType)
}
query.Set("activityTypes", strings.Join(logItemTypes, ","))
}
if len(a.ItemIDs) > 0 {
itemIDs := make([]string, len(a.ItemIDs))
for i, itemID := range a.ItemIDs {
itemIDs[i] = strconv.FormatInt(itemID, 10)
}
query.Set("itemIds", strings.Join(itemIDs, ","))
}
if a.OrderBy != "" {
query.Set("orderBy", string(a.OrderBy))
}
if a.OrderMode != "" {
query.Set("orderMode", string(a.OrderMode))
}
if a.Page > 0 {
query.Set("page", strconv.FormatInt(a.Page, 10))
}
if a.PageSize > 0 {
query.Set("pageSize", strconv.FormatInt(a.PageSize, 10))
}
querySetTimestamp(query, "startDate", &a.StartDate)
querySetTimestamp(query, "endDate", &a.EndDate)
querySetStrings(query, "activityTypes", a.LogItemTypes)
querySetInt64s(query, "itemIds", a.ItemIDs)
querySetInt64s(query, "projectIds", a.ProjectIDs)
querySetInt64s(query, "userIds", a.UserIDs)
querySetInt64s(query, "excludeUserIds", a.ExcludeUserIDs)
querySetString(query, "orderBy", a.OrderBy)
querySetString(query, "orderMode", a.OrderMode)
querySetInt64(query, "page", a.Page)
querySetInt64(query, "pageSize", a.PageSize)
a.Fields.apply(query)
a.CountMode.Apply(query)
req.URL.RawQuery = query.Encode()
Expand Down
83 changes: 52 additions & 31 deletions projects/activity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,45 +114,66 @@ func TestLogItemType_UnmarshalText(t *testing.T) {
})
}

func TestActivityListItemIDs(t *testing.T) {
func TestActivityListIDFilters(t *testing.T) {
filters := []struct {
param string
set func(*projects.ActivityListRequestFilters, []int64)
}{{
param: "itemIds",
set: func(f *projects.ActivityListRequestFilters, ids []int64) { f.ItemIDs = ids },
}, {
param: "projectIds",
set: func(f *projects.ActivityListRequestFilters, ids []int64) { f.ProjectIDs = ids },
}, {
param: "userIds",
set: func(f *projects.ActivityListRequestFilters, ids []int64) { f.UserIDs = ids },
}, {
param: "excludeUserIds",
set: func(f *projects.ActivityListRequestFilters, ids []int64) { f.ExcludeUserIDs = ids },
}}

tests := []struct {
name string
itemIDs []int64
want string
name string
ids []int64
want string
}{{
name: "unset item ids are not sent",
name: "unset ids are not sent",
}, {
name: "single item id",
itemIDs: []int64{777},
want: "777",
name: "single id",
ids: []int64{777},
want: "777",
}, {
name: "multiple item ids are comma-separated",
itemIDs: []int64{777, 12345},
want: "777,12345",
name: "multiple ids are comma-separated",
ids: []int64{777, 12345},
want: "777,12345",
}}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := projects.NewActivityListRequest()
req.Filters.ItemIDs = tt.itemIDs
for _, filter := range filters {
t.Run(filter.param, func(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := projects.NewActivityListRequest()
filter.set(&req.Filters, tt.ids)

httpReq, err := req.HTTPRequest(context.Background(), "https://test.com")
if err != nil {
t.Fatalf("unexpected error creating HTTP request: %s", err)
}
query, err := url.ParseQuery(httpReq.URL.RawQuery)
if err != nil {
t.Fatalf("failed to parse query string: %s", err)
}
httpReq, err := req.HTTPRequest(context.Background(), "https://test.com")
if err != nil {
t.Fatalf("unexpected error creating HTTP request: %s", err)
}
query, err := url.ParseQuery(httpReq.URL.RawQuery)
if err != nil {
t.Fatalf("failed to parse query string: %s", err)
}

if tt.want == "" {
if _, ok := query["itemIds"]; ok {
t.Errorf("expected no itemIds parameter, got %q", query.Get("itemIds"))
}
return
}
if got := query.Get("itemIds"); got != tt.want {
t.Errorf("itemIds = %q, want %q", got, tt.want)
if tt.want == "" {
if _, ok := query[filter.param]; ok {
t.Errorf("expected no %s parameter, got %q", filter.param, query.Get(filter.param))
}
return
}
if got := query.Get(filter.param); got != tt.want {
t.Errorf("%s = %q, want %q", filter.param, got, tt.want)
}
})
}
})
}
Expand Down