Add sharepoint selector boilerplate (#1464)
## Description Adds the boilerplate for sharepoint selectors to the selectors package. Many categories are given filler names (folders, items) and are expected to change through development as we pin down the design for those structures. ## Type of change - [x] 🌻 Feature ## Issue(s) * #1462 ## Test Plan - [x] ⚡ Unit test
This commit is contained in:
parent
20795d3b56
commit
9ac9f8bbe9
@ -17,15 +17,17 @@ type service int
|
||||
|
||||
//go:generate stringer -type=service -linecomment
|
||||
const (
|
||||
ServiceUnknown service = iota // Unknown Service
|
||||
ServiceExchange // Exchange
|
||||
ServiceOneDrive // OneDrive
|
||||
ServiceUnknown service = iota // Unknown Service
|
||||
ServiceExchange // Exchange
|
||||
ServiceOneDrive // OneDrive
|
||||
ServiceSharePoint // SharePoint
|
||||
)
|
||||
|
||||
var serviceToPathType = map[service]path.ServiceType{
|
||||
ServiceUnknown: path.UnknownService,
|
||||
ServiceExchange: path.ExchangeService,
|
||||
ServiceOneDrive: path.OneDriveService,
|
||||
// ServiceSharePoint: path.SharePointService, TODO: add sharepoint to path
|
||||
}
|
||||
|
||||
var (
|
||||
@ -192,6 +194,8 @@ func (s Selector) Reduce(ctx context.Context, deets *details.Details) (*details.
|
||||
r, err = s.ToExchangeRestore()
|
||||
case ServiceOneDrive:
|
||||
r, err = s.ToOneDriveRestore()
|
||||
case ServiceSharePoint:
|
||||
r, err = s.ToSharePointRestore()
|
||||
default:
|
||||
return nil, errors.New("service not supported: " + s.Service.String())
|
||||
}
|
||||
@ -231,6 +235,14 @@ func (s Selector) ToPrintable() Printable {
|
||||
return Printable{}
|
||||
}
|
||||
|
||||
return r.Printable()
|
||||
|
||||
case ServiceSharePoint:
|
||||
r, err := s.ToSharePointBackup()
|
||||
if err != nil {
|
||||
return Printable{}
|
||||
}
|
||||
|
||||
return r.Printable()
|
||||
}
|
||||
|
||||
|
||||
434
src/pkg/selectors/sharepoint.go
Normal file
434
src/pkg/selectors/sharepoint.go
Normal file
@ -0,0 +1,434 @@
|
||||
package selectors
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/filters"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Selectors
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
type (
|
||||
// sharePoint provides an api for selecting
|
||||
// data scopes applicable to the SharePoint service.
|
||||
sharePoint struct {
|
||||
Selector
|
||||
}
|
||||
|
||||
// SharePointBackup provides an api for selecting
|
||||
// data scopes applicable to the SharePoint service,
|
||||
// plus backup-specific methods.
|
||||
SharePointBackup struct {
|
||||
sharePoint
|
||||
}
|
||||
|
||||
// SharePointRestorep provides an api for selecting
|
||||
// data scopes applicable to the SharePoint service,
|
||||
// plus restore-specific methods.
|
||||
SharePointRestore struct {
|
||||
sharePoint
|
||||
}
|
||||
)
|
||||
|
||||
var _ Reducer = &SharePointRestore{}
|
||||
|
||||
// NewSharePointBackup produces a new Selector with the service set to ServiceSharePoint.
|
||||
func NewSharePointBackup() *SharePointBackup {
|
||||
src := SharePointBackup{
|
||||
sharePoint{
|
||||
newSelector(ServiceSharePoint),
|
||||
},
|
||||
}
|
||||
|
||||
return &src
|
||||
}
|
||||
|
||||
// ToSharePointBackup transforms the generic selector into an SharePointBackup.
|
||||
// Errors if the service defined by the selector is not ServiceSharePoint.
|
||||
func (s Selector) ToSharePointBackup() (*SharePointBackup, error) {
|
||||
if s.Service != ServiceSharePoint {
|
||||
return nil, badCastErr(ServiceSharePoint, s.Service)
|
||||
}
|
||||
|
||||
src := SharePointBackup{sharePoint{s}}
|
||||
|
||||
return &src, nil
|
||||
}
|
||||
|
||||
// NewSharePointRestore produces a new Selector with the service set to ServiceSharePoint.
|
||||
func NewSharePointRestore() *SharePointRestore {
|
||||
src := SharePointRestore{
|
||||
sharePoint{
|
||||
newSelector(ServiceSharePoint),
|
||||
},
|
||||
}
|
||||
|
||||
return &src
|
||||
}
|
||||
|
||||
// ToSharePointRestore transforms the generic selector into an SharePointRestore.
|
||||
// Errors if the service defined by the selector is not ServiceSharePoint.
|
||||
func (s Selector) ToSharePointRestore() (*SharePointRestore, error) {
|
||||
if s.Service != ServiceSharePoint {
|
||||
return nil, badCastErr(ServiceSharePoint, s.Service)
|
||||
}
|
||||
|
||||
src := SharePointRestore{sharePoint{s}}
|
||||
|
||||
return &src, nil
|
||||
}
|
||||
|
||||
// Printable creates the minimized display of a selector, formatted for human readability.
|
||||
func (s sharePoint) Printable() Printable {
|
||||
return toPrintable[SharePointScope](s.Selector)
|
||||
}
|
||||
|
||||
// -------------------
|
||||
// Scope Factories
|
||||
|
||||
// Include appends the provided scopes to the selector's inclusion set.
|
||||
// Data is included if it matches ANY inclusion.
|
||||
// The inclusion set is later filtered (all included data must pass ALL
|
||||
// filters) and excluded (all included data must not match ANY exclusion).
|
||||
// Data is included if it matches ANY inclusion (of the same data category).
|
||||
//
|
||||
// All parts of the scope must match for data to be exclucded.
|
||||
// Ex: File(s1, f1, i1) => only excludes an item if it is owned by site s1,
|
||||
// located in folder f1, and ID'd as i1. Use selectors.Any() to wildcard
|
||||
// a scope value. No value will match if selectors.None() is provided.
|
||||
//
|
||||
// Group-level scopes will automatically apply the Any() wildcard to
|
||||
// child properties.
|
||||
// ex: Site(u1) automatically cascades to all folders and files owned
|
||||
// by s1.
|
||||
func (s *sharePoint) Include(scopes ...[]SharePointScope) {
|
||||
s.Includes = appendScopes(s.Includes, scopes...)
|
||||
}
|
||||
|
||||
// Exclude appends the provided scopes to the selector's exclusion set.
|
||||
// Every Exclusion scope applies globally, affecting all inclusion scopes.
|
||||
// Data is excluded if it matches ANY exclusion.
|
||||
//
|
||||
// All parts of the scope must match for data to be exclucded.
|
||||
// Ex: File(s1, f1, i1) => only excludes an item if it is owned by site s1,
|
||||
// located in folder f1, and ID'd as i1. Use selectors.Any() to wildcard
|
||||
// a scope value. No value will match if selectors.None() is provided.
|
||||
//
|
||||
// Group-level scopes will automatically apply the Any() wildcard to
|
||||
// child properties.
|
||||
// ex: Site(u1) automatically cascades to all folders and files owned
|
||||
// by s1.
|
||||
func (s *sharePoint) Exclude(scopes ...[]SharePointScope) {
|
||||
s.Excludes = appendScopes(s.Excludes, scopes...)
|
||||
}
|
||||
|
||||
// Filter appends the provided scopes to the selector's filters set.
|
||||
// A selector with >0 filters and 0 inclusions will include any data
|
||||
// that passes all filters.
|
||||
// A selector with >0 filters and >0 inclusions will reduce the
|
||||
// inclusion set to only the data that passes all filters.
|
||||
// Data is retained if it passes ALL filters.
|
||||
//
|
||||
// All parts of the scope must match for data to be exclucded.
|
||||
// Ex: File(s1, f1, i1) => only excludes an item if it is owned by site s1,
|
||||
// located in folder f1, and ID'd as i1. Use selectors.Any() to wildcard
|
||||
// a scope value. No value will match if selectors.None() is provided.
|
||||
//
|
||||
// Group-level scopes will automatically apply the Any() wildcard to
|
||||
// child properties.
|
||||
// ex: Site(u1) automatically cascades to all folders and files owned
|
||||
// by s1.
|
||||
func (s *sharePoint) Filter(scopes ...[]SharePointScope) {
|
||||
s.Filters = appendScopes(s.Filters, scopes...)
|
||||
}
|
||||
|
||||
// Scopes retrieves the list of sharePointScopes in the selector.
|
||||
func (s *sharePoint) Scopes() []SharePointScope {
|
||||
return scopes[SharePointScope](s.Selector)
|
||||
}
|
||||
|
||||
// DiscreteScopes retrieves the list of sharePointScopes in the selector.
|
||||
// If any Include scope's Site category is set to Any, replaces that
|
||||
// scope's value with the list of siteIDs instead.
|
||||
func (s *sharePoint) DiscreteScopes(siteIDs []string) []SharePointScope {
|
||||
return discreteScopes[SharePointScope](s.Selector, SharePointSite, siteIDs)
|
||||
}
|
||||
|
||||
// -------------------
|
||||
// Scope Factories
|
||||
|
||||
// Produces one or more SharePoint site scopes.
|
||||
// One scope is created per site entry.
|
||||
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
||||
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
||||
// If any slice is empty, it defaults to [selectors.None]
|
||||
func (s *sharePoint) Sites(sites []string) []SharePointScope {
|
||||
scopes := []SharePointScope{}
|
||||
|
||||
scopes = append(scopes, makeScope[SharePointScope](SharePointFolder, sites, Any()))
|
||||
|
||||
return scopes
|
||||
}
|
||||
|
||||
// Folders produces one or more SharePoint folder scopes.
|
||||
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
||||
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
||||
// If any slice is empty, it defaults to [selectors.None]
|
||||
func (s *sharePoint) Folders(sites, folders []string, opts ...option) []SharePointScope {
|
||||
var (
|
||||
scopes = []SharePointScope{}
|
||||
os = append([]option{pathType()}, opts...)
|
||||
)
|
||||
|
||||
scopes = append(
|
||||
scopes,
|
||||
makeScope[SharePointScope](SharePointFolder, sites, folders, os...),
|
||||
)
|
||||
|
||||
return scopes
|
||||
}
|
||||
|
||||
// Items produces one or more SharePoint item scopes.
|
||||
// If any slice contains selectors.Any, that slice is reduced to [selectors.Any]
|
||||
// If any slice contains selectors.None, that slice is reduced to [selectors.None]
|
||||
// If any slice is empty, it defaults to [selectors.None]
|
||||
// options are only applied to the folder scopes.
|
||||
func (s *sharePoint) Items(sites, folders, items []string, opts ...option) []SharePointScope {
|
||||
scopes := []SharePointScope{}
|
||||
|
||||
scopes = append(
|
||||
scopes,
|
||||
makeScope[SharePointScope](SharePointItem, sites, items).
|
||||
set(SharePointFolder, folders, opts...),
|
||||
)
|
||||
|
||||
return scopes
|
||||
}
|
||||
|
||||
// -------------------
|
||||
// Filter Factories
|
||||
|
||||
// WebURL produces a SharePoint item webURL filter scope.
|
||||
// Matches any item where the webURL contains the substring.
|
||||
// If the input equals selectors.Any, the scope will match all times.
|
||||
// If the input is empty or selectors.None, the scope will always fail comparisons.
|
||||
func (s *sharePoint) WebURL(substring string) []SharePointScope {
|
||||
return []SharePointScope{
|
||||
makeFilterScope[SharePointScope](
|
||||
SharePointItem,
|
||||
SharePointFilterWebURL,
|
||||
[]string{substring},
|
||||
wrapFilter(filters.Less)),
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Categories
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// sharePointCategory enumerates the type of the lowest level
|
||||
// of data () in a scope.
|
||||
type sharePointCategory string
|
||||
|
||||
// interface compliance checks
|
||||
var _ categorizer = SharePointCategoryUnknown
|
||||
|
||||
const (
|
||||
SharePointCategoryUnknown sharePointCategory = ""
|
||||
// types of data identified by SharePoint
|
||||
SharePointSite sharePointCategory = "SharePointSitte"
|
||||
SharePointFolder sharePointCategory = "SharePointFolder"
|
||||
SharePointItem sharePointCategory = "SharePointItem"
|
||||
|
||||
// filterable topics identified by SharePoint
|
||||
SharePointFilterWebURL sharePointCategory = "SharePointFilterWebURL"
|
||||
)
|
||||
|
||||
// sharePointLeafProperties describes common metadata of the leaf categories
|
||||
var sharePointLeafProperties = map[categorizer]leafProperty{
|
||||
SharePointItem: {
|
||||
pathKeys: []categorizer{SharePointSite, SharePointFolder, SharePointItem},
|
||||
pathType: path.FilesCategory,
|
||||
},
|
||||
SharePointSite: { // the root category must be represented, even though it isn't a leaf
|
||||
pathKeys: []categorizer{SharePointSite},
|
||||
pathType: path.UnknownCategory,
|
||||
},
|
||||
}
|
||||
|
||||
func (c sharePointCategory) String() string {
|
||||
return string(c)
|
||||
}
|
||||
|
||||
// leafCat returns the leaf category of the receiver.
|
||||
// If the receiver category has multiple leaves (ex: User) or no leaves,
|
||||
// (ex: Unknown), the receiver itself is returned.
|
||||
// Ex: ServiceTypeFolder.leafCat() => ServiceTypeItem
|
||||
// Ex: ServiceUser.leafCat() => ServiceUser
|
||||
func (c sharePointCategory) leafCat() categorizer {
|
||||
switch c {
|
||||
case SharePointFolder, SharePointItem,
|
||||
SharePointFilterWebURL:
|
||||
return SharePointItem
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// rootCat returns the root category type.
|
||||
func (c sharePointCategory) rootCat() categorizer {
|
||||
return SharePointSite
|
||||
}
|
||||
|
||||
// unknownCat returns the unknown category type.
|
||||
func (c sharePointCategory) unknownCat() categorizer {
|
||||
return SharePointCategoryUnknown
|
||||
}
|
||||
|
||||
// isLeaf is true if the category is a SharePointItem category.
|
||||
func (c sharePointCategory) isLeaf() bool {
|
||||
// return c == c.leafCat()??
|
||||
return c == SharePointItem
|
||||
}
|
||||
|
||||
// pathValues transforms a path to a map of identified properties.
|
||||
//
|
||||
// Example:
|
||||
// [tenantID, service, siteID, category, folder, itemID]
|
||||
// => {spSite: siteID, spFolder: folder, spItemID: itemID}
|
||||
func (c sharePointCategory) pathValues(p path.Path) map[categorizer]string {
|
||||
return map[categorizer]string{
|
||||
SharePointSite: p.ResourceOwner(),
|
||||
SharePointFolder: p.Folder(),
|
||||
SharePointItem: p.Item(),
|
||||
}
|
||||
}
|
||||
|
||||
// pathKeys returns the path keys recognized by the receiver's leaf type.
|
||||
func (c sharePointCategory) pathKeys() []categorizer {
|
||||
return sharePointLeafProperties[c.leafCat()].pathKeys
|
||||
}
|
||||
|
||||
// PathType converts the category's leaf type into the matching path.CategoryType.
|
||||
func (c sharePointCategory) PathType() path.CategoryType {
|
||||
return sharePointLeafProperties[c.leafCat()].pathType
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Scopes
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// SharePointScope specifies the data available
|
||||
// when interfacing with the SharePoint service.
|
||||
type SharePointScope scope
|
||||
|
||||
// interface compliance checks
|
||||
var _ scoper = &SharePointScope{}
|
||||
|
||||
// Category describes the type of the data in scope.
|
||||
func (s SharePointScope) Category() sharePointCategory {
|
||||
return sharePointCategory(getCategory(s))
|
||||
}
|
||||
|
||||
// categorizer type is a generic wrapper around Category.
|
||||
// Primarily used by scopes.go to for abstract comparisons.
|
||||
func (s SharePointScope) categorizer() categorizer {
|
||||
return s.Category()
|
||||
}
|
||||
|
||||
// FilterCategory returns the category enum of the scope filter.
|
||||
// If the scope is not a filter type, returns SharePointUnknownCategory.
|
||||
func (s SharePointScope) FilterCategory() sharePointCategory {
|
||||
return sharePointCategory(getFilterCategory(s))
|
||||
}
|
||||
|
||||
// IncludeCategory checks whether the scope includes a
|
||||
// certain category of data.
|
||||
// Ex: to check if the scope includes file data:
|
||||
// s.IncludesCategory(selector.SharePointFile)
|
||||
func (s SharePointScope) IncludesCategory(cat sharePointCategory) bool {
|
||||
return categoryMatches(s.Category(), cat)
|
||||
}
|
||||
|
||||
// Matches returns true if the category is included in the scope's
|
||||
// data type, and the target string matches that category's comparator.
|
||||
func (s SharePointScope) Matches(cat sharePointCategory, target string) bool {
|
||||
return matches(s, cat, target)
|
||||
}
|
||||
|
||||
// returns true if the category is included in the scope's data type,
|
||||
// and the value is set to Any().
|
||||
func (s SharePointScope) IsAny(cat sharePointCategory) bool {
|
||||
return isAnyTarget(s, cat)
|
||||
}
|
||||
|
||||
// Get returns the data category in the scope. If the scope
|
||||
// contains all data types for a user, it'll return the
|
||||
// SharePointUser category.
|
||||
func (s SharePointScope) Get(cat sharePointCategory) []string {
|
||||
return getCatValue(s, cat)
|
||||
}
|
||||
|
||||
// sets a value by category to the scope. Only intended for internal use.
|
||||
func (s SharePointScope) set(cat sharePointCategory, v []string, opts ...option) SharePointScope {
|
||||
os := []option{}
|
||||
if cat == SharePointFolder {
|
||||
os = append(os, pathType())
|
||||
}
|
||||
|
||||
return set(s, cat, v, append(os, opts...)...)
|
||||
}
|
||||
|
||||
// setDefaults ensures that site scopes express `AnyTgt` for their child category types.
|
||||
func (s SharePointScope) setDefaults() {
|
||||
switch s.Category() {
|
||||
case SharePointSite:
|
||||
s[SharePointFolder.String()] = passAny
|
||||
s[SharePointItem.String()] = passAny
|
||||
case SharePointFolder:
|
||||
s[SharePointItem.String()] = passAny
|
||||
}
|
||||
}
|
||||
|
||||
// matchesInfo handles the standard behavior when comparing a scope and an sharePointInfo
|
||||
// returns true if the scope and info match for the provided category.
|
||||
func (s SharePointScope) matchesInfo(dii details.ItemInfo) bool {
|
||||
// info := dii.SharePoint
|
||||
// if info == nil {
|
||||
// return false
|
||||
// }
|
||||
var (
|
||||
filterCat = s.FilterCategory()
|
||||
i = ""
|
||||
)
|
||||
|
||||
// switch filterCat {
|
||||
// case FileFilterCreatedAfter, FileFilterCreatedBefore:
|
||||
// i = common.FormatTime(info.Created)
|
||||
// case FileFilterModifiedAfter, FileFilterModifiedBefore:
|
||||
// i = common.FormatTime(info.Modified)
|
||||
// }
|
||||
|
||||
return s.Matches(filterCat, i)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Backup Details Filtering
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Reduce filters the entries in a details struct to only those that match the
|
||||
// inclusions, filters, and exclusions in the selector.
|
||||
func (s sharePoint) Reduce(ctx context.Context, deets *details.Details) *details.Details {
|
||||
return reduce[SharePointScope](
|
||||
ctx,
|
||||
deets,
|
||||
s.Selector,
|
||||
map[path.CategoryType]sharePointCategory{
|
||||
// path.FilesCategory: SharePointItem,
|
||||
},
|
||||
)
|
||||
}
|
||||
336
src/pkg/selectors/sharepoint_test.go
Normal file
336
src/pkg/selectors/sharepoint_test.go
Normal file
@ -0,0 +1,336 @@
|
||||
package selectors
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type SharePointSelectorSuite struct {
|
||||
suite.Suite
|
||||
}
|
||||
|
||||
func TestSharePointSelectorSuite(t *testing.T) {
|
||||
suite.Run(t, new(SharePointSelectorSuite))
|
||||
}
|
||||
|
||||
func (suite *SharePointSelectorSuite) TestNewSharePointBackup() {
|
||||
t := suite.T()
|
||||
ob := NewSharePointBackup()
|
||||
assert.Equal(t, ob.Service, ServiceSharePoint)
|
||||
assert.NotZero(t, ob.Scopes())
|
||||
}
|
||||
|
||||
func (suite *SharePointSelectorSuite) TestToSharePointBackup() {
|
||||
t := suite.T()
|
||||
ob := NewSharePointBackup()
|
||||
s := ob.Selector
|
||||
ob, err := s.ToSharePointBackup()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, ob.Service, ServiceSharePoint)
|
||||
assert.NotZero(t, ob.Scopes())
|
||||
}
|
||||
|
||||
func (suite *SharePointSelectorSuite) TestSharePointBackup_DiscreteScopes() {
|
||||
sites := []string{"s1", "s2"}
|
||||
table := []struct {
|
||||
name string
|
||||
include []string
|
||||
discrete []string
|
||||
expect []string
|
||||
}{
|
||||
{
|
||||
name: "any site",
|
||||
include: Any(),
|
||||
discrete: sites,
|
||||
expect: sites,
|
||||
},
|
||||
{
|
||||
name: "discrete sitet",
|
||||
include: []string{"s3"},
|
||||
discrete: sites,
|
||||
expect: []string{"s3"},
|
||||
},
|
||||
{
|
||||
name: "nil discrete slice",
|
||||
include: Any(),
|
||||
discrete: nil,
|
||||
expect: Any(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range table {
|
||||
suite.T().Run(test.name, func(t *testing.T) {
|
||||
eb := NewSharePointBackup()
|
||||
eb.Include(eb.Sites(test.include))
|
||||
|
||||
scopes := eb.DiscreteScopes(test.discrete)
|
||||
for _, sc := range scopes {
|
||||
sites := sc.Get(SharePointSite)
|
||||
assert.Equal(t, test.expect, sites)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *SharePointSelectorSuite) TestSharePointSelector_Sites() {
|
||||
t := suite.T()
|
||||
sel := NewSharePointBackup()
|
||||
|
||||
const (
|
||||
s1 = "s1"
|
||||
s2 = "s2"
|
||||
)
|
||||
|
||||
siteScopes := sel.Sites([]string{s1, s2})
|
||||
for _, scope := range siteScopes {
|
||||
// Scope value is either s1 or s2
|
||||
assert.Contains(t, join(s1, s2), scope[SharePointSite.String()].Target)
|
||||
}
|
||||
|
||||
// Initialize the selector Include, Exclude, Filter
|
||||
sel.Exclude(siteScopes)
|
||||
sel.Include(siteScopes)
|
||||
sel.Filter(siteScopes)
|
||||
|
||||
table := []struct {
|
||||
name string
|
||||
scopesToCheck []scope
|
||||
}{
|
||||
{"Include Scopes", sel.Includes},
|
||||
{"Exclude Scopes", sel.Excludes},
|
||||
{"Filter Scopes", sel.Filters},
|
||||
}
|
||||
for _, test := range table {
|
||||
suite.T().Run(test.name, func(t *testing.T) {
|
||||
require.Len(t, test.scopesToCheck, 1)
|
||||
for _, scope := range test.scopesToCheck {
|
||||
// Scope value is s1,s2
|
||||
assert.Contains(t, join(s1, s2), scope[SharePointSite.String()].Target)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *SharePointSelectorSuite) TestSharePointSelector_Include_Sites() {
|
||||
t := suite.T()
|
||||
sel := NewSharePointBackup()
|
||||
|
||||
const (
|
||||
s1 = "s1"
|
||||
s2 = "s2"
|
||||
)
|
||||
|
||||
sel.Include(sel.Sites([]string{s1, s2}))
|
||||
scopes := sel.Includes
|
||||
require.Len(t, scopes, 1)
|
||||
|
||||
for _, sc := range scopes {
|
||||
scopeMustHave(
|
||||
t,
|
||||
SharePointScope(sc),
|
||||
map[categorizer]string{SharePointSite: join(s1, s2)},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *SharePointSelectorSuite) TestSharePointSelector_Exclude_Sites() {
|
||||
t := suite.T()
|
||||
sel := NewSharePointBackup()
|
||||
|
||||
const (
|
||||
s1 = "s1"
|
||||
s2 = "s2"
|
||||
)
|
||||
|
||||
sel.Exclude(sel.Sites([]string{s1, s2}))
|
||||
scopes := sel.Excludes
|
||||
require.Len(t, scopes, 1)
|
||||
|
||||
for _, sc := range scopes {
|
||||
scopeMustHave(
|
||||
t,
|
||||
SharePointScope(sc),
|
||||
map[categorizer]string{SharePointSite: join(s1, s2)},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *SharePointSelectorSuite) TestNewSharePointRestore() {
|
||||
t := suite.T()
|
||||
or := NewSharePointRestore()
|
||||
assert.Equal(t, or.Service, ServiceSharePoint)
|
||||
assert.NotZero(t, or.Scopes())
|
||||
}
|
||||
|
||||
func (suite *SharePointSelectorSuite) TestToSharePointRestore() {
|
||||
t := suite.T()
|
||||
eb := NewSharePointRestore()
|
||||
s := eb.Selector
|
||||
or, err := s.ToSharePointRestore()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, or.Service, ServiceSharePoint)
|
||||
assert.NotZero(t, or.Scopes())
|
||||
}
|
||||
|
||||
// TODO: enable when sharepoint has path and detail representation
|
||||
// func (suite *SharePointSelectorSuite) TestSharePointRestore_Reduce() {
|
||||
// var (
|
||||
// item = stubRepoRef(path.SharePointService, path.SharePointItemsCategory, "uid", "/folderA/folderB", "item")
|
||||
// item2 = stubRepoRef(path.SharePointService, path.SharePointItemsCategory, "uid", "/folderA/folderC", "item2")
|
||||
// item3 = stubRepoRef(path.SharePointService, path.SharePointItemsCategory, "uid", "/folderD/folderE", "item3")
|
||||
// )
|
||||
|
||||
// deets := &details.Details{
|
||||
// DetailsModel: details.DetailsModel{
|
||||
// Entries: []details.DetailsEntry{
|
||||
// {
|
||||
// RepoRef: item,
|
||||
// ItemInfo: details.ItemInfo{
|
||||
// SharePoint: &details.SharePointInfo{
|
||||
// ItemType: details.SharePointItem,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// RepoRef: item2,
|
||||
// ItemInfo: details.ItemInfo{
|
||||
// SharePoint: &details.SharePointInfo{
|
||||
// ItemType: details.SharePointItem,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// RepoRef: item3,
|
||||
// ItemInfo: details.ItemInfo{
|
||||
// SharePoint: &details.SharePointInfo{
|
||||
// ItemType: details.SharePointItem,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
|
||||
// arr := func(s ...string) []string {
|
||||
// return s
|
||||
// }
|
||||
|
||||
// table := []struct {
|
||||
// name string
|
||||
// deets *details.Details
|
||||
// makeSelector func() *SharePointRestore
|
||||
// expect []string
|
||||
// }{
|
||||
// {
|
||||
// "all",
|
||||
// deets,
|
||||
// func() *SharePointRestore {
|
||||
// odr := NewSharePointRestore()
|
||||
// odr.Include(odr.Sites(Any()))
|
||||
// return odr
|
||||
// },
|
||||
// arr(item, item2, item3),
|
||||
// },
|
||||
// {
|
||||
// "only match item",
|
||||
// deets,
|
||||
// func() *SharePointRestore {
|
||||
// odr := NewSharePointRestore()
|
||||
// odr.Include(odr.Items(Any(), Any(), []string{"item2"}))
|
||||
// return odr
|
||||
// },
|
||||
// arr(item2),
|
||||
// },
|
||||
// {
|
||||
// "only match folder",
|
||||
// deets,
|
||||
// func() *SharePointRestore {
|
||||
// odr := NewSharePointRestore()
|
||||
// odr.Include(odr.Folders([]string{"uid"}, []string{"folderA/folderB", "folderA/folderC"}))
|
||||
// return odr
|
||||
// },
|
||||
// arr(item, item2),
|
||||
// },
|
||||
// }
|
||||
// for _, test := range table {
|
||||
// suite.T().Run(test.name, func(t *testing.T) {
|
||||
// ctx, flush := tester.NewContext()
|
||||
// defer flush()
|
||||
|
||||
// sel := test.makeSelector()
|
||||
// results := sel.Reduce(ctx, test.deets)
|
||||
// paths := results.Paths()
|
||||
// assert.Equal(t, test.expect, paths)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
// func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() {
|
||||
// t := suite.T()
|
||||
|
||||
// pathBuilder := path.Builder{}.Append("dir1", "dir2", "item")
|
||||
// itemPath, err := pathBuilder.ToDataLayerSharePointPath("tenant", "site", true)
|
||||
// require.NoError(t, err)
|
||||
|
||||
// expected := map[categorizer]string{
|
||||
// SharePointSite: "site",
|
||||
// SharePointFolder: "dir1/dir2",
|
||||
// SharePointItem: "item",
|
||||
// }
|
||||
|
||||
// assert.Equal(t, expected, SharePointItem.pathValues(itemPath))
|
||||
// }
|
||||
|
||||
// func (suite *SharePointSelectorSuite) TestSharePointScope_MatchesInfo() {
|
||||
// ods := NewSharePointRestore()
|
||||
|
||||
// var (
|
||||
// url = "www.website.com"
|
||||
// )
|
||||
|
||||
// itemInfo := details.ItemInfo{
|
||||
// SharePoint: &details.SharepointInfo{
|
||||
// ItemType: details.SharePointItem,
|
||||
// WebURL: "www.website.com",
|
||||
// },
|
||||
// }
|
||||
|
||||
// table := []struct {
|
||||
// name string
|
||||
// scope []SharePointScope
|
||||
// expect assert.BoolAssertionFunc
|
||||
// }{
|
||||
// {"item webURL match", ods.WebURL(url), assert.True},
|
||||
// {"item webURL substring", ods.WebURL("website"), assert.True},
|
||||
// {"item webURL mismatch", ods.WebURL("google"), assert.False},
|
||||
// }
|
||||
// for _, test := range table {
|
||||
// suite.T().Run(test.name, func(t *testing.T) {
|
||||
// scopes := setScopesToDefault(test.scope)
|
||||
// for _, scope := range scopes {
|
||||
// test.expect(t, scope.matchesInfo(itemInfo))
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
// func (suite *SharePointSelectorSuite) TestCategory_PathType() {
|
||||
// table := []struct {
|
||||
// cat sharePointCategory
|
||||
// pathType path.CategoryType
|
||||
// }{
|
||||
// {SharePointCategoryUnknown, path.UnknownCategory},
|
||||
// {SharePointSite, path.UnknownCategory},
|
||||
// {SharePointFolder, path.SharePointItemCategory},
|
||||
// {SharePointItem, path.SharePointItemCategory},
|
||||
// {SharePointFilterWebURL, path.SharePointItemCategory},
|
||||
// }
|
||||
// for _, test := range table {
|
||||
// suite.T().Run(test.cat.String(), func(t *testing.T) {
|
||||
// assert.Equal(t, test.pathType, test.cat.PathType())
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
Loading…
x
Reference in New Issue
Block a user