add chats boilerplate to details
This commit is contained in:
parent
eefce75f1d
commit
07997b0987
120
src/pkg/backup/details/chats.go
Normal file
120
src/pkg/backup/details/chats.go
Normal file
@ -0,0 +1,120 @@
|
||||
package details
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/alcionai/clues"
|
||||
|
||||
"github.com/alcionai/corso/src/pkg/dttm"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
)
|
||||
|
||||
// NewChatsLocationIDer builds a LocationIDer for the chats.
|
||||
func NewChatsLocationIDer(
|
||||
category path.CategoryType,
|
||||
escapedFolders ...string,
|
||||
) (uniqueLoc, error) {
|
||||
if err := path.ValidateServiceAndCategory(path.TeamsChatsService, category); err != nil {
|
||||
return uniqueLoc{}, clues.Wrap(err, "making chats LocationIDer")
|
||||
}
|
||||
|
||||
pb := path.Builder{}.Append(category.String()).Append(escapedFolders...)
|
||||
|
||||
return uniqueLoc{
|
||||
pb: pb,
|
||||
prefixElems: 1,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// TeamsChatsInfo describes a chat within teams chats.
|
||||
type TeamsChatsInfo struct {
|
||||
ItemType ItemType `json:"itemType,omitempty"`
|
||||
Modified time.Time `json:"modified,omitempty"`
|
||||
ParentPath string `json:"parentPath,omitempty"`
|
||||
|
||||
Chat ChatInfo `json:"chat,omitempty"`
|
||||
}
|
||||
|
||||
type ChatInfo struct {
|
||||
CreatedAt time.Time `json:"createdAt,omitempty"`
|
||||
HasExternalMembers bool `json:"hasExternalMemebers,omitempty"`
|
||||
LastMessageAt time.Time `json:"lastMessageAt,omitempty"`
|
||||
LastMessagePreview string `json:"preview,omitempty"`
|
||||
Members []string `json:"members,omitempty"`
|
||||
MessageCount int `json:"size,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// Headers returns the human-readable names of properties in a ChatsInfo
|
||||
// for printing out to a terminal in a columnar display.
|
||||
func (i TeamsChatsInfo) Headers() []string {
|
||||
switch i.ItemType {
|
||||
case TeamsChat:
|
||||
return []string{"Name", "Last message", "Last message at", "Message count", "Created", "Members"}
|
||||
}
|
||||
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// Values returns the values matching the Headers list for printing
|
||||
// out to a terminal in a columnar display.
|
||||
func (i TeamsChatsInfo) Values() []string {
|
||||
switch i.ItemType {
|
||||
case TeamsChat:
|
||||
members := ""
|
||||
icmLen := len(i.Chat.Members)
|
||||
|
||||
if icmLen > 0 {
|
||||
members = i.Chat.Members[0]
|
||||
}
|
||||
|
||||
if icmLen > 1 {
|
||||
members = fmt.Sprintf("%s, and %d more", members, icmLen-1)
|
||||
}
|
||||
|
||||
return []string{
|
||||
i.Chat.Name,
|
||||
i.Chat.LastMessagePreview,
|
||||
dttm.FormatToTabularDisplay(i.Chat.LastMessageAt),
|
||||
strconv.Itoa(i.Chat.MessageCount),
|
||||
dttm.FormatToTabularDisplay(i.Chat.CreatedAt),
|
||||
members,
|
||||
}
|
||||
}
|
||||
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (i *TeamsChatsInfo) UpdateParentPath(newLocPath *path.Builder) {
|
||||
i.ParentPath = newLocPath.String()
|
||||
}
|
||||
|
||||
func (i *TeamsChatsInfo) uniqueLocation(baseLoc *path.Builder) (*uniqueLoc, error) {
|
||||
var category path.CategoryType
|
||||
|
||||
switch i.ItemType {
|
||||
case TeamsChat:
|
||||
category = path.ChatsCategory
|
||||
}
|
||||
|
||||
loc, err := NewChatsLocationIDer(category, baseLoc.Elements()...)
|
||||
|
||||
return &loc, err
|
||||
}
|
||||
|
||||
func (i *TeamsChatsInfo) updateFolder(f *FolderInfo) error {
|
||||
// Use a switch instead of a rather large if-statement. Just make sure it's an
|
||||
// Exchange type. If it's not return an error.
|
||||
switch i.ItemType {
|
||||
case TeamsChat:
|
||||
default:
|
||||
return clues.New("unsupported non-Chats ItemType").
|
||||
With("item_type", i.ItemType)
|
||||
}
|
||||
|
||||
f.DataType = i.ItemType
|
||||
|
||||
return nil
|
||||
}
|
||||
71
src/pkg/backup/details/chats_test.go
Normal file
71
src/pkg/backup/details/chats_test.go
Normal file
@ -0,0 +1,71 @@
|
||||
package details_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/tester"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/dttm"
|
||||
)
|
||||
|
||||
type ChatsUnitSuite struct {
|
||||
tester.Suite
|
||||
}
|
||||
|
||||
func TestChatsUnitSuite(t *testing.T) {
|
||||
suite.Run(t, &ChatsUnitSuite{Suite: tester.NewUnitSuite(t)})
|
||||
}
|
||||
|
||||
func (suite *ChatsUnitSuite) TestChatsPrintable() {
|
||||
now := time.Now()
|
||||
then := now.Add(time.Minute)
|
||||
|
||||
table := []struct {
|
||||
name string
|
||||
info details.TeamsChatsInfo
|
||||
expectHs []string
|
||||
expectVs []string
|
||||
}{
|
||||
{
|
||||
name: "channel message",
|
||||
info: details.TeamsChatsInfo{
|
||||
ItemType: details.TeamsChat,
|
||||
ParentPath: "parentpath",
|
||||
Chat: details.ChatInfo{
|
||||
CreatedAt: now,
|
||||
HasExternalMembers: true,
|
||||
LastMessageAt: then,
|
||||
LastMessagePreview: "last message preview",
|
||||
Members: []string{"foo@bar.baz", "fnords@smarf.zoomba"},
|
||||
MessageCount: 42,
|
||||
Name: "chat name",
|
||||
},
|
||||
},
|
||||
expectHs: []string{"Name", "Last message", "Last message at", "Message count", "Created", "Members"},
|
||||
expectVs: []string{
|
||||
"chat name",
|
||||
"last message preview",
|
||||
dttm.FormatToTabularDisplay(then),
|
||||
"42",
|
||||
dttm.FormatToTabularDisplay(now),
|
||||
"foo@bar.baz, and 1 more",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range table {
|
||||
suite.Run(test.name, func() {
|
||||
t := suite.T()
|
||||
|
||||
hs := test.info.Headers()
|
||||
vs := test.info.Values()
|
||||
|
||||
assert.Equal(t, len(hs), len(vs))
|
||||
assert.Equal(t, test.expectHs, hs)
|
||||
assert.Equal(t, test.expectVs, vs)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -78,7 +78,7 @@ type ChannelMessageInfo struct {
|
||||
Subject string `json:"subject,omitempty"`
|
||||
}
|
||||
|
||||
// Headers returns the human-readable names of properties in a SharePointInfo
|
||||
// Headers returns the human-readable names of properties in a gropusInfo
|
||||
// for printing out to a terminal in a columnar display.
|
||||
func (i GroupsInfo) Headers() []string {
|
||||
switch i.ItemType {
|
||||
|
||||
@ -41,6 +41,9 @@ const (
|
||||
// Groups/Teams(40x)
|
||||
GroupsChannelMessage ItemType = 401
|
||||
GroupsConversationPost ItemType = 402
|
||||
|
||||
// Teams Chat
|
||||
TeamsChat ItemType = 501
|
||||
)
|
||||
|
||||
func UpdateItem(item *ItemInfo, newLocPath *path.Builder) {
|
||||
@ -73,6 +76,7 @@ type ItemInfo struct {
|
||||
SharePoint *SharePointInfo `json:"sharePoint,omitempty"`
|
||||
OneDrive *OneDriveInfo `json:"oneDrive,omitempty"`
|
||||
Groups *GroupsInfo `json:"groups,omitempty"`
|
||||
TeamsChats *TeamsChatsInfo `json:"teamsChats,omitempty"`
|
||||
// Optional item extension data
|
||||
Extension *ExtensionData `json:"extension,omitempty"`
|
||||
}
|
||||
@ -99,6 +103,9 @@ func (i ItemInfo) infoType() ItemType {
|
||||
|
||||
case i.Groups != nil:
|
||||
return i.Groups.ItemType
|
||||
|
||||
case i.TeamsChats != nil:
|
||||
return i.TeamsChats.ItemType
|
||||
}
|
||||
|
||||
return UnknownType
|
||||
@ -120,6 +127,9 @@ func (i ItemInfo) size() int64 {
|
||||
|
||||
case i.Folder != nil:
|
||||
return i.Folder.Size
|
||||
|
||||
case i.TeamsChats != nil:
|
||||
return int64(i.TeamsChats.Chat.MessageCount)
|
||||
}
|
||||
|
||||
return 0
|
||||
@ -141,6 +151,9 @@ func (i ItemInfo) Modified() time.Time {
|
||||
|
||||
case i.Folder != nil:
|
||||
return i.Folder.Modified
|
||||
|
||||
case i.TeamsChats != nil:
|
||||
return i.TeamsChats.Modified
|
||||
}
|
||||
|
||||
return time.Time{}
|
||||
@ -160,6 +173,9 @@ func (i ItemInfo) uniqueLocation(baseLoc *path.Builder) (*uniqueLoc, error) {
|
||||
case i.Groups != nil:
|
||||
return i.Groups.uniqueLocation(baseLoc)
|
||||
|
||||
case i.TeamsChats != nil:
|
||||
return i.TeamsChats.uniqueLocation(baseLoc)
|
||||
|
||||
default:
|
||||
return nil, clues.New("unsupported type")
|
||||
}
|
||||
@ -179,6 +195,9 @@ func (i ItemInfo) updateFolder(f *FolderInfo) error {
|
||||
case i.Groups != nil:
|
||||
return i.Groups.updateFolder(f)
|
||||
|
||||
case i.TeamsChats != nil:
|
||||
return i.TeamsChats.updateFolder(f)
|
||||
|
||||
default:
|
||||
return clues.New("unsupported type")
|
||||
}
|
||||
|
||||
@ -71,12 +71,21 @@ func (suite *ItemInfoUnitSuite) TestItemInfo_IsDriveItem() {
|
||||
{
|
||||
name: "exchange anything",
|
||||
ii: ItemInfo{
|
||||
Groups: &GroupsInfo{
|
||||
Exchange: &ExchangeInfo{
|
||||
ItemType: ExchangeMail,
|
||||
},
|
||||
},
|
||||
expect: assert.False,
|
||||
},
|
||||
{
|
||||
name: "teams chat",
|
||||
ii: ItemInfo{
|
||||
TeamsChats: &TeamsChatsInfo{
|
||||
ItemType: TeamsChat,
|
||||
},
|
||||
},
|
||||
expect: assert.False,
|
||||
},
|
||||
}
|
||||
for _, test := range table {
|
||||
suite.Run(test.name, func() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user