diff --git a/pkg/models/task_collection_filter.go b/pkg/models/task_collection_filter.go index 0e86a683be1..4a254a3c71f 100644 --- a/pkg/models/task_collection_filter.go +++ b/pkg/models/task_collection_filter.go @@ -214,6 +214,15 @@ func getNativeValueForTaskField(fieldName string, comparator taskFilterComparato return } + if realFieldName == "Assignees" { + vals := strings.Split(value, ",") + valueSlice := []string{} + for _, val := range vals { + valueSlice = append(valueSlice, val) + } + return valueSlice, nil + } + field, ok := reflect.TypeOf(&Task{}).Elem().FieldByName(realFieldName) if !ok { return nil, ErrInvalidTaskField{TaskField: fieldName} diff --git a/pkg/models/task_collection_test.go b/pkg/models/task_collection_test.go index b15d77fec3d..7429ab5af8d 100644 --- a/pkg/models/task_collection_test.go +++ b/pkg/models/task_collection_test.go @@ -934,10 +934,10 @@ func TestTaskCollection_ReadAll(t *testing.T) { wantErr: false, }, { - name: "filter assignees", + name: "filter assignees by username", fields: fields{ FilterBy: []string{"assignees"}, - FilterValue: []string{"1"}, + FilterValue: []string{"user1"}, FilterComparator: []string{"equals"}, }, args: defaultArgs, @@ -947,12 +947,80 @@ func TestTaskCollection_ReadAll(t *testing.T) { wantErr: false, }, { - name: "filter assignees in", + name: "filter assignees by username with users field name", + fields: fields{ + FilterBy: []string{"users"}, + FilterValue: []string{"user1"}, + FilterComparator: []string{"equals"}, + }, + args: defaultArgs, + want: nil, + wantErr: true, + }, + { + name: "filter assignees by username with user_id field name", + fields: fields{ + FilterBy: []string{"user_id"}, + FilterValue: []string{"user1"}, + FilterComparator: []string{"equals"}, + }, + args: defaultArgs, + want: nil, + wantErr: true, + }, + { + name: "filter assignees by multiple username", + fields: fields{ + FilterBy: []string{"assignees", "assignees"}, + FilterValue: []string{"user1", "user2"}, + FilterComparator: []string{"equals", "equals"}, + }, + args: defaultArgs, + want: []*Task{ + task30, + }, + wantErr: false, + }, + { + name: "filter assignees by numbers", + fields: fields{ + FilterBy: []string{"assignees"}, + FilterValue: []string{"1"}, + FilterComparator: []string{"equals"}, + }, + args: defaultArgs, + want: []*Task{}, + wantErr: false, + }, + { + name: "filter assignees by name with like", + fields: fields{ + FilterBy: []string{"assignees"}, + FilterValue: []string{"user"}, + FilterComparator: []string{"like"}, + }, + args: defaultArgs, + want: []*Task{}, + wantErr: true, + }, + { + name: "filter assignees in by id", fields: fields{ FilterBy: []string{"assignees"}, FilterValue: []string{"1,2"}, FilterComparator: []string{"in"}, }, + args: defaultArgs, + want: []*Task{}, + wantErr: false, + }, + { + name: "filter assignees in by username", + fields: fields{ + FilterBy: []string{"assignees"}, + FilterValue: []string{"user1,user2"}, + FilterComparator: []string{"in"}, + }, args: defaultArgs, want: []*Task{ task30, diff --git a/pkg/models/tasks.go b/pkg/models/tasks.go index db1eda693ef..9cdc85834fc 100644 --- a/pkg/models/tasks.go +++ b/pkg/models/tasks.go @@ -338,8 +338,11 @@ func getRawTasksForLists(s *xorm.Session, lists []*List, a web.Auth, opts *taskO continue } - if f.field == "assignees" || f.field == "user_id" { - f.field = "user_id" + if f.field == "assignees" { + if f.comparator == taskFilterComparatorLike { + return nil, 0, 0, ErrInvalidTaskFilterValue{Field: f.field, Value: f.value} + } + f.field = "username" filter, err := getFilterCond(f, opts.filterIncludeNulls) if err != nil { return nil, 0, 0, err @@ -430,7 +433,13 @@ func getRawTasksForLists(s *xorm.Session, lists []*List, a web.Auth, opts *taskO } if len(assigneeFilters) > 0 { - filters = append(filters, getFilterCondForSeparateTable("task_assignees", opts.filterConcat, assigneeFilters)) + assigneeFilter := []builder.Cond{ + builder.In("user_id", + builder.Select("id"). + From("users"). + Where(builder.Or(assigneeFilters...)), + )} + filters = append(filters, getFilterCondForSeparateTable("task_assignees", opts.filterConcat, assigneeFilter)) } if len(labelFilters) > 0 {