* Mark category as read

* Fix lint and test

* Fix tests

* Fix test and remove wrong aria

* Address server issues and add mark as read for unreads

* Missing changes

* Fix tests

* fix tests

* Add confirmation popup to mark as read category

* Always use viewMultipleChannels and other fixes

* Remove unneeded code

* Fix test

* Address feedback

* Address feedback

* Fix tests

* Fix test

* Fix tests

* Update aria-haspopup depending on the number of channels to mark as viewed

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Daniel Espino García
2023-08-14 10:01:02 +02:00
коммит произвёл GitHub
родитель c1c07ba1bb
Коммит e9b3afecc2
60 изменённых файлов: 1151 добавлений и 1557 удалений

Просмотреть файл

@@ -8,6 +8,7 @@ import (
"database/sql"
"encoding/json"
"errors"
"fmt"
"sort"
"strconv"
"strings"
@@ -149,6 +150,7 @@ func TestChannelStore(t *testing.T, ss store.Store, s SqlStore) {
t.Run("UpdateSidebarChannelsByPreferences", func(t *testing.T) { testUpdateSidebarChannelsByPreferences(t, ss) })
t.Run("SetShared", func(t *testing.T) { testSetShared(t, ss) })
t.Run("GetTeamForChannel", func(t *testing.T) { testGetTeamForChannel(t, ss) })
t.Run("GetChannelsWithUnreadsAndWithMentions", func(t *testing.T) { testGetChannelsWithUnreadsAndWithMentions(t, ss) })
}
func testChannelStoreSave(t *testing.T, ss store.Store) {
@@ -8065,3 +8067,166 @@ func testGetTeamForChannel(t *testing.T, ss store.Store) {
var nfErr *store.ErrNotFound
require.True(t, errors.As(err, &nfErr))
}
func testGetChannelsWithUnreadsAndWithMentions(t *testing.T, ss store.Store) {
setupMembership := func(
pushProp string,
withUnreads bool,
withMentions bool,
isDirect bool,
userId string,
) (model.Channel, model.ChannelMember) {
if !isDirect {
o1 := model.Channel{}
o1.TeamId = model.NewId()
o1.DisplayName = "Channel1"
o1.Name = NewTestId()
o1.Type = model.ChannelTypeOpen
o1.TotalMsgCount = 25
o1.LastPostAt = 12345
o1.LastRootPostAt = 12345
_, nErr := ss.Channel().Save(&o1, -1)
require.NoError(t, nErr)
m1 := model.ChannelMember{}
m1.ChannelId = o1.Id
m1.UserId = userId
m1.NotifyProps = model.GetDefaultChannelNotifyProps()
m1.NotifyProps[model.PushNotifyProp] = pushProp
if !withUnreads {
m1.MsgCount = o1.TotalMsgCount
m1.LastViewedAt = o1.LastPostAt
}
if withMentions {
m1.MentionCount = 5
}
_, err := ss.Channel().SaveMember(&m1)
require.NoError(t, err)
return o1, m1
}
o1, err := ss.Channel().CreateDirectChannel(&model.User{Id: userId}, &model.User{Id: model.NewId()}, func(channel *model.Channel) {
channel.TotalMsgCount = 25
channel.LastPostAt = 12345
channel.LastRootPostAt = 12345
})
require.NoError(t, err)
m1, err := ss.Channel().GetMember(context.Background(), o1.Id, userId)
require.NoError(t, err)
if !withUnreads {
m1.MsgCount = o1.TotalMsgCount
m1.LastViewedAt = o1.LastPostAt
}
if withMentions {
m1.MentionCount = 5
}
m1, err = ss.Channel().UpdateMember(m1)
require.NoError(t, err)
return *o1, *m1
}
type TestCase struct {
name string
pushProp string
userNotifyProp string
isDirect bool
withUnreads bool
withMentions bool
}
ttcc := []TestCase{}
channelNotifyProps := []string{model.ChannelNotifyDefault, model.ChannelNotifyAll, model.ChannelNotifyMention, model.ChannelNotifyNone}
userNotifyProps := []string{model.UserNotifyAll, model.UserNotifyMention, model.UserNotifyHere, model.UserNotifyNone}
boolRange := []bool{true, false}
nameTemplate := "pushProp: %s, userPushProp: %s, direct: %t, unreads: %t, mentions: %t"
for _, pushProp := range channelNotifyProps {
for _, userNotifyProp := range userNotifyProps {
for _, isDirect := range boolRange {
for _, withUnreads := range boolRange {
ttcc = append(ttcc, TestCase{
name: fmt.Sprintf(nameTemplate, pushProp, userNotifyProp, isDirect, withUnreads, false),
pushProp: pushProp,
userNotifyProp: userNotifyProp,
isDirect: isDirect,
withUnreads: withUnreads,
withMentions: false,
})
if withUnreads {
ttcc = append(ttcc, TestCase{
name: fmt.Sprintf(nameTemplate, pushProp, userNotifyProp, isDirect, withUnreads, true),
pushProp: pushProp,
userNotifyProp: userNotifyProp,
isDirect: isDirect,
withUnreads: withUnreads,
withMentions: true,
})
}
}
}
}
}
for _, tc := range ttcc {
t.Run(tc.name, func(t *testing.T) {
o1, m1 := setupMembership(tc.pushProp, tc.withUnreads, tc.withMentions, tc.isDirect, model.NewId())
userNotifyProps := model.GetDefaultChannelNotifyProps()
userNotifyProps[model.PushNotifyProp] = tc.userNotifyProp
unreads, mentions, times, err := ss.Channel().GetChannelsWithUnreadsAndWithMentions(context.Background(), []string{o1.Id}, m1.UserId, userNotifyProps)
require.NoError(t, err)
expectedUnreadsLength := 0
if tc.withUnreads {
expectedUnreadsLength = 1
}
require.Len(t, unreads, expectedUnreadsLength)
propToUse := tc.pushProp
if tc.pushProp == model.ChannelNotifyDefault {
propToUse = tc.userNotifyProp
}
expectedMentionsLength := 0
if (tc.isDirect && tc.withUnreads) || (propToUse == model.UserNotifyAll && tc.withUnreads) || (propToUse == model.UserNotifyMention && tc.withMentions) {
expectedMentionsLength = 1
}
require.Len(t, mentions, expectedMentionsLength)
require.Equal(t, o1.LastPostAt, times[o1.Id])
})
}
t.Run("multiple channels", func(t *testing.T) {
userId := model.NewId()
o1, _ := setupMembership(model.ChannelNotifyDefault, true, true, false, userId)
o2, _ := setupMembership(model.ChannelNotifyDefault, true, true, false, userId)
userNotifyProps := model.GetDefaultChannelNotifyProps()
userNotifyProps[model.PushNotifyProp] = model.UserNotifyMention
unreads, mentions, times, err := ss.Channel().GetChannelsWithUnreadsAndWithMentions(context.Background(), []string{o1.Id, o2.Id}, userId, userNotifyProps)
require.NoError(t, err)
require.Contains(t, unreads, o1.Id)
require.Contains(t, unreads, o2.Id)
require.Contains(t, mentions, o1.Id)
require.Contains(t, mentions, o2.Id)
require.Equal(t, o1.LastPostAt, times[o1.Id])
require.Equal(t, o2.LastPostAt, times[o2.Id])
})
t.Run("non existing channel", func(t *testing.T) {
userNotifyProps := model.GetDefaultChannelNotifyProps()
userNotifyProps[model.PushNotifyProp] = model.UserNotifyMention
unreads, mentions, times, err := ss.Channel().GetChannelsWithUnreadsAndWithMentions(context.Background(), []string{"foo"}, "foo", userNotifyProps)
require.NoError(t, err)
require.Len(t, unreads, 0)
require.Len(t, mentions, 0)
require.Len(t, times, 0)
})
}

Просмотреть файл

@@ -986,6 +986,50 @@ func (_m *ChannelStore) GetChannelsWithTeamDataByIds(channelIds []string, includ
return r0, r1
}
// GetChannelsWithUnreadsAndWithMentions provides a mock function with given fields: ctx, channelIDs, userID, userNotifyProps
func (_m *ChannelStore) GetChannelsWithUnreadsAndWithMentions(ctx context.Context, channelIDs []string, userID string, userNotifyProps model.StringMap) ([]string, []string, map[string]int64, error) {
ret := _m.Called(ctx, channelIDs, userID, userNotifyProps)
var r0 []string
var r1 []string
var r2 map[string]int64
var r3 error
if rf, ok := ret.Get(0).(func(context.Context, []string, string, model.StringMap) ([]string, []string, map[string]int64, error)); ok {
return rf(ctx, channelIDs, userID, userNotifyProps)
}
if rf, ok := ret.Get(0).(func(context.Context, []string, string, model.StringMap) []string); ok {
r0 = rf(ctx, channelIDs, userID, userNotifyProps)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
if rf, ok := ret.Get(1).(func(context.Context, []string, string, model.StringMap) []string); ok {
r1 = rf(ctx, channelIDs, userID, userNotifyProps)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).([]string)
}
}
if rf, ok := ret.Get(2).(func(context.Context, []string, string, model.StringMap) map[string]int64); ok {
r2 = rf(ctx, channelIDs, userID, userNotifyProps)
} else {
if ret.Get(2) != nil {
r2 = ret.Get(2).(map[string]int64)
}
}
if rf, ok := ret.Get(3).(func(context.Context, []string, string, model.StringMap) error); ok {
r3 = rf(ctx, channelIDs, userID, userNotifyProps)
} else {
r3 = ret.Error(3)
}
return r0, r1, r2, r3
}
// GetDeleted provides a mock function with given fields: team_id, offset, limit, userID
func (_m *ChannelStore) GetDeleted(team_id string, offset int, limit int, userID string) (model.ChannelList, error) {
ret := _m.Called(team_id, offset, limit, userID)