[MM-47751][MM-48102] MPA: Send Persistent Notifications (#21619)

* MM-46410: adds urgency on mention counts

We have introduced priority for posts in
https://github.com/mattermost/mattermost-webapp/pull/10951.
We do need to color the mention badges in the webapp with a prominent
color when a mention is posted in an urgent message.
A thread has urgent mentions if the root post is marked as urgent, and
the replies contain mentions to the user viewing the thread.

This PR adds two columns, urgentmentioncount, and isurgent, in
channelmembers, and threads tables respectively.
Furthermore when asking for team/thread mention counts, we also return
urgent mention counts for the user.

* Adds PostAcknowledgements table and apis

* job init and fetch mentions

* add-migrations

* delete-expired

* send-notifications

* Fetches post priority in batches

* stop-notifications

* stop-notification-on-reply

* MM-47750: Adds PostAcknowledgements table and apis

- Adds post acknowledgement api/app/store methods to be able to save and
delete post acknowledgements by users.
- Adds wesbsocket events for acknowledgement created/deleted
- Returns post acknowledgements in the post's metadata

* add-license-check

* add-pagination

* delete on channel and team

* validate guests

* add configs

* move create priority post check from app to api

* Add desktop notifications

* check status

* use config in job

* add IsUrgent check

* Add last-sent-at

* validate max recipients

* Update lastSentAt

* Validate min. recipient

* send email notification only once

* remove email notifications

* use latest time from config to run job

* Add notifications counter

* publish events to mentioned users only

* pickup license updates in scheduler

* don't allow post owner to stop notifications

* follow normal notifications behaviour

* Validates persistent notifications interval

* move logic of handling valid and expired posts into sql

* Adds persistent notifications in the webapp

---------

Co-authored-by: koox00 <3829551+koox00@users.noreply.github.com>
Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Vishal
2023-05-18 23:44:12 +05:30
коммит произвёл GitHub
родитель ce165302cf
Коммит 9399ce8637
74 изменённых файлов: 4052 добавлений и 888 удалений

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

@@ -0,0 +1,152 @@
// Code generated by mockery v2.23.2. DO NOT EDIT.
// Regenerate this file using `make store-mocks`.
package mocks
import (
model "github.com/mattermost/mattermost-server/server/public/model"
mock "github.com/stretchr/testify/mock"
)
// PostPersistentNotificationStore is an autogenerated mock type for the PostPersistentNotificationStore type
type PostPersistentNotificationStore struct {
mock.Mock
}
// Delete provides a mock function with given fields: postIds
func (_m *PostPersistentNotificationStore) Delete(postIds []string) error {
ret := _m.Called(postIds)
var r0 error
if rf, ok := ret.Get(0).(func([]string) error); ok {
r0 = rf(postIds)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteByChannel provides a mock function with given fields: channelIds
func (_m *PostPersistentNotificationStore) DeleteByChannel(channelIds []string) error {
ret := _m.Called(channelIds)
var r0 error
if rf, ok := ret.Get(0).(func([]string) error); ok {
r0 = rf(channelIds)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteByTeam provides a mock function with given fields: teamIds
func (_m *PostPersistentNotificationStore) DeleteByTeam(teamIds []string) error {
ret := _m.Called(teamIds)
var r0 error
if rf, ok := ret.Get(0).(func([]string) error); ok {
r0 = rf(teamIds)
} else {
r0 = ret.Error(0)
}
return r0
}
// DeleteExpired provides a mock function with given fields: maxSentCount
func (_m *PostPersistentNotificationStore) DeleteExpired(maxSentCount int16) error {
ret := _m.Called(maxSentCount)
var r0 error
if rf, ok := ret.Get(0).(func(int16) error); ok {
r0 = rf(maxSentCount)
} else {
r0 = ret.Error(0)
}
return r0
}
// Get provides a mock function with given fields: params
func (_m *PostPersistentNotificationStore) Get(params model.GetPersistentNotificationsPostsParams) ([]*model.PostPersistentNotifications, error) {
ret := _m.Called(params)
var r0 []*model.PostPersistentNotifications
var r1 error
if rf, ok := ret.Get(0).(func(model.GetPersistentNotificationsPostsParams) ([]*model.PostPersistentNotifications, error)); ok {
return rf(params)
}
if rf, ok := ret.Get(0).(func(model.GetPersistentNotificationsPostsParams) []*model.PostPersistentNotifications); ok {
r0 = rf(params)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*model.PostPersistentNotifications)
}
}
if rf, ok := ret.Get(1).(func(model.GetPersistentNotificationsPostsParams) error); ok {
r1 = rf(params)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetSingle provides a mock function with given fields: postID
func (_m *PostPersistentNotificationStore) GetSingle(postID string) (*model.PostPersistentNotifications, error) {
ret := _m.Called(postID)
var r0 *model.PostPersistentNotifications
var r1 error
if rf, ok := ret.Get(0).(func(string) (*model.PostPersistentNotifications, error)); ok {
return rf(postID)
}
if rf, ok := ret.Get(0).(func(string) *model.PostPersistentNotifications); ok {
r0 = rf(postID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.PostPersistentNotifications)
}
}
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(postID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// UpdateLastActivity provides a mock function with given fields: postIds
func (_m *PostPersistentNotificationStore) UpdateLastActivity(postIds []string) error {
ret := _m.Called(postIds)
var r0 error
if rf, ok := ret.Get(0).(func([]string) error); ok {
r0 = rf(postIds)
} else {
r0 = ret.Error(0)
}
return r0
}
type mockConstructorTestingTNewPostPersistentNotificationStore interface {
mock.TestingT
Cleanup(func())
}
// NewPostPersistentNotificationStore creates a new instance of PostPersistentNotificationStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewPostPersistentNotificationStore(t mockConstructorTestingTNewPostPersistentNotificationStore) *PostPersistentNotificationStore {
mock := &PostPersistentNotificationStore{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

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

@@ -500,6 +500,22 @@ func (_m *Store) PostAcknowledgement() store.PostAcknowledgementStore {
return r0
}
// PostPersistentNotification provides a mock function with given fields:
func (_m *Store) PostPersistentNotification() store.PostPersistentNotificationStore {
ret := _m.Called()
var r0 store.PostPersistentNotificationStore
if rf, ok := ret.Get(0).(func() store.PostPersistentNotificationStore); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.PostPersistentNotificationStore)
}
}
return r0
}
// PostPriority provides a mock function with given fields:
func (_m *Store) PostPriority() store.PostPriorityStore {
ret := _m.Called()

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

@@ -0,0 +1,452 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package storetest
import (
"testing"
"time"
"github.com/mattermost/mattermost-server/server/public/model"
"github.com/mattermost/mattermost-server/server/v8/channels/store"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPostPersistentNotificationStore(t *testing.T, ss store.Store, s SqlStore) {
t.Run("Get", func(t *testing.T) { testPostPersistentNotificationStoreGet(t, ss) })
t.Run("Delete", func(t *testing.T) { testPostPersistentNotificationStoreDelete(t, ss) })
t.Run("UpdateLastSentAt", func(t *testing.T) { testPostPersistentNotificationStoreUpdateLastSentAt(t, ss) })
}
func testPostPersistentNotificationStoreGet(t *testing.T, ss store.Store) {
p1 := model.Post{}
p1.ChannelId = model.NewId()
p1.UserId = model.NewId()
p1.Message = NewTestId()
p1.CreateAt = 10
p1.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString("important"),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
p2 := model.Post{}
p2.ChannelId = p1.ChannelId
p2.UserId = model.NewId()
p2.Message = NewTestId()
p2.CreateAt = 20
p2.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString(model.PostPriorityUrgent),
RequestedAck: model.NewBool(true),
PersistentNotifications: model.NewBool(true),
},
}
// Invalid - Has no Priority
p3 := model.Post{}
p3.ChannelId = p1.ChannelId
p3.UserId = model.NewId()
p3.Message = NewTestId()
p3.CreateAt = 30
// Invalid - Notification is false
p4 := model.Post{}
p4.ChannelId = p1.ChannelId
p4.UserId = model.NewId()
p4.Message = NewTestId()
p4.CreateAt = 40
p4.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString(model.PostPriorityUrgent),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(false),
},
}
p5 := model.Post{}
p5.ChannelId = p1.ChannelId
p5.UserId = model.NewId()
p5.Message = NewTestId()
p5.CreateAt = 50
p5.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString(model.PostPriorityUrgent),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
_, errIdx, err := ss.Post().SaveMultiple([]*model.Post{&p1, &p2, &p3, &p4, &p5})
require.NoError(t, err)
require.Equal(t, -1, errIdx)
defer ss.Post().PermanentDeleteByChannel(p1.ChannelId)
defer ss.PostPersistentNotification().Delete([]string{p1.Id, p2.Id, p3.Id, p4.Id, p5.Id})
t.Run("Get Single", func(t *testing.T) {
pn, err := ss.PostPersistentNotification().GetSingle(p1.Id)
require.NoError(t, err)
assert.Equal(t, p1.Id, pn.PostId)
pn, err = ss.PostPersistentNotification().GetSingle(p2.Id)
require.NoError(t, err)
assert.Equal(t, p2.Id, pn.PostId)
pn, err = ss.PostPersistentNotification().GetSingle(p5.Id)
require.NoError(t, err)
assert.Equal(t, p5.Id, pn.PostId)
pn, err = ss.PostPersistentNotification().GetSingle(p3.Id)
require.Error(t, err)
require.Zero(t, pn)
pn, err = ss.PostPersistentNotification().GetSingle(p4.Id)
require.Error(t, err)
require.Zero(t, pn)
})
t.Run("Get all before MaxTime", func(t *testing.T) {
validIDs := []string{p1.Id, p2.Id, p5.Id}
getIDs := func(posts []*model.PostPersistentNotifications) (ids []string) {
for _, p := range posts {
ids = append(ids, p.PostId)
}
return
}
// p5 is filtered by maxTime
pn, err := ss.PostPersistentNotification().Get(model.GetPersistentNotificationsPostsParams{
MaxTime: 45,
MaxSentCount: 60,
PerPage: 20,
})
require.NoError(t, err)
require.Len(t, pn, 2)
assert.Contains(t, getIDs(pn), p1.Id)
assert.Contains(t, getIDs(pn), p2.Id)
// nothing is filtered out
pn, err = ss.PostPersistentNotification().Get(model.GetPersistentNotificationsPostsParams{
MaxTime: 100,
MaxSentCount: 60,
PerPage: 20,
})
require.NoError(t, err)
require.Len(t, pn, 3)
assert.ElementsMatch(t, validIDs, getIDs(pn))
})
}
func testPostPersistentNotificationStoreUpdateLastSentAt(t *testing.T, ss store.Store) {
p1 := model.Post{}
p1.ChannelId = model.NewId()
p1.UserId = model.NewId()
p1.Message = NewTestId()
p1.CreateAt = 10
p1.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString("important"),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
_, errIdx, err := ss.Post().SaveMultiple([]*model.Post{&p1})
require.NoError(t, err)
require.Equal(t, -1, errIdx)
defer ss.Post().PermanentDeleteByChannel(p1.ChannelId)
defer ss.PostPersistentNotification().Delete([]string{p1.Id})
// Update from 0 value
now := model.GetTimeForMillis(model.GetMillis())
delta := 2 * time.Second
err = ss.PostPersistentNotification().UpdateLastActivity([]string{p1.Id})
require.NoError(t, err)
pn, err := ss.PostPersistentNotification().Get(model.GetPersistentNotificationsPostsParams{
MaxTime: model.GetMillisForTime(now.Add(delta)),
MaxSentCount: 60,
})
require.NoError(t, err)
require.Len(t, pn, 1)
assert.WithinDuration(t, now, model.GetTimeForMillis(pn[0].LastSentAt), delta)
time.Sleep(time.Second)
// Update from non-zero value
now = model.GetTimeForMillis(model.GetMillis())
delta = 2 * time.Second
err = ss.PostPersistentNotification().UpdateLastActivity([]string{p1.Id})
require.NoError(t, err)
pn, err = ss.PostPersistentNotification().Get(model.GetPersistentNotificationsPostsParams{
MaxTime: model.GetMillisForTime(now.Add(delta)),
MaxSentCount: 60,
})
require.NoError(t, err)
require.Len(t, pn, 1)
assert.WithinDuration(t, now, model.GetTimeForMillis(pn[0].LastSentAt), delta)
}
func testPostPersistentNotificationStoreDelete(t *testing.T, ss store.Store) {
t.Run("Delete", func(t *testing.T) {
p1 := model.Post{}
p1.ChannelId = model.NewId()
p1.UserId = model.NewId()
p1.Message = NewTestId()
p1.CreateAt = 10
p1.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString("important"),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
p2 := model.Post{}
p2.ChannelId = p1.ChannelId
p2.UserId = model.NewId()
p2.Message = NewTestId()
p2.CreateAt = 20
p2.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString(model.PostPriorityUrgent),
RequestedAck: model.NewBool(true),
PersistentNotifications: model.NewBool(true),
},
}
p3 := model.Post{}
p3.ChannelId = p1.ChannelId
p3.UserId = model.NewId()
p3.Message = NewTestId()
p3.CreateAt = 30
p3.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString(model.PostPriorityUrgent),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
_, errIdx, err := ss.Post().SaveMultiple([]*model.Post{&p1, &p2, &p3})
require.NoError(t, err)
require.Equal(t, -1, errIdx)
defer ss.Post().PermanentDeleteByChannel(p1.ChannelId)
defer ss.PostPersistentNotification().Delete([]string{p1.Id, p2.Id, p3.Id})
err = ss.PostPersistentNotification().Delete([]string{p1.Id, p3.Id})
require.NoError(t, err)
pn, err := ss.PostPersistentNotification().Get(model.GetPersistentNotificationsPostsParams{
MaxTime: 100,
MaxSentCount: 6,
PerPage: 20,
})
require.NoError(t, err)
require.Len(t, pn, 1)
assert.Equal(t, p2.Id, pn[0].PostId)
})
t.Run("Delete By Channel", func(t *testing.T) {
p1 := model.Post{}
p1.ChannelId = model.NewId()
p1.UserId = model.NewId()
p1.Message = NewTestId()
p1.CreateAt = 10
p1.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString("important"),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
p2 := model.Post{}
p2.ChannelId = p1.ChannelId
p2.UserId = model.NewId()
p2.Message = NewTestId()
p2.CreateAt = 20
p2.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString(model.PostPriorityUrgent),
RequestedAck: model.NewBool(true),
PersistentNotifications: model.NewBool(true),
},
}
p3 := model.Post{}
p3.ChannelId = p1.ChannelId
p3.UserId = model.NewId()
p3.Message = NewTestId()
p3.CreateAt = 30
p3.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString(model.PostPriorityUrgent),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
p4 := model.Post{}
p4.ChannelId = model.NewId()
p4.UserId = model.NewId()
p4.Message = NewTestId()
p4.CreateAt = 40
p4.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString("important"),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
p5 := model.Post{}
p5.ChannelId = p4.ChannelId
p5.UserId = model.NewId()
p5.Message = NewTestId()
p5.CreateAt = 50
p5.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString("important"),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
_, errIdx, err := ss.Post().SaveMultiple([]*model.Post{&p1, &p2, &p3, &p4, &p5})
require.NoError(t, err)
require.Equal(t, -1, errIdx)
defer ss.Post().PermanentDeleteByChannel(p1.ChannelId)
defer ss.Post().PermanentDeleteByChannel(p4.ChannelId)
defer ss.PostPersistentNotification().Delete([]string{p1.Id, p2.Id, p3.Id, p4.Id, p5.Id})
err = ss.PostPersistentNotification().DeleteByChannel([]string{p1.ChannelId})
require.NoError(t, err)
pn, err := ss.PostPersistentNotification().Get(model.GetPersistentNotificationsPostsParams{
MaxTime: 100,
MaxSentCount: 6,
PerPage: 20,
})
require.NoError(t, err)
require.Len(t, pn, 2)
assert.ElementsMatch(t, []string{p4.Id, p5.Id}, []string{pn[0].PostId, pn[1].PostId})
})
t.Run("Delete By Team", func(t *testing.T) {
t1 := &model.Team{DisplayName: "t1", Name: NewTestId(), Email: MakeEmail(), Type: model.TeamOpen}
_, err := ss.Team().Save(t1)
require.NoError(t, err)
t2 := &model.Team{DisplayName: "t2", Name: NewTestId(), Email: MakeEmail(), Type: model.TeamOpen}
_, err = ss.Team().Save(t2)
require.NoError(t, err)
c1 := &model.Channel{TeamId: t1.Id, Name: model.NewId(), DisplayName: "c1", Type: model.ChannelTypeOpen}
_, err = ss.Channel().Save(c1, -1)
require.NoError(t, err)
c2 := &model.Channel{TeamId: t1.Id, Name: model.NewId(), DisplayName: "c2", Type: model.ChannelTypeOpen}
_, err = ss.Channel().Save(c2, -1)
require.NoError(t, err)
c3 := &model.Channel{TeamId: t2.Id, Name: model.NewId(), DisplayName: "c1", Type: model.ChannelTypeOpen}
_, err = ss.Channel().Save(c3, -1)
require.NoError(t, err)
p1 := model.Post{}
p1.ChannelId = c1.Id
p1.UserId = model.NewId()
p1.Message = NewTestId()
p1.CreateAt = 10
p1.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString("important"),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
p2 := model.Post{}
p2.ChannelId = p1.ChannelId
p2.UserId = model.NewId()
p2.Message = NewTestId()
p2.CreateAt = 20
p2.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString(model.PostPriorityUrgent),
RequestedAck: model.NewBool(true),
PersistentNotifications: model.NewBool(true),
},
}
p3 := model.Post{}
p3.ChannelId = c2.Id
p3.UserId = model.NewId()
p3.Message = NewTestId()
p3.CreateAt = 30
p3.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString(model.PostPriorityUrgent),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
p4 := model.Post{}
p4.ChannelId = c3.Id
p4.UserId = model.NewId()
p4.Message = NewTestId()
p4.CreateAt = 40
p4.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString("important"),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
p5 := model.Post{}
p5.ChannelId = p4.ChannelId
p5.UserId = model.NewId()
p5.Message = NewTestId()
p5.CreateAt = 50
p5.Metadata = &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString("important"),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
},
}
_, errIdx, err := ss.Post().SaveMultiple([]*model.Post{&p1, &p2, &p3, &p4, &p5})
require.NoError(t, err)
require.Equal(t, -1, errIdx)
defer ss.Post().PermanentDeleteByChannel(c1.Id)
defer ss.Post().PermanentDeleteByChannel(c2.Id)
defer ss.Post().PermanentDeleteByChannel(c3.Id)
defer ss.Channel().PermanentDeleteByTeam(t1.Id)
defer ss.Channel().PermanentDeleteByTeam(t2.Id)
defer ss.Team().PermanentDelete(t1.Id)
defer ss.Team().PermanentDelete(t2.Id)
defer ss.PostPersistentNotification().Delete([]string{p1.Id, p2.Id, p3.Id, p4.Id, p5.Id})
err = ss.PostPersistentNotification().DeleteByTeam([]string{t1.Id})
require.NoError(t, err)
pn, err := ss.PostPersistentNotification().Get(model.GetPersistentNotificationsPostsParams{
MaxTime: 100,
MaxSentCount: 6,
PerPage: 20,
})
require.NoError(t, err)
require.Len(t, pn, 2)
assert.ElementsMatch(t, []string{p4.Id, p5.Id}, []string{pn[0].PostId, pn[1].PostId})
})
}

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

@@ -17,49 +17,50 @@ import (
// Store can be used to provide mock stores for testing.
type Store struct {
TeamStore mocks.TeamStore
ChannelStore mocks.ChannelStore
PostStore mocks.PostStore
UserStore mocks.UserStore
RetentionPolicyStore mocks.RetentionPolicyStore
BotStore mocks.BotStore
AuditStore mocks.AuditStore
ClusterDiscoveryStore mocks.ClusterDiscoveryStore
RemoteClusterStore mocks.RemoteClusterStore
ComplianceStore mocks.ComplianceStore
SessionStore mocks.SessionStore
OAuthStore mocks.OAuthStore
SystemStore mocks.SystemStore
WebhookStore mocks.WebhookStore
CommandStore mocks.CommandStore
CommandWebhookStore mocks.CommandWebhookStore
PreferenceStore mocks.PreferenceStore
LicenseStore mocks.LicenseStore
TokenStore mocks.TokenStore
EmojiStore mocks.EmojiStore
ThreadStore mocks.ThreadStore
StatusStore mocks.StatusStore
FileInfoStore mocks.FileInfoStore
UploadSessionStore mocks.UploadSessionStore
ReactionStore mocks.ReactionStore
JobStore mocks.JobStore
UserAccessTokenStore mocks.UserAccessTokenStore
PluginStore mocks.PluginStore
ChannelMemberHistoryStore mocks.ChannelMemberHistoryStore
RoleStore mocks.RoleStore
SchemeStore mocks.SchemeStore
TermsOfServiceStore mocks.TermsOfServiceStore
GroupStore mocks.GroupStore
UserTermsOfServiceStore mocks.UserTermsOfServiceStore
LinkMetadataStore mocks.LinkMetadataStore
SharedChannelStore mocks.SharedChannelStore
ProductNoticesStore mocks.ProductNoticesStore
DraftStore mocks.DraftStore
context context.Context
NotifyAdminStore mocks.NotifyAdminStore
PostPriorityStore mocks.PostPriorityStore
PostAcknowledgementStore mocks.PostAcknowledgementStore
TrueUpReviewStore mocks.TrueUpReviewStore
TeamStore mocks.TeamStore
ChannelStore mocks.ChannelStore
PostStore mocks.PostStore
UserStore mocks.UserStore
RetentionPolicyStore mocks.RetentionPolicyStore
BotStore mocks.BotStore
AuditStore mocks.AuditStore
ClusterDiscoveryStore mocks.ClusterDiscoveryStore
RemoteClusterStore mocks.RemoteClusterStore
ComplianceStore mocks.ComplianceStore
SessionStore mocks.SessionStore
OAuthStore mocks.OAuthStore
SystemStore mocks.SystemStore
WebhookStore mocks.WebhookStore
CommandStore mocks.CommandStore
CommandWebhookStore mocks.CommandWebhookStore
PreferenceStore mocks.PreferenceStore
LicenseStore mocks.LicenseStore
TokenStore mocks.TokenStore
EmojiStore mocks.EmojiStore
ThreadStore mocks.ThreadStore
StatusStore mocks.StatusStore
FileInfoStore mocks.FileInfoStore
UploadSessionStore mocks.UploadSessionStore
ReactionStore mocks.ReactionStore
JobStore mocks.JobStore
UserAccessTokenStore mocks.UserAccessTokenStore
PluginStore mocks.PluginStore
ChannelMemberHistoryStore mocks.ChannelMemberHistoryStore
RoleStore mocks.RoleStore
SchemeStore mocks.SchemeStore
TermsOfServiceStore mocks.TermsOfServiceStore
GroupStore mocks.GroupStore
UserTermsOfServiceStore mocks.UserTermsOfServiceStore
LinkMetadataStore mocks.LinkMetadataStore
SharedChannelStore mocks.SharedChannelStore
ProductNoticesStore mocks.ProductNoticesStore
DraftStore mocks.DraftStore
context context.Context
NotifyAdminStore mocks.NotifyAdminStore
PostPriorityStore mocks.PostPriorityStore
PostAcknowledgementStore mocks.PostAcknowledgementStore
PostPersistentNotificationStore mocks.PostPersistentNotificationStore
TrueUpReviewStore mocks.TrueUpReviewStore
}
func (s *Store) SetContext(context context.Context) { s.context = context }
@@ -110,6 +111,9 @@ func (s *Store) PostPriority() store.PostPriorityStore { return &s.PostPriorit
func (s *Store) PostAcknowledgement() store.PostAcknowledgementStore {
return &s.PostAcknowledgementStore
}
func (s *Store) PostPersistentNotification() store.PostPersistentNotificationStore {
return &s.PostPersistentNotificationStore
}
func (s *Store) MarkSystemRanUnitTests() { /* do nothing */ }
func (s *Store) Close() { /* do nothing */ }
func (s *Store) LockToMaster() { /* do nothing */ }
@@ -171,5 +175,6 @@ func (s *Store) AssertExpectations(t mock.TestingT) bool {
&s.NotifyAdminStore,
&s.PostPriorityStore,
&s.PostAcknowledgementStore,
&s.PostPersistentNotificationStore,
)
}