MM-28247 Threads metadata table (#15571)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
10961f9500
Коммит
595248b10e
@@ -782,6 +782,22 @@ func (_m *SqlStore) TermsOfService() store.TermsOfServiceStore {
|
||||
return r0
|
||||
}
|
||||
|
||||
// Thread provides a mock function with given fields:
|
||||
func (_m *SqlStore) Thread() store.ThreadStore {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 store.ThreadStore
|
||||
if rf, ok := ret.Get(0).(func() store.ThreadStore); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.ThreadStore)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Token provides a mock function with given fields:
|
||||
func (_m *SqlStore) Token() store.TokenStore {
|
||||
ret := _m.Called()
|
||||
|
||||
@@ -549,6 +549,22 @@ func (_m *Store) TermsOfService() store.TermsOfServiceStore {
|
||||
return r0
|
||||
}
|
||||
|
||||
// Thread provides a mock function with given fields:
|
||||
func (_m *Store) Thread() store.ThreadStore {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 store.ThreadStore
|
||||
if rf, ok := ret.Get(0).(func() store.ThreadStore); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.ThreadStore)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Token provides a mock function with given fields:
|
||||
func (_m *Store) Token() store.TokenStore {
|
||||
ret := _m.Called()
|
||||
|
||||
128
store/storetest/mocks/ThreadStore.go
Обычный файл
128
store/storetest/mocks/ThreadStore.go
Обычный файл
@@ -0,0 +1,128 @@
|
||||
// Code generated by mockery v1.0.0. DO NOT EDIT.
|
||||
|
||||
// Regenerate this file using `make store-mocks`.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
model "github.com/mattermost/mattermost-server/v5/model"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// ThreadStore is an autogenerated mock type for the ThreadStore type
|
||||
type ThreadStore struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Delete provides a mock function with given fields: postId
|
||||
func (_m *ThreadStore) Delete(postId string) error {
|
||||
ret := _m.Called(postId)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(postId)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Get provides a mock function with given fields: id
|
||||
func (_m *ThreadStore) Get(id string) (*model.Thread, error) {
|
||||
ret := _m.Called(id)
|
||||
|
||||
var r0 *model.Thread
|
||||
if rf, ok := ret.Get(0).(func(string) *model.Thread); ok {
|
||||
r0 = rf(id)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Thread)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(id)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Save provides a mock function with given fields: thread
|
||||
func (_m *ThreadStore) Save(thread *model.Thread) (*model.Thread, error) {
|
||||
ret := _m.Called(thread)
|
||||
|
||||
var r0 *model.Thread
|
||||
if rf, ok := ret.Get(0).(func(*model.Thread) *model.Thread); ok {
|
||||
r0 = rf(thread)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Thread)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*model.Thread) error); ok {
|
||||
r1 = rf(thread)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SaveMultiple provides a mock function with given fields: thread
|
||||
func (_m *ThreadStore) SaveMultiple(thread []*model.Thread) ([]*model.Thread, int, error) {
|
||||
ret := _m.Called(thread)
|
||||
|
||||
var r0 []*model.Thread
|
||||
if rf, ok := ret.Get(0).(func([]*model.Thread) []*model.Thread); ok {
|
||||
r0 = rf(thread)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Thread)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 int
|
||||
if rf, ok := ret.Get(1).(func([]*model.Thread) int); ok {
|
||||
r1 = rf(thread)
|
||||
} else {
|
||||
r1 = ret.Get(1).(int)
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func([]*model.Thread) error); ok {
|
||||
r2 = rf(thread)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// Update provides a mock function with given fields: thread
|
||||
func (_m *ThreadStore) Update(thread *model.Thread) (*model.Thread, error) {
|
||||
ret := _m.Called(thread)
|
||||
|
||||
var r0 *model.Thread
|
||||
if rf, ok := ret.Get(0).(func(*model.Thread) *model.Thread); ok {
|
||||
r0 = rf(thread)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Thread)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(*model.Thread) error); ok {
|
||||
r1 = rf(thread)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
@@ -33,6 +33,7 @@ type Store struct {
|
||||
LicenseStore mocks.LicenseStore
|
||||
TokenStore mocks.TokenStore
|
||||
EmojiStore mocks.EmojiStore
|
||||
ThreadStore mocks.ThreadStore
|
||||
StatusStore mocks.StatusStore
|
||||
FileInfoStore mocks.FileInfoStore
|
||||
UploadSessionStore mocks.UploadSessionStore
|
||||
@@ -72,6 +73,7 @@ func (s *Store) Preference() store.PreferenceStore { return &s.P
|
||||
func (s *Store) License() store.LicenseStore { return &s.LicenseStore }
|
||||
func (s *Store) Token() store.TokenStore { return &s.TokenStore }
|
||||
func (s *Store) Emoji() store.EmojiStore { return &s.EmojiStore }
|
||||
func (s *Store) Thread() store.ThreadStore { return &s.ThreadStore }
|
||||
func (s *Store) Status() store.StatusStore { return &s.StatusStore }
|
||||
func (s *Store) FileInfo() store.FileInfoStore { return &s.FileInfoStore }
|
||||
func (s *Store) UploadSession() store.UploadSessionStore { return &s.UploadSessionStore }
|
||||
@@ -133,6 +135,7 @@ func (s *Store) AssertExpectations(t mock.TestingT) bool {
|
||||
&s.PluginStore,
|
||||
&s.RoleStore,
|
||||
&s.SchemeStore,
|
||||
&s.ThreadStore,
|
||||
&s.ProductNoticesStore,
|
||||
)
|
||||
}
|
||||
|
||||
200
store/storetest/thread_store.go
Обычный файл
200
store/storetest/thread_store.go
Обычный файл
@@ -0,0 +1,200 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package storetest
|
||||
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/store"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestThreadStore(t *testing.T, ss store.Store, s SqlSupplier) {
|
||||
t.Run("ThreadStorePopulation", func(t *testing.T) { testThreadStorePopulation(t, ss) })
|
||||
}
|
||||
|
||||
func testThreadStorePopulation(t *testing.T, ss store.Store) {
|
||||
makeSomePosts := func() []*model.Post {
|
||||
o1 := model.Post{}
|
||||
o1.ChannelId = model.NewId()
|
||||
o1.UserId = model.NewId()
|
||||
o1.RootId = model.NewId()
|
||||
o1.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
o2 := model.Post{}
|
||||
o2.ChannelId = model.NewId()
|
||||
o2.UserId = model.NewId()
|
||||
o2.RootId = o1.RootId
|
||||
o2.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
o3 := model.Post{}
|
||||
o3.ChannelId = model.NewId()
|
||||
o3.UserId = model.NewId()
|
||||
o3.RootId = model.NewId()
|
||||
o3.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
o4 := model.Post{}
|
||||
o4.ChannelId = model.NewId()
|
||||
o4.UserId = model.NewId()
|
||||
o4.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
newPosts, errIdx, err := ss.Post().SaveMultiple([]*model.Post{&o1, &o2, &o3, &o4})
|
||||
require.Nil(t, err, "couldn't save item")
|
||||
require.Equal(t, -1, errIdx)
|
||||
require.Len(t, newPosts, 4)
|
||||
require.Equal(t, int64(2), newPosts[0].ReplyCount)
|
||||
require.Equal(t, int64(2), newPosts[1].ReplyCount)
|
||||
require.Equal(t, int64(1), newPosts[2].ReplyCount)
|
||||
require.Equal(t, int64(0), newPosts[3].ReplyCount)
|
||||
return newPosts
|
||||
}
|
||||
t.Run("Save replies creates a thread", func(t *testing.T) {
|
||||
newPosts := makeSomePosts()
|
||||
thread, err := ss.Thread().Get(newPosts[0].RootId)
|
||||
require.Nil(t, err, "couldn't get thread")
|
||||
require.NotNil(t, thread)
|
||||
require.Equal(t, int64(2), thread.ReplyCount)
|
||||
require.ElementsMatch(t, model.StringArray{newPosts[0].UserId, newPosts[1].UserId}, thread.Participants)
|
||||
|
||||
o5 := model.Post{}
|
||||
o5.ChannelId = model.NewId()
|
||||
o5.UserId = model.NewId()
|
||||
o5.RootId = newPosts[0].RootId
|
||||
o5.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
_, _, err = ss.Post().SaveMultiple([]*model.Post{&o5})
|
||||
require.Nil(t, err, "couldn't save item")
|
||||
|
||||
thread, err = ss.Thread().Get(newPosts[0].RootId)
|
||||
require.Nil(t, err, "couldn't get thread")
|
||||
require.NotNil(t, thread)
|
||||
require.Equal(t, int64(3), thread.ReplyCount)
|
||||
require.ElementsMatch(t, model.StringArray{newPosts[0].UserId, newPosts[1].UserId, o5.UserId}, thread.Participants)
|
||||
})
|
||||
|
||||
t.Run("Delete a reply updates count on a thread", func(t *testing.T) {
|
||||
newPosts := makeSomePosts()
|
||||
thread, err := ss.Thread().Get(newPosts[0].RootId)
|
||||
require.Nil(t, err, "couldn't get thread")
|
||||
require.NotNil(t, thread)
|
||||
require.Equal(t, int64(2), thread.ReplyCount)
|
||||
require.ElementsMatch(t, model.StringArray{newPosts[0].UserId, newPosts[1].UserId}, thread.Participants)
|
||||
|
||||
err = ss.Post().Delete(newPosts[1].Id, 1234, model.NewId())
|
||||
require.Nil(t, err, "couldn't delete post")
|
||||
|
||||
thread, err = ss.Thread().Get(newPosts[0].RootId)
|
||||
require.Nil(t, err, "couldn't get thread")
|
||||
require.NotNil(t, thread)
|
||||
require.Equal(t, int64(1), thread.ReplyCount)
|
||||
require.ElementsMatch(t, model.StringArray{newPosts[0].UserId}, thread.Participants)
|
||||
})
|
||||
|
||||
t.Run("Update reply should update the UpdateAt of the thread", func(t *testing.T) {
|
||||
rootPost := model.Post{}
|
||||
rootPost.RootId = model.NewId()
|
||||
rootPost.ChannelId = model.NewId()
|
||||
rootPost.UserId = model.NewId()
|
||||
rootPost.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
replyPost := model.Post{}
|
||||
replyPost.ChannelId = rootPost.ChannelId
|
||||
replyPost.UserId = model.NewId()
|
||||
replyPost.Message = "zz" + model.NewId() + "b"
|
||||
replyPost.RootId = rootPost.RootId
|
||||
|
||||
newPosts, _, err := ss.Post().SaveMultiple([]*model.Post{&rootPost, &replyPost})
|
||||
require.Nil(t, err)
|
||||
|
||||
thread1, err := ss.Thread().Get(newPosts[0].RootId)
|
||||
require.Nil(t, err)
|
||||
|
||||
rrootPost, err := ss.Post().GetSingle(rootPost.Id)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, rrootPost.UpdateAt, rootPost.UpdateAt)
|
||||
|
||||
replyPost2 := model.Post{}
|
||||
replyPost2.ChannelId = rootPost.ChannelId
|
||||
replyPost2.UserId = model.NewId()
|
||||
replyPost2.Message = "zz" + model.NewId() + "b"
|
||||
replyPost2.RootId = rootPost.Id
|
||||
|
||||
replyPost3 := model.Post{}
|
||||
replyPost3.ChannelId = rootPost.ChannelId
|
||||
replyPost3.UserId = model.NewId()
|
||||
replyPost3.Message = "zz" + model.NewId() + "b"
|
||||
replyPost3.RootId = rootPost.Id
|
||||
|
||||
_, _, err = ss.Post().SaveMultiple([]*model.Post{&replyPost2, &replyPost3})
|
||||
require.Nil(t, err)
|
||||
|
||||
rrootPost2, err := ss.Post().GetSingle(rootPost.Id)
|
||||
require.Nil(t, err)
|
||||
require.Greater(t, rrootPost2.UpdateAt, rrootPost.UpdateAt)
|
||||
|
||||
thread2, err := ss.Thread().Get(rootPost.Id)
|
||||
require.Nil(t, err)
|
||||
require.Greater(t, thread2.LastReplyAt, thread1.LastReplyAt)
|
||||
})
|
||||
|
||||
t.Run("Deleting reply should update the thread", func(t *testing.T) {
|
||||
rootPost := model.Post{}
|
||||
rootPost.RootId = model.NewId()
|
||||
rootPost.ChannelId = model.NewId()
|
||||
rootPost.UserId = model.NewId()
|
||||
rootPost.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
replyPost := model.Post{}
|
||||
replyPost.ChannelId = rootPost.ChannelId
|
||||
replyPost.UserId = model.NewId()
|
||||
replyPost.Message = "zz" + model.NewId() + "b"
|
||||
replyPost.RootId = rootPost.RootId
|
||||
|
||||
newPosts, _, err := ss.Post().SaveMultiple([]*model.Post{&rootPost, &replyPost})
|
||||
require.Nil(t, err)
|
||||
|
||||
thread1, err := ss.Thread().Get(newPosts[0].RootId)
|
||||
require.Nil(t, err)
|
||||
require.EqualValues(t, thread1.ReplyCount, 2)
|
||||
require.Len(t, thread1.Participants, 2)
|
||||
|
||||
err = ss.Post().Delete(replyPost.Id, 123, model.NewId())
|
||||
require.Nil(t, err)
|
||||
|
||||
thread2, err := ss.Thread().Get(rootPost.RootId)
|
||||
require.Nil(t, err)
|
||||
require.EqualValues(t, thread2.ReplyCount, 1)
|
||||
require.Len(t, thread2.Participants, 1)
|
||||
})
|
||||
|
||||
t.Run("Deleting root post should delete the thread", func(t *testing.T) {
|
||||
rootPost := model.Post{}
|
||||
rootPost.ChannelId = model.NewId()
|
||||
rootPost.UserId = model.NewId()
|
||||
rootPost.Message = "zz" + model.NewId() + "b"
|
||||
|
||||
newPosts1, _, err := ss.Post().SaveMultiple([]*model.Post{&rootPost})
|
||||
require.Nil(t, err)
|
||||
|
||||
replyPost := model.Post{}
|
||||
replyPost.ChannelId = rootPost.ChannelId
|
||||
replyPost.UserId = model.NewId()
|
||||
replyPost.Message = "zz" + model.NewId() + "b"
|
||||
replyPost.RootId = newPosts1[0].Id
|
||||
|
||||
_, _, err = ss.Post().SaveMultiple([]*model.Post{&replyPost})
|
||||
require.Nil(t, err)
|
||||
|
||||
thread1, err := ss.Thread().Get(newPosts1[0].Id)
|
||||
require.Nil(t, err)
|
||||
require.EqualValues(t, thread1.ReplyCount, 1)
|
||||
require.Len(t, thread1.Participants, 1)
|
||||
|
||||
err = ss.Post().Delete(rootPost.Id, 123, model.NewId())
|
||||
require.Nil(t, err)
|
||||
|
||||
thread2, _ := ss.Thread().Get(rootPost.Id)
|
||||
require.Nil(t, thread2)
|
||||
})
|
||||
}
|
||||
Ссылка в новой задаче
Block a user