Onedrive selectors (#594)

## Description

Introduces OneDrive selectors - currently only users are supported.

## Type of change

Please check the type of change your PR introduces:
- [x] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Test
- [ ] 🐹 Trivial/Minor

## Issue(s)
- #388  

## Test Plan

<!-- How will this be tested prior to merging.-->

- [ ] 💪 Manual
- [x]  Unit test
- [ ] 💚 E2E
This commit is contained in:
Vaibhav Kamra 2022-08-18 17:00:28 -07:00 committed by GitHub
parent 8fd867745f
commit c3c361282d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 209 additions and 0 deletions

View File

@ -0,0 +1,112 @@
package selectors
// ---------------------------------------------------------------------------
// Selectors
// ---------------------------------------------------------------------------
type (
// onedrive provides an api for selecting
// data scopes applicable to the OneDrive service.
onedrive struct {
Selector
}
// OneDriveBackup provides an api for selecting
// data scopes applicable to the OneDrive service,
// plus backup-specific methods.
OneDriveBackup struct {
onedrive
}
)
// NewOneDriveBackup produces a new Selector with the service set to ServiceOneDrive.
func NewOneDriveBackup() *OneDriveBackup {
src := OneDriveBackup{
onedrive{
newSelector(ServiceOneDrive),
},
}
return &src
}
// ToOneDriveBackup transforms the generic selector into an OneDriveBackup.
// Errors if the service defined by the selector is not ServiceOneDrive.
func (s Selector) ToOneDriveBackup() (*OneDriveBackup, error) {
if s.Service != ServiceOneDrive {
return nil, badCastErr(ServiceOneDrive, s.Service)
}
src := OneDriveBackup{onedrive{s}}
return &src, nil
}
// ---------------------------------------------------------------------------
// Scopes
// ---------------------------------------------------------------------------
type (
// OneDriveScope specifies the data available
// when interfacing with the OneDrive service.
OneDriveScope scope
// onedriveCategory enumerates the type of the lowest level
// of data () in a scope.
onedriveCategory int
)
//go:generate go run golang.org/x/tools/cmd/stringer -type=onedriveCategory
const (
OneDriveCategoryUnknown onedriveCategory = iota
// types of data identified by OneDrive
OneDriveUser
)
// Scopes retrieves the list of onedriveScopes in the selector.
func (s *onedrive) Scopes() []OneDriveScope {
scopes := []OneDriveScope{}
for _, v := range s.Includes {
scopes = append(scopes, OneDriveScope(v))
}
return scopes
}
// Get returns the data category in the scope. If the scope
// contains all data types for a user, it'll return the
// OneDriveUser category.
func (s OneDriveScope) Get(cat onedriveCategory) []string {
v, ok := s[cat.String()]
if !ok {
return None()
}
return split(v)
}
// Produces one or more onedrive user scopes.
// One scope is created per user 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 *onedrive) Users(users []string) []OneDriveScope {
users = normalize(users)
scopes := []OneDriveScope{}
for _, u := range users {
userScope := OneDriveScope{
OneDriveUser.String(): u,
}
scopes = append(scopes, userScope)
}
return scopes
}
// nop-transform method
func nopTransform(sl []OneDriveScope) []OneDriveScope { return sl }
func (s *onedrive) Include(scopes ...[]OneDriveScope) {
appendIncludes(&s.Selector, nopTransform, scopes...)
}
func (s *onedrive) Exclude(scopes ...[]OneDriveScope) {
appendExcludes(&s.Selector, nopTransform, scopes...)
}
func (s *onedrive) Filter(scopes ...[]OneDriveScope) {
appendFilters(&s.Selector, nopTransform, scopes...)
}

View File

@ -0,0 +1,72 @@
package selectors
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
type OnedriveSourceSuite struct {
suite.Suite
}
func TestOnedriveSourceSuite(t *testing.T) {
suite.Run(t, new(OnedriveSourceSuite))
}
func (suite *OnedriveSourceSuite) TestNewOnedriveBackup() {
t := suite.T()
ob := NewOneDriveBackup()
assert.Equal(t, ob.Service, ServiceOneDrive)
assert.NotZero(t, ob.Scopes())
}
func (suite *OnedriveSourceSuite) TestToOnedriveBackup() {
t := suite.T()
ob := NewOneDriveBackup()
s := ob.Selector
ob, err := s.ToOneDriveBackup()
require.NoError(t, err)
assert.Equal(t, ob.Service, ServiceOneDrive)
assert.NotZero(t, ob.Scopes())
}
func (suite *OnedriveSourceSuite) TestOnedriveSelector_Users() {
t := suite.T()
sel := NewOneDriveBackup()
const (
u1 = "u1"
u2 = "u2"
)
userScopes := sel.Users([]string{u1, u2})
for _, scope := range userScopes {
// Scope value is either u1 or u2
assert.Contains(t, []string{u1, u2}, scope[OneDriveUser.String()])
}
// Initialize the selector Include, Exclude, Filter
sel.Exclude(userScopes)
sel.Include(userScopes)
sel.Filter(userScopes)
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.Equal(t, 2, len(test.scopesToCheck))
for _, scope := range test.scopesToCheck {
// Scope value is either u1 or u2
assert.Contains(t, []string{u1, u2}, scope[OneDriveUser.String()])
}
})
}
}

View File

@ -0,0 +1,24 @@
// Code generated by "stringer -type=onedriveCategory"; DO NOT EDIT.
package selectors
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[OneDriveCategoryUnknown-0]
_ = x[OneDriveUser-1]
}
const _onedriveCategory_name = "OneDriveCategoryUnknownOneDriveUser"
var _onedriveCategory_index = [...]uint8{0, 23, 35}
func (i onedriveCategory) String() string {
if i < 0 || i >= onedriveCategory(len(_onedriveCategory_index)-1) {
return "onedriveCategory(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _onedriveCategory_name[_onedriveCategory_index[i]:_onedriveCategory_index[i+1]]
}

View File

@ -14,6 +14,7 @@ type service int
const ( const (
ServiceUnknown service = iota // Unknown Service ServiceUnknown service = iota // Unknown Service
ServiceExchange // Exchange ServiceExchange // Exchange
ServiceOneDrive // OneDrive
) )
var ErrorBadSelectorCast = errors.New("wrong selector service type") var ErrorBadSelectorCast = errors.New("wrong selector service type")