From 9793d81670744d6fb94195b00ec3b9bd0cc8f695 Mon Sep 17 00:00:00 2001 From: Danny Date: Thu, 23 Feb 2023 14:43:10 -0500 Subject: [PATCH] GC: Sharepoint: Pages info extended (#2461) ## Description SharePoint details has a field `ParentPath`. This PR populates that field. Requires an additional call per collection to retrieve the Site's webURL. ## Does this PR need a docs update or release note? - [x] :no_entry: No ## Type of change - [x] :broom: Tech Debt/Cleanup ## Test Plan - [x] :muscle: Manual --- .../connector/sharepoint/api/pages.go | 19 ++++++++ .../connector/sharepoint/collection.go | 9 +++- src/internal/connector/sharepoint/pageInfo.go | 48 +++++++++++++++++++ .../connector/sharepoint/pageInfo_test.go | 48 +++++++++++++++++++ 4 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 src/internal/connector/sharepoint/pageInfo.go create mode 100644 src/internal/connector/sharepoint/pageInfo_test.go diff --git a/src/internal/connector/sharepoint/api/pages.go b/src/internal/connector/sharepoint/api/pages.go index 8f33760fb..136c7c750 100644 --- a/src/internal/connector/sharepoint/api/pages.go +++ b/src/internal/connector/sharepoint/api/pages.go @@ -19,6 +19,8 @@ import ( D "github.com/alcionai/corso/src/internal/diagnostics" "github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/fault" + msmodels "github.com/microsoftgraph/msgraph-sdk-go/models" + mssites "github.com/microsoftgraph/msgraph-sdk-go/sites" ) // GetSitePages retrieves a collection of Pages related to the give Site. @@ -81,6 +83,23 @@ func GetSitePages( return col, et.Err() } +// GetSite returns a minimal Site with the SiteID and the WebURL +func GetSite(ctx context.Context, gs graph.Servicer, siteID string) (msmodels.Siteable, error) { + // resp *sites.SiteItemRequestBuilderresp *sites.SiteItemRequestBuilde + options := &mssites.SiteItemRequestBuilderGetRequestConfiguration{ + QueryParameters: &mssites.SiteItemRequestBuilderGetQueryParameters{ + Select: []string{"webUrl"}, + }, + } + + resp, err := gs.Client().SitesById(siteID).Get(ctx, options) + if err != nil { + return nil, err + } + + return resp, nil +} + // fetchPages utility function to return the tuple of item func FetchPages(ctx context.Context, bs *discover.BetaService, siteID string) ([]NameID, error) { var ( diff --git a/src/internal/connector/sharepoint/collection.go b/src/internal/connector/sharepoint/collection.go index 121f70d70..5e180c03d 100644 --- a/src/internal/connector/sharepoint/collection.go +++ b/src/internal/connector/sharepoint/collection.go @@ -288,6 +288,13 @@ func (sc *Collection) retrievePages( return metrics, clues.New("beta service required").WithClues(ctx) } + parent, err := sapi.GetSite(ctx, sc.service, sc.fullPath.ResourceOwner()) + if err != nil { + return metrics, err + } + + root := ptr.Val(parent.GetWebUrl()) + pages, err := sapi.GetSitePages(ctx, betaService, sc.fullPath.ResourceOwner(), sc.jobs, errs) if err != nil { return metrics, err @@ -316,7 +323,7 @@ func (sc *Collection) retrievePages( sc.data <- &Item{ id: *pg.GetId(), data: io.NopCloser(bytes.NewReader(byteArray)), - info: sapi.PageInfo(pg, size), + info: sharePointPageInfo(pg, root, size), modTime: ptr.OrNow(pg.GetLastModifiedDateTime()), } diff --git a/src/internal/connector/sharepoint/pageInfo.go b/src/internal/connector/sharepoint/pageInfo.go new file mode 100644 index 000000000..2990f31f7 --- /dev/null +++ b/src/internal/connector/sharepoint/pageInfo.go @@ -0,0 +1,48 @@ +package sharepoint + +import ( + "time" + + "github.com/alcionai/corso/src/internal/connector/graph/betasdk/models" + "github.com/alcionai/corso/src/pkg/backup/details" +) + +// sharePointPageInfo propagates metadata from the SharePoint Page data type +// into searchable content. +// Page Details: https://learn.microsoft.com/en-us/graph/api/resources/sitepage?view=graph-rest-beta +func sharePointPageInfo(page models.SitePageable, root string, size int64) *details.SharePointInfo { + var ( + name, prefix, webURL string + created, modified time.Time + ) + + if page.GetTitle() != nil { + name = *page.GetTitle() + } + + if page.GetWebUrl() != nil { + if len(root) > 0 { + prefix = root + "/" + } + + webURL = prefix + *page.GetWebUrl() + } + + if page.GetCreatedDateTime() != nil { + created = *page.GetCreatedDateTime() + } + + if page.GetLastModifiedDateTime() != nil { + modified = *page.GetLastModifiedDateTime() + } + + return &details.SharePointInfo{ + ItemType: details.SharePointItem, + ItemName: name, + ParentPath: root, + Created: created, + Modified: modified, + WebURL: webURL, + Size: size, + } +} diff --git a/src/internal/connector/sharepoint/pageInfo_test.go b/src/internal/connector/sharepoint/pageInfo_test.go new file mode 100644 index 000000000..8bd563a0c --- /dev/null +++ b/src/internal/connector/sharepoint/pageInfo_test.go @@ -0,0 +1,48 @@ +package sharepoint + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/alcionai/corso/src/internal/connector/graph/betasdk/models" + "github.com/alcionai/corso/src/pkg/backup/details" +) + +func (suite *SharePointInfoSuite) TestSharePointInfo_Pages() { + tests := []struct { + name string + pageAndDeets func() (models.SitePageable, *details.SharePointInfo) + }{ + { + name: "Empty Page", + pageAndDeets: func() (models.SitePageable, *details.SharePointInfo) { + deets := &details.SharePointInfo{ItemType: details.SharePointItem} + return models.NewSitePage(), deets + }, + }, + { + name: "Only Name", + pageAndDeets: func() (models.SitePageable, *details.SharePointInfo) { + title := "Blank Page" + sPage := models.NewSitePage() + sPage.SetTitle(&title) + deets := &details.SharePointInfo{ + ItemType: details.SharePointItem, + ItemName: title, + } + + return sPage, deets + }, + }, + } + for _, test := range tests { + suite.T().Run(test.name, func(t *testing.T) { + paged, expected := test.pageAndDeets() + info := sharePointPageInfo(paged, "", 0) + assert.Equal(t, expected.ItemType, info.ItemType) + assert.Equal(t, expected.ItemName, info.ItemName) + assert.Equal(t, expected.WebURL, info.WebURL) + }) + } +}