Prep for MS Teams plugin API (#25565)
* - columns added to ShareChannelRemotes: lastpostcreateat, lastpostupdateat - SyncMsg and SyncResponse moved to `model` package - field added to RemoteCluster struct: PluginID * sync new posts before updated posts to ensure post order in MS Teams * add plugid to remoteclusters table and store * don't sync history by default
Этот коммит содержится в:
@@ -58,7 +58,8 @@ func TestPostStore(t *testing.T, rctx request.CTX, ss store.Store, s SqlStore) {
|
||||
t.Run("GetDirectPostParentsForExportAfterBatched", func(t *testing.T) { testPostStoreGetDirectPostParentsForExportAfterBatched(t, rctx, ss, s) })
|
||||
t.Run("GetForThread", func(t *testing.T) { testPostStoreGetForThread(t, rctx, ss) })
|
||||
t.Run("HasAutoResponsePostByUserSince", func(t *testing.T) { testHasAutoResponsePostByUserSince(t, rctx, ss) })
|
||||
t.Run("GetPostsSinceForSync", func(t *testing.T) { testGetPostsSinceForSync(t, rctx, ss, s) })
|
||||
t.Run("GetPostsSinceUpdateForSync", func(t *testing.T) { testGetPostsSinceUpdateForSync(t, rctx, ss, s) })
|
||||
t.Run("GetPostsSinceCreateForSync", func(t *testing.T) { testGetPostsSinceCreateForSync(t, rctx, ss, s) })
|
||||
t.Run("SetPostReminder", func(t *testing.T) { testSetPostReminder(t, rctx, ss, s) })
|
||||
t.Run("GetPostReminders", func(t *testing.T) { testGetPostReminders(t, rctx, ss, s) })
|
||||
t.Run("GetPostReminderMetadata", func(t *testing.T) { testGetPostReminderMetadata(t, rctx, ss, s) })
|
||||
@@ -4655,7 +4656,7 @@ func testHasAutoResponsePostByUserSince(t *testing.T, rctx request.CTX, ss store
|
||||
})
|
||||
}
|
||||
|
||||
func testGetPostsSinceForSync(t *testing.T, rctx request.CTX, ss store.Store, s SqlStore) {
|
||||
func testGetPostsSinceUpdateForSync(t *testing.T, rctx request.CTX, ss store.Store, s SqlStore) {
|
||||
// create some posts.
|
||||
channelID := model.NewId()
|
||||
remoteID := model.NewString(model.NewId())
|
||||
@@ -4758,6 +4759,113 @@ func testGetPostsSinceForSync(t *testing.T, rctx request.CTX, ss store.Store, s
|
||||
})
|
||||
}
|
||||
|
||||
func testGetPostsSinceCreateForSync(t *testing.T, rctx request.CTX, ss store.Store, s SqlStore) {
|
||||
// create some posts.
|
||||
channelID := model.NewId()
|
||||
remoteID := model.NewString(model.NewId())
|
||||
first := model.GetMillis()
|
||||
|
||||
data := []*model.Post{
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 0"},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 1"},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 2"},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 3", RemoteId: remoteID},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 4", RemoteId: remoteID},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 5", RemoteId: remoteID},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 6", RemoteId: remoteID},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 7"},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 8", DeleteAt: model.GetMillis()},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 9", DeleteAt: model.GetMillis()},
|
||||
}
|
||||
|
||||
for i, p := range data {
|
||||
p.CreateAt = first + (int64(i) * 300000)
|
||||
if p.RemoteId == nil {
|
||||
p.RemoteId = model.NewString(model.NewId())
|
||||
}
|
||||
_, err := ss.Post().Save(p)
|
||||
require.NoError(t, err, "couldn't save post")
|
||||
}
|
||||
|
||||
t.Run("Invalid channel id", func(t *testing.T) {
|
||||
opt := model.GetPostsSinceForSyncOptions{
|
||||
ChannelId: model.NewId(),
|
||||
SinceCreateAt: true,
|
||||
}
|
||||
cursor := model.GetPostsSinceForSyncCursor{}
|
||||
posts, cursorOut, err := ss.Post().GetPostsSinceForSync(opt, cursor, 100)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, posts, "should return zero posts")
|
||||
require.Equal(t, cursor, cursorOut)
|
||||
})
|
||||
|
||||
t.Run("Get by channel, exclude remotes, exclude deleted", func(t *testing.T) {
|
||||
opt := model.GetPostsSinceForSyncOptions{
|
||||
ChannelId: channelID,
|
||||
ExcludeRemoteId: *remoteID,
|
||||
SinceCreateAt: true,
|
||||
}
|
||||
cursor := model.GetPostsSinceForSyncCursor{}
|
||||
posts, _, err := ss.Post().GetPostsSinceForSync(opt, cursor, 100)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.ElementsMatch(t, getPostIds(data[0:3], data[7]), getPostIds(posts))
|
||||
})
|
||||
|
||||
t.Run("Include deleted", func(t *testing.T) {
|
||||
opt := model.GetPostsSinceForSyncOptions{
|
||||
ChannelId: channelID,
|
||||
IncludeDeleted: true,
|
||||
SinceCreateAt: true,
|
||||
}
|
||||
cursor := model.GetPostsSinceForSyncCursor{}
|
||||
posts, _, err := ss.Post().GetPostsSinceForSync(opt, cursor, 100)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.ElementsMatch(t, getPostIds(data), getPostIds(posts))
|
||||
})
|
||||
|
||||
t.Run("Limit and cursor", func(t *testing.T) {
|
||||
opt := model.GetPostsSinceForSyncOptions{
|
||||
ChannelId: channelID,
|
||||
SinceCreateAt: true,
|
||||
}
|
||||
cursor := model.GetPostsSinceForSyncCursor{}
|
||||
posts1, cursor, err := ss.Post().GetPostsSinceForSync(opt, cursor, 5)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, posts1, 5, "should get 5 posts")
|
||||
|
||||
posts2, _, err := ss.Post().GetPostsSinceForSync(opt, cursor, 5)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, posts2, 3, "should get 3 posts")
|
||||
|
||||
require.ElementsMatch(t, getPostIds(data[0:8]), getPostIds(posts1, posts2...))
|
||||
})
|
||||
|
||||
t.Run("CreateAt collisions", func(t *testing.T) {
|
||||
// this test requires all the CreateAt timestamps to be the same.
|
||||
result, err := s.GetMasterX().Exec("UPDATE Posts SET CreateAt = ?", model.GetMillis())
|
||||
require.NoError(t, err)
|
||||
rows, err := result.RowsAffected()
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, rows, int64(0))
|
||||
|
||||
opt := model.GetPostsSinceForSyncOptions{
|
||||
ChannelId: channelID,
|
||||
}
|
||||
cursor := model.GetPostsSinceForSyncCursor{}
|
||||
posts1, cursor, err := ss.Post().GetPostsSinceForSync(opt, cursor, 5)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, posts1, 5, "should get 5 posts")
|
||||
|
||||
posts2, _, err := ss.Post().GetPostsSinceForSync(opt, cursor, 5)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, posts2, 3, "should get 3 posts")
|
||||
|
||||
require.ElementsMatch(t, getPostIds(data[0:8]), getPostIds(posts1, posts2...))
|
||||
})
|
||||
}
|
||||
|
||||
func testSetPostReminder(t *testing.T, rctx request.CTX, ss store.Store, s SqlStore) {
|
||||
// Basic
|
||||
userID := NewTestId()
|
||||
|
||||
@@ -15,6 +15,10 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
testPluginID = "com.sample.blap"
|
||||
)
|
||||
|
||||
func TestRemoteClusterStore(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
t.Run("RemoteClusterGetAllInChannel", func(t *testing.T) { testRemoteClusterGetAllInChannel(t, rctx, ss) })
|
||||
t.Run("RemoteClusterGetAllNotInChannel", func(t *testing.T) { testRemoteClusterGetAllNotInChannel(t, rctx, ss) })
|
||||
@@ -89,6 +93,7 @@ func testRemoteClusterGet(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
Name: "shortlived_remote_2",
|
||||
SiteURL: "nowhere.com",
|
||||
CreatorId: model.NewId(),
|
||||
PluginID: testPluginID,
|
||||
}
|
||||
rcSaved, err := ss.RemoteCluster().Save(rc)
|
||||
require.NoError(t, err)
|
||||
@@ -96,6 +101,7 @@ func testRemoteClusterGet(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
rcGet, err := ss.RemoteCluster().Get(rcSaved.RemoteId)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, rcSaved.RemoteId, rcGet.RemoteId)
|
||||
require.Equal(t, testPluginID, rcGet.PluginID)
|
||||
})
|
||||
|
||||
t.Run("Get not found", func(t *testing.T) {
|
||||
@@ -237,8 +243,8 @@ func testRemoteClusterGetAllInChannel(t *testing.T, rctx request.CTX, ss store.S
|
||||
|
||||
// Create some remote clusters
|
||||
rcData := []*model.RemoteCluster{
|
||||
{Name: "AAAA_Inc", CreatorId: userId, SiteURL: "aaaa.com", RemoteId: model.NewId(), LastPingAt: now},
|
||||
{Name: "BBBB_Inc", CreatorId: userId, SiteURL: "bbbb.com", RemoteId: model.NewId(), LastPingAt: 0},
|
||||
{Name: "AAAA_Inc", CreatorId: userId, SiteURL: "aaaa.com", RemoteId: model.NewId(), LastPingAt: now, PluginID: testPluginID},
|
||||
{Name: "BBBB_Inc", CreatorId: userId, SiteURL: "bbbb.com", RemoteId: model.NewId(), LastPingAt: 0, PluginID: testPluginID},
|
||||
{Name: "CCCC_Inc", CreatorId: userId, SiteURL: "cccc.com", RemoteId: model.NewId(), LastPingAt: now},
|
||||
{Name: "DDDD_Inc", CreatorId: userId, SiteURL: "dddd.com", RemoteId: model.NewId(), LastPingAt: now},
|
||||
{Name: "EEEE_Inc", CreatorId: userId, SiteURL: "eeee.com", RemoteId: model.NewId(), LastPingAt: 0},
|
||||
@@ -270,6 +276,8 @@ func testRemoteClusterGetAllInChannel(t *testing.T, rctx request.CTX, ss store.S
|
||||
require.Len(t, list, 2, "channel 1 should have 2 remote clusters")
|
||||
ids := getIds(list)
|
||||
require.ElementsMatch(t, []string{rcData[0].RemoteId, rcData[1].RemoteId}, ids)
|
||||
require.Equal(t, testPluginID, rcData[0].PluginID)
|
||||
require.Equal(t, testPluginID, rcData[1].PluginID)
|
||||
})
|
||||
|
||||
t.Run("Channel 1 online only", func(t *testing.T) {
|
||||
|
||||
@@ -765,28 +765,52 @@ func testUpdateSharedChannelRemoteCursor(t *testing.T, rctx request.CTX, ss stor
|
||||
remoteSaved, err := ss.SharedChannel().SaveRemote(remote)
|
||||
require.NoError(t, err, "couldn't save remote", err)
|
||||
|
||||
future := model.GetMillis() + 3600000 // 1 hour in the future
|
||||
postID := model.NewId()
|
||||
futureCreateAt := model.GetMillis() + 3600000 // 1 hour in the future
|
||||
postCreateID := model.NewId()
|
||||
|
||||
cursor := model.GetPostsSinceForSyncCursor{
|
||||
LastPostUpdateAt: future,
|
||||
LastPostId: postID,
|
||||
futureUpdateAt := model.GetMillis() + (3600000 * 2) // 2 hours in the future
|
||||
postUpdateID := model.NewId()
|
||||
|
||||
cursorCreate := model.GetPostsSinceForSyncCursor{
|
||||
LastPostCreateAt: futureCreateAt,
|
||||
LastPostCreateID: postCreateID,
|
||||
}
|
||||
|
||||
t.Run("Update NextSyncAt for remote", func(t *testing.T) {
|
||||
err := ss.SharedChannel().UpdateRemoteCursor(remoteSaved.Id, cursor)
|
||||
require.NoError(t, err, "update NextSyncAt should not error", err)
|
||||
cursorUpdate := model.GetPostsSinceForSyncCursor{
|
||||
LastPostUpdateAt: futureUpdateAt,
|
||||
LastPostUpdateID: postUpdateID,
|
||||
}
|
||||
|
||||
t.Run("Update cursor CreateAt for remote", func(t *testing.T) {
|
||||
err := ss.SharedChannel().UpdateRemoteCursor(remoteSaved.Id, cursorCreate)
|
||||
require.NoError(t, err, "update cursor should not error", err)
|
||||
|
||||
r, err := ss.SharedChannel().GetRemote(remoteSaved.Id)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, future, r.LastPostUpdateAt)
|
||||
require.Equal(t, postID, r.LastPostId)
|
||||
require.Equal(t, futureCreateAt, r.LastPostCreateAt)
|
||||
require.Equal(t, postCreateID, r.LastPostCreateID)
|
||||
})
|
||||
|
||||
t.Run("Update NextSyncAt for non-existent shared channel remote", func(t *testing.T) {
|
||||
err := ss.SharedChannel().UpdateRemoteCursor(model.NewId(), cursor)
|
||||
t.Run("Update cursor UpdateAt for remote", func(t *testing.T) {
|
||||
err := ss.SharedChannel().UpdateRemoteCursor(remoteSaved.Id, cursorUpdate)
|
||||
require.NoError(t, err, "update cursor should not error", err)
|
||||
|
||||
r, err := ss.SharedChannel().GetRemote(remoteSaved.Id)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, futureUpdateAt, r.LastPostUpdateAt)
|
||||
require.Equal(t, postUpdateID, r.LastPostUpdateID)
|
||||
})
|
||||
|
||||
t.Run("Update cursor for non-existent shared channel remote", func(t *testing.T) {
|
||||
err := ss.SharedChannel().UpdateRemoteCursor(model.NewId(), cursorUpdate)
|
||||
require.Error(t, err, "update non-existent remote should error", err)
|
||||
})
|
||||
|
||||
t.Run("Update with empty cursor", func(t *testing.T) {
|
||||
emptyCursor := model.GetPostsSinceForSyncCursor{}
|
||||
err := ss.SharedChannel().UpdateRemoteCursor(remoteSaved.Id, emptyCursor)
|
||||
require.Error(t, err, "update with empty cursor should error", err)
|
||||
})
|
||||
}
|
||||
|
||||
func testDeleteSharedChannelRemote(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
|
||||
Ссылка в новой задаче
Block a user