Skip to content

Commit

Permalink
[MM-56398] Fix date range query for user reporting (mattermost#25960)
Browse files Browse the repository at this point in the history
* [MM-56398] Fix date range query for user reporting

* Missing debug stuff

* Fix tests
  • Loading branch information
devinbinnie authored Jan 18, 2024
1 parent 81de078 commit bbe432b
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 23 deletions.
10 changes: 5 additions & 5 deletions server/channels/api4/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func fillReportingBaseOptions(values url.Values) model.ReportingBaseOptions {
pageSize = int(pageSizeStr)
}

return model.ReportingBaseOptions{
options := model.ReportingBaseOptions{
Direction: direction,
SortColumn: sortColumn,
SortDesc: values.Get("sort_direction") == "desc",
Expand All @@ -98,6 +98,8 @@ func fillReportingBaseOptions(values url.Values) model.ReportingBaseOptions {
FromId: values.Get("from_id"),
DateRange: values.Get("date_range"),
}
options.PopulateDateRange(time.Now())
return options
}

func fillUserReportOptions(values url.Values) (*model.UserReportOptions, *model.AppError) {
Expand All @@ -112,15 +114,13 @@ func fillUserReportOptions(values url.Values) (*model.UserReportOptions, *model.
return nil, model.NewAppError("getUsersForReporting", "api.getUsersForReporting.invalid_active_filter", nil, "", http.StatusBadRequest)
}

options := &model.UserReportOptions{
return &model.UserReportOptions{

Team: teamFilter,
Role: values.Get("role_filter"),
HasNoTeam: values.Get("has_no_team") == "true",
HideActive: hideActive,
HideInactive: hideInactive,
SearchTerm: values.Get("search_term"),
}
options.PopulateDateRange(time.Now())
return options, nil
}, nil
}
34 changes: 16 additions & 18 deletions server/channels/store/sqlstore/user_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -2377,35 +2377,33 @@ func (us SqlUserStore) GetUserReport(filter *model.UserReportOptions) ([]*model.
}

if isPostgres {
query = query.LeftJoin("PostStats ps ON ps.UserId = u.Id")
joinSql := sq.And{}
if filter.StartAt > 0 {
startDate := time.UnixMilli(filter.StartAt)
query = query.Where(sq.Or{
sq.Expr("ps.UserId IS NULL"),
sq.GtOrEq{"ps.Day": startDate.Format("2006-01-02")},
})
joinSql = append(joinSql, sq.GtOrEq{"ps.Day": startDate.Format("2006-01-02")})
}
if filter.EndAt > 0 {
endDate := time.UnixMilli(filter.EndAt)
query = query.Where(sq.Or{
sq.Expr("ps.UserId IS NULL"),
sq.Lt{"ps.Day": endDate.Format("2006-01-02")},
})
joinSql = append(joinSql, sq.Lt{"ps.Day": endDate.Format("2006-01-02")})
}
sql, args, err := joinSql.ToSql()
if err != nil {
return nil, err
}
query = query.LeftJoin("PostStats ps ON ps.UserId = u.Id AND "+sql, args...)
} else {
query = query.LeftJoin("Posts p on p.UserId = u.Id")
joinSql := sq.And{}
if filter.StartAt > 0 {
query = query.Where(sq.Or{
sq.Expr("p.UserId IS NULL"),
sq.GtOrEq{"p.CreateAt": filter.StartAt},
})
joinSql = append(joinSql, sq.GtOrEq{"p.CreateAt": filter.StartAt})
}
if filter.EndAt > 0 {
query = query.Where(sq.Or{
sq.Expr("p.UserId IS NULL"),
sq.Lt{"p.CreateAt": filter.EndAt},
})
joinSql = append(joinSql, sq.Lt{"p.CreateAt": filter.EndAt})
}
sql, args, err := joinSql.ToSql()
if err != nil {
return nil, err
}
query = query.LeftJoin("Posts p ON p.UserId = u.Id AND "+sql, args...)
}

query = applyUserReportFilter(query, filter, isPostgres)
Expand Down
14 changes: 14 additions & 0 deletions server/channels/store/storetest/user_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -6400,6 +6400,20 @@ func testGetUserReport(t *testing.T, rctx request.CTX, ss store.Store) {
require.Equal(t, users[60].Username, userReport[0].Username)
})

t.Run("should return all users regardless of date range", func(t *testing.T) {
userReport, err := ss.User().GetUserReport(&model.UserReportOptions{
ReportingBaseOptions: model.ReportingBaseOptions{
SortColumn: "Username",
PageSize: 50,
StartAt: now.AddDate(1000, 0, 0).UnixMilli(),
EndAt: now.AddDate(1000, 0, 0).UnixMilli(),
},
})

require.NoError(t, err)
require.Len(t, userReport, 50)
})

t.Run("should return accurate post stats for various date ranges", func(t *testing.T) {
userReport, err := ss.User().GetUserReport(&model.UserReportOptions{
ReportingBaseOptions: model.ReportingBaseOptions{
Expand Down

0 comments on commit bbe432b

Please sign in to comment.