Compare commits

...

18 Commits

Author SHA1 Message Date
neha-Gupta1
fdd67bdaa7 merge commit 2023-08-23 14:45:30 +05:30
neha-Gupta1
13c6286371 channel pager 2023-08-22 19:23:42 +05:30
neha-Gupta1
4d0d66bec0 interface implementation 2023-08-22 18:29:23 +05:30
neha-Gupta1
8902e64487 merge commit 2023-08-22 14:45:22 +05:30
neha-Gupta1
8a9fc804ee Merge branch 'channelHandlers' of https://github.com/alcionai/corso into implementProduceBackupCollection 2023-08-22 14:19:39 +05:30
neha-Gupta1
27990e6174 item pager for channels 2023-08-22 12:48:11 +05:30
neha_gupta
6aff5c62fe
Merge branch 'main' into channelHandlers 2023-08-22 10:24:13 +05:30
neha-Gupta1
a4b65f1ab5 improve function names 2023-08-22 10:23:13 +05:30
neha-Gupta1
7de04b98ab test cases channel api 2023-08-22 10:19:36 +05:30
ryanfkeepers
b9db41eef5 add boilerplate groups backup collection
Adds the boilerplate for groups backup collection processing.
Not necessarily functional at this time, due to missing dependencies
and consts that aren't yet in the branch.  Thus the lack of
tests.  It's just good enough to keep progress rolling forward.
2023-08-21 18:44:00 -06:00
Abin
203f7bd18d ProduceBackupCollections for SharePoint 2023-08-21 12:39:00 +05:30
neha-Gupta1
aef4c688ac lint code 2023-08-18 23:34:31 +05:30
neha-Gupta1
4c5a33db69 lint file 2023-08-18 23:33:21 +05:30
neha-Gupta1
54d5e05950 channels and messages API 2023-08-18 18:27:03 +05:30
neha-Gupta1
5fbc37fbc1 Merge branch 'main' of https://github.com/alcionai/corso into channelHandlers 2023-08-18 13:41:01 +05:30
neha-Gupta1
d1f0d683af message handler 2023-08-18 13:40:42 +05:30
neha-Gupta1
fa1a432a87 lint changes 2023-08-17 16:42:14 +05:30
neha-Gupta1
8d4277b1c7 add handers for channels 2023-08-17 16:24:38 +05:30
11 changed files with 808 additions and 21 deletions

View File

@ -439,7 +439,7 @@ func (c *Collections) Get(
service, category := c.handler.ServiceCat()
md, err := graph.MakeMetadataCollection(
c.tenantID,
c.resourceOwner,
c.resourceOwner, // TODO(meain): path fixes: group id
service,
category,
[]graph.MetadataCollectionEntry{

View File

@ -0,0 +1,18 @@
package groups
import (
"context"
"github.com/microsoft/kiota-abstractions-go/serialization"
"github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/alcionai/corso/src/pkg/services/m365/api"
)
type BackupMessagesHandler interface {
GetMessageByID(ctx context.Context, teamID, channelID, itemID string) (models.ChatMessageable, error)
NewMessagePager(teamID, channelID string) api.ChannelMessageDeltaEnumerator
GetChannelByID(ctx context.Context, teamID, channelID string) (models.Channelable, error)
NewChannelPager(teamID, channelID string) api.ChannelDeltaEnumerator
GetReplyByID(ctx context.Context, teamID, channelID, messageID string) (serialization.Parsable, error)
}

View File

@ -28,6 +28,7 @@ const (
TestCfgSiteURL = "m365siteurl"
TestCfgTeamID = "m365teamid"
TestCfgGroupID = "m365groupid"
TestCfgChannelID = "m365channelid"
TestCfgUserID = "m365userid"
TestCfgSecondaryUserID = "secondarym365userid"
TestCfgSecondaryGroupID = "secondarym365groupid"
@ -46,6 +47,7 @@ const (
EnvCorsoM365TestSiteURL = "CORSO_M365_TEST_SITE_URL"
EnvCorsoM365TestTeamID = "CORSO_M365_TEST_TEAM_ID"
EnvCorsoM365TestGroupID = "CORSO_M365_TEST_GROUP_ID"
EnvCorsoM365TestChannelID = "CORSO_M365_TEST_CHANNEL_ID"
EnvCorsoM365TestUserID = "CORSO_M365_TEST_USER_ID"
EnvCorsoSecondaryM365TestSiteID = "CORSO_SECONDARY_M365_TEST_SITE_ID"
EnvCorsoSecondaryM365TestUserID = "CORSO_SECONDARY_M365_TEST_USER_ID"
@ -167,6 +169,12 @@ func ReadTestConfig() (map[string]string, error) {
os.Getenv(EnvCorsoM365TestGroupID),
vpr.GetString(TestCfgGroupID),
"6f24b40d-b13d-4752-980f-f5fb9fba7aa0")
fallbackTo(
testEnv,
TestCfgChannelID,
os.Getenv(EnvCorsoM365TestChannelID),
vpr.GetString(TestCfgChannelID),
"19:nY6QHZ3hnHJ6ylarBxPjCOLRJNvrL3oKI5iW15QxTPA1@thread.tacv2")
fallbackTo(
testEnv,
TestCfgSiteURL,

View File

@ -246,3 +246,14 @@ func M365GroupID(t *testing.T) string {
return strings.ToLower(cfg[TestCfgTeamID])
}
// M365ChannelID returns a channelID string representing the m365TeamsID described
// by either the env var CORSO_M365_TEST_CHANNEL_ID, the corso_test.toml config
// file or the default value (in that order of priority). The default is a
// last-attempt fallback that will only work on alcion's testing org.
func M365ChannelID(t *testing.T) string {
cfg, err := ReadTestConfig()
require.NoError(t, err, "retrieving m365 channel id from test configuration: %+v", clues.ToCore(err))
return cfg[TestCfgChannelID]
}

View File

@ -37,6 +37,9 @@ const (
// Folder Management(30x)
FolderItem ItemType = 306
// GroupChannel(40x)
GroupChannel ItemType = 407
)
func UpdateItem(item *ItemInfo, newLocPath *path.Builder) {

View File

@ -350,6 +350,14 @@ func (pb Builder) ToDataLayerSharePointPath(
return pb.ToDataLayerPath(tenant, site, SharePointService, category, isItem)
}
func (pb Builder) ToDataLayerGroupPath(
tenant, group string,
category CategoryType,
isItem bool,
) (Path, error) {
return pb.ToDataLayerPath(tenant, group, GroupsService, category, isItem)
}
// ---------------------------------------------------------------------------
// Stringers and PII Concealer Compliance
// ---------------------------------------------------------------------------

View File

@ -82,7 +82,7 @@ var serviceCategories = map[ServiceType]map[CategoryType]struct{}{
},
TeamsService: {
ChannelMessagesCategory: {},
LibrariesCategory: {},
LibrariesCategory: {}, // TODO(meain)
},
}

View File

@ -329,14 +329,24 @@ const (
GroupsGroup groupsCategory = "GroupsGroup"
GroupsChannel groupsCategory = "GroupsChannel"
GroupsChannelMessage groupsCategory = "GroupsChannelMessage"
GroupsLibraryFolder groupsCategory = "GroupsLibraryFolder"
GroupsLibraryItem groupsCategory = "GroupsLibraryItem"
// details.itemInfo comparables
// channel drive selection
GroupsInfoSiteLibraryDrive groupsCategory = "GroupsInfoSiteLibraryDrive"
GroupsInfoChannel groupsCategory = "GroupsInfoChannel"
GroupsInfoChannel groupsCategory = "GroupsInfoChannel"
// sharepoint
GroupsLibraryFolder groupsCategory = "GroupsLibraryFolder"
GroupsLibraryItem groupsCategory = "GroupsLibraryItem"
// messages
// GroupsTeamChannel groupsCategory = "GroupsTeamChannel"
// GroupsTeamChannelMessages groupsCategory = "GroupsTeamChannelMessages"
// details.itemInfo comparables
// library drive selection
GroupsInfoSiteLibraryDrive groupsCategory = "GroupsInfoSiteLibraryDrive" // TODO(meain)
)
// groupsLeafProperties describes common metadata of the leaf categories
@ -424,7 +434,8 @@ func (c groupsCategory) pathValues(
}
folderCat, itemCat = GroupsLibraryFolder, GroupsLibraryItem
rFld = ent.Groups.ParentPath
rFld = ent.Groups.ParentPath // TODO(meain)
default:
return nil, clues.New("unrecognized groupsCategory").With("category", c)
}

View File

@ -1 +1,380 @@
package api
import (
"context"
"fmt"
"github.com/alcionai/clues"
"github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/m365/graph"
"github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/fault"
"github.com/alcionai/corso/src/pkg/logger"
"github.com/microsoft/kiota-abstractions-go/serialization"
"github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/microsoftgraph/msgraph-sdk-go/teams"
)
// ---------------------------------------------------------------------------
// controller
// ---------------------------------------------------------------------------
func (c Client) Channels() Channels {
return Channels{c}
}
// Channels is an interface-compliant provider of the client.
type Channels struct {
Client
}
// ---------------------------------------------------------------------------
// containers
// ---------------------------------------------------------------------------
// CreateContainer makes an channels with the name in the team
func (c Channels) CreateChannel(
ctx context.Context,
teamID, containerName string,
) (graph.Container, error) {
body := models.NewChannel()
body.SetDisplayName(&containerName)
container, err := c.Stable.
Client().
Teams().
ByTeamId(teamID).
Channels().
Post(ctx, body, nil)
if err != nil {
return nil, graph.Wrap(ctx, err, "creating channel")
}
return ChannelsDisplayable{Channelable: container}, nil
}
// DeleteChannel removes a channel from user's M365 account
func (c Channels) DeleteChannel(
ctx context.Context,
teamID, containerID string,
) error {
// deletes require unique http clients
// https://github.com/alcionai/corso/issues/2707
srv, err := NewService(c.Credentials)
if err != nil {
return graph.Stack(ctx, err)
}
err = srv.Client().
Teams().
ByTeamId(teamID).
Channels().
ByChannelId(containerID).
Delete(ctx, nil)
if err != nil {
return graph.Stack(ctx, err)
}
return nil
}
func (c Channels) GetChannel(
ctx context.Context,
teamID, containerID string,
) (models.Channelable, error) {
config := &teams.ItemChannelsChannelItemRequestBuilderGetRequestConfiguration{
QueryParameters: &teams.ItemChannelsChannelItemRequestBuilderGetQueryParameters{
Select: idAnd("displayName"),
},
}
resp, err := c.Stable.
Client().
Teams().
ByTeamId(teamID).
Channels().
ByChannelId(containerID).
Get(ctx, config)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, nil
}
func (c Channels) GetChannelByID(
ctx context.Context,
teamID, containerID string,
) (graph.Container, error) {
channel, err := c.GetChannel(ctx, teamID, containerID)
if err != nil {
return nil, err
}
return ChannelsDisplayable{Channelable: channel}, nil
}
// GetChannelByName fetches a channel by name
func (c Channels) GetChannelByName(
ctx context.Context,
teamID, containerName string,
) (graph.Container, error) {
ctx = clues.Add(ctx, "channel_name", containerName)
filter := fmt.Sprintf("displayName eq '%s'", containerName)
options := &teams.ItemChannelsRequestBuilderGetRequestConfiguration{
QueryParameters: &teams.ItemChannelsRequestBuilderGetQueryParameters{
Filter: &filter,
},
}
resp, err := c.Stable.
Client().
Teams().
ByTeamId(teamID).
Channels().
Get(ctx, options)
if err != nil {
return nil, graph.Stack(ctx, err).WithClues(ctx)
}
gv := resp.GetValue()
if len(gv) == 0 {
return nil, clues.New("channel not found").WithClues(ctx)
}
// We only allow the api to match one channel with the provided name.
// If we match multiples, we'll eagerly return the first one.
logger.Ctx(ctx).Debugw("channels matched the name search")
// Sanity check ID and name
cal := gv[0]
container := ChannelsDisplayable{Channelable: cal}
if err := graph.CheckIDAndName(container); err != nil {
return nil, clues.Stack(err).WithClues(ctx)
}
return container, nil
}
func (c Channels) PatchChannel(
ctx context.Context,
teamID, containerID string,
body models.Channelable,
) error {
_, err := c.Stable.
Client().
Teams().
ByTeamId(teamID).
Channels().
ByChannelId(containerID).
Patch(ctx, body, nil)
if err != nil {
return graph.Wrap(ctx, err, "patching channel")
}
return nil
}
// ---------------------------------------------------------------------------
// message
// ---------------------------------------------------------------------------
// GetItem retrieves a Messageable item.
func (c Channels) GetMessage(
ctx context.Context,
teamID, channelID, itemID string,
immutableIDs bool,
errs *fault.Bus,
) (serialization.Parsable, *details.GroupsInfo, error) {
var (
size int64
)
// is preferImmutableIDs headers required here
message, err := c.Stable.
Client().
Teams().
ByTeamId(teamID).
Channels().
ByChannelId(channelID).
Messages().
ByChatMessageId(itemID).
Get(ctx, nil)
if err != nil {
return nil, nil, graph.Stack(ctx, err)
}
return message, MessageInfo(message, size), nil
}
func (c Channels) PostMessage(
ctx context.Context,
teamID, containerID string,
body models.ChatMessageable,
) (models.ChatMessageable, error) {
itm, err := c.Stable.
Client().
Teams().
ByTeamId(teamID).
Channels().
ByChannelId(containerID).
Messages().
Post(ctx, body, nil)
if err != nil {
return nil, graph.Wrap(ctx, err, "creating mail message")
}
if itm == nil {
return nil, clues.New("nil response mail message creation").WithClues(ctx)
}
return itm, nil
}
func (c Channels) DeleteMessage(
ctx context.Context,
teamID, itemID, containerID string,
) error {
// deletes require unique http clients
// https://github.com/alcionai/corso/issues/2707
srv, err := NewService(c.Credentials)
if err != nil {
return graph.Stack(ctx, err)
}
err = srv.
Client().
Teams().
ByTeamId(teamID).
Channels().
ByChannelId(containerID).
Messages().
ByChatMessageId(itemID).
Delete(ctx, nil)
if err != nil {
return graph.Wrap(ctx, err, "deleting mail message")
}
return nil
}
// ---------------------------------------------------------------------------
// replies
// ---------------------------------------------------------------------------
// GetReplies retrieves a Messageable item.
func (c Channels) GetReplies(
ctx context.Context,
teamID, channelID, itemID string,
) (serialization.Parsable, error) {
replies, err := c.Stable.
Client().
Teams().
ByTeamId(teamID).
Channels().
ByChannelId(channelID).
Messages().
ByChatMessageId(itemID).
Replies().
Get(ctx, nil)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return replies, nil
}
func (c Channels) PostReply(
ctx context.Context,
teamID, containerID, messageID string,
body models.ChatMessageable,
) (models.ChatMessageable, error) {
itm, err := c.Stable.
Client().
Teams().
ByTeamId(teamID).
Channels().
ByChannelId(containerID).
Messages().
ByChatMessageId(messageID).
Replies().
Post(ctx, body, nil)
if err != nil {
return nil, graph.Wrap(ctx, err, "creating reply message")
}
if itm == nil {
return nil, clues.New("nil response reply to message creation").WithClues(ctx)
}
return itm, nil
}
func (c Channels) DeleteReply(
ctx context.Context,
teamID, itemID, containerID, replyID string,
) error {
// deletes require unique http clients
// https://github.com/alcionai/corso/issues/2707
srv, err := NewService(c.Credentials)
if err != nil {
return graph.Stack(ctx, err)
}
err = srv.
Client().
Teams().
ByTeamId(teamID).
Channels().
ByChannelId(containerID).
Messages().
ByChatMessageId(itemID).
Replies().
ByChatMessageId1(replyID).
Delete(ctx, nil)
if err != nil {
return graph.Wrap(ctx, err, "deleting mail message")
}
return nil
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
func MessageInfo(msg models.ChatMessageable, size int64) *details.GroupsInfo {
var (
created = ptr.Val(msg.GetCreatedDateTime())
)
return &details.GroupsInfo{
ItemType: details.GroupChannel,
Size: size,
Created: created,
Modified: ptr.OrNow(msg.GetLastModifiedDateTime()),
}
}
// ---------------------------------------------------------------------------
// helper funcs
// ---------------------------------------------------------------------------
// ChannelsDisplayable is a wrapper that complies with the
// models.Channelable interface with the graph.Container
// interfaces.
type ChannelsDisplayable struct {
models.Channelable
}
// GetParentFolderId returns the default channe name address
//nolint:revive
func (c ChannelsDisplayable) GetParentFolderId() *string {
return nil
}

View File

@ -1,7 +1,13 @@
package api
import (
"context"
"github.com/alcionai/clues"
"github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/m365/graph"
"github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/microsoftgraph/msgraph-sdk-go/teams"
)
// ---------------------------------------------------------------------------
@ -14,30 +20,206 @@ type ChannelMessageDeltaEnumerator interface {
SetNextLinker
}
// TODO: implement
// var _ ChannelMessageDeltaEnumerator = &messagePageCtrl{}
var _ ChannelMessageDeltaEnumerator = &MessagePageCtrl{}
// type messagePageCtrl struct {
// gs graph.Servicer
// builder *teams.ItemChannelsItemMessagesRequestBuilder
// options *teams.ItemChannelsItemMessagesRequestBuilderGetRequestConfiguration
// }
type MessagePageCtrl struct {
gs graph.Servicer
builder *teams.ItemChannelsItemMessagesDeltaRequestBuilder
options *teams.ItemChannelsItemMessagesDeltaRequestBuilderGetRequestConfiguration
}
func (c Channels) NewMessagePager(
teamID,
channelID string,
fields []string,
) *MessagePageCtrl {
requestConfig := &teams.ItemChannelsItemMessagesDeltaRequestBuilderGetRequestConfiguration{
QueryParameters: &teams.ItemChannelsItemMessagesDeltaRequestBuilderGetQueryParameters{
Select: fields,
},
}
res := &MessagePageCtrl{
gs: c.Stable,
options: requestConfig,
builder: c.Stable.
Client().
Teams().
ByTeamId(teamID).
Channels().
ByChannelId(channelID).
Messages().
Delta(),
}
return res
}
func (p *MessagePageCtrl) SetNext(nextLink string) {
p.builder = teams.NewItemChannelsItemMessagesDeltaRequestBuilder(nextLink, p.gs.Adapter())
}
func (p *MessagePageCtrl) GetPage(ctx context.Context) (DeltaPageLinker, error) {
var (
resp DeltaPageLinker
err error
)
resp, err = p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, nil
}
func (p *MessagePageCtrl) ValuesIn(l PageLinker) ([]models.ChatMessageable, error) {
return getValues[models.ChatMessageable](l)
}
// ---------------------------------------------------------------------------
// channel pager
// ---------------------------------------------------------------------------
type ChannelDeltaEnumerator interface {
DeltaGetPager
PageLinker
ValuesInPageLinker[models.Channelable]
SetNextLinker
}
// TODO: implement
// var _ ChannelDeltaEnumerator = &channelsPageCtrl{}
var _ ChannelDeltaEnumerator = &channelPageCtrl{}
// type channelsPageCtrl struct {
// gs graph.Servicer
// builder *teams.ItemChannelsChannelItemRequestBuilder
// options *teams.ItemChannelsChannelItemRequestBuilderGetRequestConfiguration
// }
type channelPageCtrl struct {
gs graph.Servicer
builder *teams.ItemChannelsRequestBuilder
options *teams.ItemChannelsRequestBuilderGetRequestConfiguration
}
func (c Channels) NewChannelPager(
teamID,
channelID string,
fields []string,
) *channelPageCtrl {
requestConfig := &teams.ItemChannelsRequestBuilderGetRequestConfiguration{
QueryParameters: &teams.ItemChannelsRequestBuilderGetQueryParameters{
Select: fields,
},
}
res := &channelPageCtrl{
gs: c.Stable,
options: requestConfig,
builder: c.Stable.
Client().
Teams().
ByTeamId(teamID).
Channels(),
}
return res
}
func (p *channelPageCtrl) SetNext(nextLink string) {
p.builder = teams.NewItemChannelsRequestBuilder(nextLink, p.gs.Adapter())
}
func (p *channelPageCtrl) GetPage(ctx context.Context) (PageLinker, error) {
var (
resp PageLinker
err error
)
resp, err = p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, nil
}
func (p *channelPageCtrl) ValuesIn(l PageLinker) ([]models.Channelable, error) {
return getValues[models.Channelable](l)
}
func (p *channelPageCtrl) GetOdataNextLink() *string {
// TODO: no delta present here. Is it possible to have interface which does not have
// GetOdataNextLink method
emptyString := ""
return &emptyString
}
// ---------------------------------------------------------------------------
// non delta item pager
// ---------------------------------------------------------------------------
type MessageItemIDType struct {
ItemID string
}
type channelItemPageCtrl struct {
gs graph.Servicer
builder *teams.ItemChannelsItemMessagesRequestBuilder
options *teams.ItemChannelsItemMessagesRequestBuilderGetRequestConfiguration
}
func (c Channels) GetItemIDsInContainer(
ctx context.Context,
teamID, channelID string,
) (map[string]MessageItemIDType, error) {
ctx = clues.Add(ctx, "channel_id", channelID)
pager := c.NewChannelItemPager(teamID, channelID)
items, err := enumerateItems(ctx, pager)
if err != nil {
return nil, graph.Wrap(ctx, err, "enumerating contacts")
}
m := map[string]MessageItemIDType{}
for _, item := range items {
m[ptr.Val(item.GetId())] = MessageItemIDType{
ItemID: ptr.Val(item.GetId()),
}
}
return m, nil
}
func (c Channels) NewChannelItemPager(
teamID, containerID string,
selectProps ...string,
) itemPager[models.ChatMessageable] {
options := &teams.ItemChannelsItemMessagesRequestBuilderGetRequestConfiguration{
QueryParameters: &teams.ItemChannelsItemMessagesRequestBuilderGetQueryParameters{},
}
if len(selectProps) > 0 {
options.QueryParameters.Select = selectProps
}
builder := c.Stable.
Client().
Teams().
ByTeamId(teamID).
Channels().
ByChannelId(containerID).
Messages()
return &channelItemPageCtrl{c.Stable, builder, options}
}
//lint:ignore U1000 False Positive
func (p *channelItemPageCtrl) getPage(ctx context.Context) (PageLinkValuer[models.ChatMessageable], error) {
page, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return EmptyDeltaLinker[models.ChatMessageable]{PageLinkValuer: page}, nil
}
//lint:ignore U1000 False Positive
func (p *channelItemPageCtrl) setNext(nextLink string) {
p.builder = teams.NewItemChannelsItemMessagesRequestBuilder(nextLink, p.gs.Adapter())
}

View File

@ -0,0 +1,167 @@
package api_test
import (
"context"
"fmt"
"testing"
"time"
"github.com/alcionai/clues"
"github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/internal/tester/tconfig"
"github.com/alcionai/corso/src/pkg/account"
"github.com/alcionai/corso/src/pkg/services/m365/api"
"github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
type ChannelPagerIntgSuite struct {
tester.Suite
its intgTesterSetup
}
func TestChannelPagerIntgSuite(t *testing.T) {
suite.Run(t, &ChannelPagerIntgSuite{
Suite: tester.NewIntegrationSuite(
t,
[][]string{tconfig.M365AcctCredEnvs}),
})
}
func (suite *ChannelPagerIntgSuite) SetupSuite() {
suite.its = newIntegrationTesterSetup(suite.T())
}
func (suite *ChannelPagerIntgSuite) TestChannels_GetPage() {
t := suite.T()
ctx, flush := tester.NewContext(t)
defer flush()
teamID := tconfig.M365TeamID(t)
channelID := tconfig.M365ChannelID(t)
pager := suite.its.ac.Channels().NewMessagePager(teamID, channelID, []string{})
a, err := pager.GetPage(ctx)
assert.NoError(t, err, clues.ToCore(err))
assert.NotNil(t, a)
}
func (suite *ChannelPagerIntgSuite) TestChannels_CreateGetAndDelete() {
t := suite.T()
ctx, flush := tester.NewContext(t)
defer flush()
var (
yy, mm, dd = time.Now().Date()
hh = time.Now().Hour()
min = time.Now().Minute()
ss = time.Now().Second()
containerName = fmt.Sprintf("testChannel%d%d%d%d%d%d", yy, mm, dd, hh, min, ss)
teamID = tconfig.M365TeamID(t)
credentials = suite.its.ac.Credentials
chanClient = suite.its.ac.Channels()
)
// GET channel - should be not found
_, err := suite.its.ac.Channels().GetChannelByName(ctx, teamID, containerName)
assert.Error(t, err, clues.ToCore(err))
// POST channel
channelPost, err := suite.its.ac.Channels().CreateChannel(ctx, teamID, containerName)
assert.NoError(t, err, clues.ToCore(err))
postChannelID := ptr.Val(channelPost.GetId())
// DELETE channel
defer func() {
_, err := chanClient.GetChannelByID(ctx, teamID, postChannelID)
if err != nil {
fmt.Println("could not find channel: ", err)
} else {
deleteChannel(ctx, credentials, teamID, postChannelID)
}
}()
// GET channel -should be found
channel, err := chanClient.GetChannelByName(ctx, teamID, containerName)
assert.NoError(t, err, clues.ToCore(err))
assert.Equal(t, ptr.Val(channel.GetDisplayName()), containerName)
// PATCH channel
patchBody := models.NewChannel()
patchName := fmt.Sprintf("othername%d%d%d%d%d%d", yy, mm, dd, hh, min, ss)
patchBody.SetDisplayName(ptr.To(patchName))
err = chanClient.PatchChannel(ctx, teamID, postChannelID, patchBody)
assert.NoError(t, err, clues.ToCore(err))
assert.Equal(t, ptr.Val(channel.GetDisplayName()), containerName)
// GET channel -should not be found with old name
_, err = chanClient.GetChannelByName(ctx, teamID, containerName)
assert.Error(t, err, clues.ToCore(err))
// GET channel -should be found with new name
channel, err = chanClient.GetChannelByName(ctx, teamID, patchName)
assert.NoError(t, err, clues.ToCore(err))
assert.Equal(t, ptr.Val(channel.GetDisplayName()), patchName)
assert.Equal(t, ptr.Val(channel.GetId()), postChannelID)
// GET channel -should not be found with old name
err = chanClient.DeleteChannel(ctx, teamID, postChannelID)
assert.NoError(t, err, clues.ToCore(err))
// GET channel -should not be found anymore
_, err = chanClient.GetChannel(ctx, teamID, postChannelID)
assert.Error(t, err, clues.ToCore(err))
}
func deleteChannel(ctx context.Context, credentials account.M365Config, teamID, postChannelID string) {
srv, err := api.NewService(credentials)
if err != nil {
fmt.Println("Error found in getting creds")
}
if err != nil {
fmt.Println("Error found in getting creds")
}
err = srv.Client().
Teams().
ByTeamId(teamID).
Channels().
ByChannelId(postChannelID).
Delete(ctx, nil)
if err != nil {
fmt.Println("channel could not be delete in defer")
}
}
// func (suite *ChannelPagerIntgSuite) TestMessages_CreateGetAndDelete() {
// t := suite.T()
// ctx, flush := tester.NewContext(t)
// defer flush()
// var (
// teamID = tconfig.M365TeamsID(t)
// channelID = tconfig.M365ChannelID(t)
// credentials = suite.its.ac.Credentials
// chanClient = suite.its.ac.Channels()
// )
// // GET channel - should be not found
// message, _, err := chanClient.GetMessage(ctx, teamID, channelID, "", "")
// assert.Error(t, err, clues.ToCore(err))
// // POST channel
// // patchBody := models.NewChatMessage()
// // body := models.NewItemBody()
// // content := "Hello World"
// // body.SetContent(&content)
// // patchBody.SetBody(body)
// // _, := suite.its.ac.Channels().PostMessage(ctx, teamID, channelID, patchBody)
// // assert.NoError(t, err, clues.ToCore(err))
// }