MM-45120: Track team join times. Add API to retrieve new team members since a given time. (#20708)
* MM-45120: Starts tracking team join time. Adds API to retrieve team members who joined after a given time. * MM-45120: Updates json casing to match model.User.
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
1738bd6e92
Коммит
55b3961b98
@@ -23,6 +23,9 @@ func (api *API) InitInsights() {
|
||||
// Threads
|
||||
api.BaseRoutes.InsightsForTeam.Handle("/threads", api.APISessionRequired(requireLicense(getTopThreadsForTeamSince))).Methods("GET")
|
||||
api.BaseRoutes.InsightsForUser.Handle("/threads", api.APISessionRequired(requireLicense(getTopThreadsForUserSince))).Methods("GET")
|
||||
|
||||
// New teammembers
|
||||
api.BaseRoutes.InsightsForTeam.Handle("/team_members", api.APISessionRequired(minimumProfessionalLicense(rejectGuests(getNewTeamMembersSince)))).Methods("GET")
|
||||
}
|
||||
|
||||
// Top Reactions
|
||||
@@ -357,3 +360,49 @@ func postCountByDurationViewModel(c *Context, topChannelList *model.TopChannelLi
|
||||
}
|
||||
return model.ToDailyPostCountViewModel(postCountsByDay, startTime, model.TimeRangeToNumberDays(timeRange), channelIDs), nil
|
||||
}
|
||||
|
||||
func getNewTeamMembersSince(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.RequireTeamId()
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
team, err := c.App.GetTeam(c.Params.TeamId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), team.Id, model.PermissionViewTeam) {
|
||||
c.SetPermissionError(model.PermissionViewTeam)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := c.App.GetUser(c.AppContext.Session().UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
loc := user.GetTimezoneLocation()
|
||||
startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, loc)
|
||||
|
||||
ntms, count, err := c.App.GetNewTeamMembersSince(c.AppContext, c.Params.TeamId, &model.InsightsOpts{
|
||||
StartUnixMilli: startTime.UnixMilli(),
|
||||
Page: c.Params.Page,
|
||||
PerPage: c.Params.PerPage,
|
||||
})
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
ntms.TotalCount = count
|
||||
|
||||
js, jsonErr := json.Marshal(ntms)
|
||||
if jsonErr != nil {
|
||||
c.Err = model.NewAppError("getNewTeamembersForTeamSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(js)
|
||||
}
|
||||
|
||||
@@ -816,3 +816,86 @@ func TestGetTopThreadsForUserSince(t *testing.T) {
|
||||
require.Nil(t, appErr)
|
||||
require.Len(t, topUser2ThreadsAfterPrivateReplyDelete.Items, 0)
|
||||
}
|
||||
|
||||
func TestNewTeamMembersSince(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
th.LoginBasic()
|
||||
|
||||
team := th.CreateTeam()
|
||||
|
||||
t.Run("accepts only starter or professional license skus", func(t *testing.T) {
|
||||
_, resp, _ := th.Client.GetNewTeamMembersSince(team.Id, model.TimeRangeToday, 0, 5)
|
||||
CheckNotImplementedStatus(t, resp)
|
||||
|
||||
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuE10))
|
||||
_, resp, _ = th.Client.GetNewTeamMembersSince(team.Id, model.TimeRangeToday, 0, 5)
|
||||
CheckNotImplementedStatus(t, resp)
|
||||
|
||||
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuE20))
|
||||
_, resp, _ = th.Client.GetNewTeamMembersSince(team.Id, model.TimeRangeToday, 0, 5)
|
||||
CheckNotImplementedStatus(t, resp)
|
||||
|
||||
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuProfessional))
|
||||
_, resp, err := th.Client.GetNewTeamMembersSince(team.Id, model.TimeRangeToday, 0, 5)
|
||||
require.NoError(t, err)
|
||||
CheckOKStatus(t, resp)
|
||||
|
||||
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterprise))
|
||||
_, resp, err = th.Client.GetNewTeamMembersSince(team.Id, model.TimeRangeToday, 0, 5)
|
||||
require.NoError(t, err)
|
||||
CheckOKStatus(t, resp)
|
||||
})
|
||||
|
||||
t.Run("rejects guests", func(t *testing.T) {
|
||||
_, resp, err := th.Client.GetNewTeamMembersSince(team.Id, model.TimeRangeToday, 0, 5)
|
||||
require.NoError(t, err)
|
||||
CheckOKStatus(t, resp)
|
||||
|
||||
th.App.DemoteUserToGuest(th.Context, th.BasicUser)
|
||||
defer th.App.PromoteGuestToUser(th.Context, th.BasicUser, "")
|
||||
|
||||
_, resp, _ = th.Client.GetNewTeamMembersSince(team.Id, model.TimeRangeToday, 0, 5)
|
||||
CheckNotImplementedStatus(t, resp)
|
||||
})
|
||||
|
||||
t.Run("implements pagination", func(t *testing.T) {
|
||||
// check the first page of results
|
||||
list, resp, err := th.Client.GetNewTeamMembersSince(team.Id, model.TimeRangeToday, 0, 2)
|
||||
require.NoError(t, err)
|
||||
CheckOKStatus(t, resp)
|
||||
|
||||
require.Equal(t, int(list.TotalCount), 1)
|
||||
require.Len(t, list.Items, 1)
|
||||
require.False(t, list.HasNext)
|
||||
|
||||
// check the 2nd page
|
||||
list, resp, err = th.Client.GetNewTeamMembersSince(team.Id, model.TimeRangeToday, 1, 2)
|
||||
require.NoError(t, err)
|
||||
CheckOKStatus(t, resp)
|
||||
|
||||
require.GreaterOrEqual(t, len(list.Items), 0)
|
||||
|
||||
// add a few new team members and re-test the pagination
|
||||
user := th.CreateUser()
|
||||
_, appErr := th.App.AddTeamMember(th.Context, team.Id, th.BasicUser2.Id)
|
||||
require.Nil(t, appErr)
|
||||
_, appErr = th.App.AddTeamMember(th.Context, team.Id, user.Id)
|
||||
require.Nil(t, appErr)
|
||||
|
||||
list, resp, err = th.Client.GetNewTeamMembersSince(team.Id, model.TimeRangeToday, 0, 2)
|
||||
require.NoError(t, err)
|
||||
CheckOKStatus(t, resp)
|
||||
require.Equal(t, 3, int(list.TotalCount))
|
||||
require.Len(t, list.Items, 2)
|
||||
require.True(t, list.HasNext)
|
||||
|
||||
list, resp, err = th.Client.GetNewTeamMembersSince(team.Id, model.TimeRangeToday, 1, 2)
|
||||
require.NoError(t, err)
|
||||
CheckOKStatus(t, resp)
|
||||
require.Equal(t, int(list.TotalCount), 3)
|
||||
require.Len(t, list.Items, 1)
|
||||
require.False(t, list.HasNext)
|
||||
})
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user