reduce restore point details to matching refs (#310)
* reduce restore point details to matching refs A selector should be able to reduce a set of restore point details to only those that pass its inclusion and exclusion rules.
This commit is contained in:
parent
2415addd05
commit
80db9a56c7
@ -1,5 +1,11 @@
|
|||||||
package selectors
|
package selectors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/pkg/backup"
|
||||||
|
)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Selectors
|
// Selectors
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -298,3 +304,191 @@ func (s exchangeScope) Get(cat exchangeCategory) []string {
|
|||||||
}
|
}
|
||||||
return split(v)
|
return split(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var categoryPathSet = map[exchangeCategory][]exchangeCategory{
|
||||||
|
ExchangeContact: {ExchangeUser, ExchangeContactFolder, ExchangeContact},
|
||||||
|
ExchangeEvent: {ExchangeUser, ExchangeEvent},
|
||||||
|
ExchangeMail: {ExchangeUser, ExchangeMailFolder, ExchangeMail},
|
||||||
|
}
|
||||||
|
|
||||||
|
// includesPath returns true if all filters in the scope match the path.
|
||||||
|
func (s exchangeScope) includesPath(cat exchangeCategory, path []string) bool {
|
||||||
|
ids := idPath(cat, path)
|
||||||
|
for _, c := range categoryPathSet[cat] {
|
||||||
|
target := s.Get(c)
|
||||||
|
if len(target) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
id, ok := ids[c]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if target[0] != All && !contains(target, id) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// excludesPath returns true if all filters in the scope match the path.
|
||||||
|
func (s exchangeScope) excludesPath(cat exchangeCategory, path []string) bool {
|
||||||
|
ids := idPath(cat, path)
|
||||||
|
for _, c := range categoryPathSet[cat] {
|
||||||
|
target := s.Get(c)
|
||||||
|
if len(target) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
id, ok := ids[c]
|
||||||
|
if !ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if target[0] == All || contains(target, id) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// temporary helper until filters replace string values for scopes.
|
||||||
|
func contains(super []string, sub string) bool {
|
||||||
|
for _, s := range super {
|
||||||
|
if s == sub {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Restore Point Filtering
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// transforms a path to a map of identified properties.
|
||||||
|
// Malformed (ie, short len) paths will return incomplete results.
|
||||||
|
// Example:
|
||||||
|
// [tenantID, userID, "mail", mailFolder, mailID]
|
||||||
|
// => {exchUser: userID, exchMailFolder: mailFolder, exchMail: mailID}
|
||||||
|
func idPath(cat exchangeCategory, path []string) map[exchangeCategory]string {
|
||||||
|
m := map[exchangeCategory]string{}
|
||||||
|
if len(path) == 0 {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
m[ExchangeUser] = path[1]
|
||||||
|
/*
|
||||||
|
TODO/Notice:
|
||||||
|
Mail and Contacts contain folder structures, identified
|
||||||
|
in this code as being at index 3. This assumes a single
|
||||||
|
folder, while in reality users can express subfolder
|
||||||
|
hierarchies of arbirary depth. Subfolder handling is coming
|
||||||
|
at a later time.
|
||||||
|
*/
|
||||||
|
switch cat {
|
||||||
|
case ExchangeContact:
|
||||||
|
if len(path) < 5 {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
m[ExchangeContactFolder] = path[3]
|
||||||
|
m[ExchangeContact] = path[4]
|
||||||
|
case ExchangeEvent:
|
||||||
|
if len(path) < 4 {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
m[ExchangeEvent] = path[3]
|
||||||
|
case ExchangeMail:
|
||||||
|
if len(path) < 5 {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
m[ExchangeMailFolder] = path[3]
|
||||||
|
m[ExchangeMail] = path[4]
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterDetails reduces the entries in a backupDetails struct to only
|
||||||
|
// those that match the inclusions and exclusions in the selector.
|
||||||
|
func (s *ExchangeRestore) FilterDetails(deets *backup.Details) []string {
|
||||||
|
if deets == nil {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
entIncs := exchangeScopesByCategory(s.Includes)
|
||||||
|
entExcs := exchangeScopesByCategory(s.Excludes)
|
||||||
|
|
||||||
|
refs := []string{}
|
||||||
|
|
||||||
|
for _, ent := range deets.Entries {
|
||||||
|
path := strings.Split(ent.RepoRef, "/")
|
||||||
|
// not all paths will be len=3. Most should be longer.
|
||||||
|
// This just protects us from panicing four lines later.
|
||||||
|
if len(path) < 3 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var cat exchangeCategory
|
||||||
|
switch path[2] {
|
||||||
|
case "contact":
|
||||||
|
cat = ExchangeContact
|
||||||
|
case "event":
|
||||||
|
cat = ExchangeEvent
|
||||||
|
case "mail":
|
||||||
|
cat = ExchangeMail
|
||||||
|
}
|
||||||
|
matched := matchExchangeEntry(
|
||||||
|
cat,
|
||||||
|
path,
|
||||||
|
entIncs[cat.String()],
|
||||||
|
entExcs[cat.String()])
|
||||||
|
if matched {
|
||||||
|
refs = append(refs, ent.RepoRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return refs
|
||||||
|
}
|
||||||
|
|
||||||
|
// groups each scope by its category of data (contact, event, or mail).
|
||||||
|
// user-level scopes will duplicate to all three categories.
|
||||||
|
func exchangeScopesByCategory(scopes []map[string]string) map[string][]exchangeScope {
|
||||||
|
m := map[string][]exchangeScope{
|
||||||
|
ExchangeContact.String(): {},
|
||||||
|
ExchangeEvent.String(): {},
|
||||||
|
ExchangeMail.String(): {},
|
||||||
|
}
|
||||||
|
for _, msc := range scopes {
|
||||||
|
sc := exchangeScope(msc)
|
||||||
|
if sc.IncludesCategory(ExchangeContact) {
|
||||||
|
m[ExchangeContact.String()] = append(m[ExchangeContact.String()], sc)
|
||||||
|
}
|
||||||
|
if sc.IncludesCategory(ExchangeEvent) {
|
||||||
|
m[ExchangeEvent.String()] = append(m[ExchangeEvent.String()], sc)
|
||||||
|
}
|
||||||
|
if sc.IncludesCategory(ExchangeMail) {
|
||||||
|
m[ExchangeMail.String()] = append(m[ExchangeMail.String()], sc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// compare each path to the included and excluded exchange scopes. Returns true
|
||||||
|
// if the path is included, and not excluded.
|
||||||
|
func matchExchangeEntry(cat exchangeCategory, path []string, incs, excs []exchangeScope) bool {
|
||||||
|
var included bool
|
||||||
|
for _, inc := range incs {
|
||||||
|
if inc.includesPath(cat, path) {
|
||||||
|
included = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !included {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var excluded bool
|
||||||
|
for _, exc := range excs {
|
||||||
|
if exc.excludesPath(cat, path) {
|
||||||
|
excluded = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !excluded
|
||||||
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package selectors
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/pkg/backup"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
@ -476,3 +477,357 @@ func (suite *ExchangeSourceSuite) TestExchangeScope_Get() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *ExchangeSourceSuite) TestExchangeScope_IncludesPath() {
|
||||||
|
const (
|
||||||
|
usr = "userID"
|
||||||
|
fld = "mailFolder"
|
||||||
|
mail = "mailID"
|
||||||
|
)
|
||||||
|
var (
|
||||||
|
path = []string{"tid", usr, "mail", fld, mail}
|
||||||
|
es = NewExchangeRestore("rpid")
|
||||||
|
)
|
||||||
|
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
scope exchangeScope
|
||||||
|
expect assert.BoolAssertionFunc
|
||||||
|
}{
|
||||||
|
{"all user's items", es.Users(All), assert.True},
|
||||||
|
{"no user's items", es.Users(None), assert.False},
|
||||||
|
{"matching user", es.Users(usr), assert.True},
|
||||||
|
{"non-maching user", es.Users("smarf"), assert.False},
|
||||||
|
{"one of multiple users", es.Users("smarf", usr), assert.True},
|
||||||
|
{"all folders", es.MailFolders(All, All), assert.True},
|
||||||
|
{"no folders", es.MailFolders(All, None), assert.False},
|
||||||
|
{"matching folder", es.MailFolders(All, fld), assert.True},
|
||||||
|
{"non-matching folder", es.MailFolders(All, "smarf"), assert.False},
|
||||||
|
{"one of multiple folders", es.MailFolders(All, "smarf", fld), assert.True},
|
||||||
|
{"all mail", es.Mails(All, All, All), assert.True},
|
||||||
|
{"no mail", es.Mails(All, All, None), assert.False},
|
||||||
|
{"matching mail", es.Mails(All, All, mail), assert.True},
|
||||||
|
{"non-matching mail", es.Mails(All, All, "smarf"), assert.False},
|
||||||
|
{"one of multiple mails", es.Mails(All, All, "smarf", mail), assert.True},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
|
scope := extendExchangeScopeValues(All, test.scope)
|
||||||
|
test.expect(t, scope.includesPath(ExchangeMail, path))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *ExchangeSourceSuite) TestExchangeScope_ExcludesPath() {
|
||||||
|
const (
|
||||||
|
usr = "userID"
|
||||||
|
fld = "mailFolder"
|
||||||
|
mail = "mailID"
|
||||||
|
)
|
||||||
|
var (
|
||||||
|
path = []string{"tid", usr, "mail", fld, mail}
|
||||||
|
es = NewExchangeRestore("rpid")
|
||||||
|
)
|
||||||
|
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
scope exchangeScope
|
||||||
|
expect assert.BoolAssertionFunc
|
||||||
|
}{
|
||||||
|
{"all user's items", es.Users(All), assert.True},
|
||||||
|
{"no user's items", es.Users(None), assert.False},
|
||||||
|
{"matching user", es.Users(usr), assert.True},
|
||||||
|
{"non-maching user", es.Users("smarf"), assert.False},
|
||||||
|
{"one of multiple users", es.Users("smarf", usr), assert.True},
|
||||||
|
{"all folders", es.MailFolders(None, All), assert.True},
|
||||||
|
{"no folders", es.MailFolders(None, None), assert.False},
|
||||||
|
{"matching folder", es.MailFolders(None, fld), assert.True},
|
||||||
|
{"non-matching folder", es.MailFolders(None, "smarf"), assert.False},
|
||||||
|
{"one of multiple folders", es.MailFolders(None, "smarf", fld), assert.True},
|
||||||
|
{"all mail", es.Mails(None, None, All), assert.True},
|
||||||
|
{"no mail", es.Mails(None, None, None), assert.False},
|
||||||
|
{"matching mail", es.Mails(None, None, mail), assert.True},
|
||||||
|
{"non-matching mail", es.Mails(None, None, "smarf"), assert.False},
|
||||||
|
{"one of multiple mails", es.Mails(None, None, "smarf", mail), assert.True},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
|
scope := extendExchangeScopeValues(None, test.scope)
|
||||||
|
test.expect(t, scope.excludesPath(ExchangeMail, path))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *ExchangeSourceSuite) TestIdPath() {
|
||||||
|
table := []struct {
|
||||||
|
cat exchangeCategory
|
||||||
|
path []string
|
||||||
|
expect map[exchangeCategory]string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
ExchangeContact,
|
||||||
|
[]string{"tid", "uid", "contact", "cFld", "cid"},
|
||||||
|
map[exchangeCategory]string{
|
||||||
|
ExchangeUser: "uid",
|
||||||
|
ExchangeContactFolder: "cFld",
|
||||||
|
ExchangeContact: "cid",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ExchangeEvent,
|
||||||
|
[]string{"tid", "uid", "event", "eid"},
|
||||||
|
map[exchangeCategory]string{
|
||||||
|
ExchangeUser: "uid",
|
||||||
|
ExchangeEvent: "eid",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ExchangeMail,
|
||||||
|
[]string{"tid", "uid", "mail", "mFld", "mid"},
|
||||||
|
map[exchangeCategory]string{
|
||||||
|
ExchangeUser: "uid",
|
||||||
|
ExchangeMailFolder: "mFld",
|
||||||
|
ExchangeMail: "mid",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ExchangeCategoryUnknown,
|
||||||
|
[]string{"tid", "uid", "contact", "cFld", "cid"},
|
||||||
|
map[exchangeCategory]string{
|
||||||
|
ExchangeUser: "uid",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.cat.String(), func(t *testing.T) {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *ExchangeSourceSuite) TestExchangeRestore_FilterDetails() {
|
||||||
|
makeDeets := func(refs ...string) *backup.Details {
|
||||||
|
deets := &backup.Details{
|
||||||
|
Entries: []backup.DetailsEntry{},
|
||||||
|
}
|
||||||
|
for _, r := range refs {
|
||||||
|
deets.Entries = append(deets.Entries, backup.DetailsEntry{
|
||||||
|
RepoRef: r,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return deets
|
||||||
|
}
|
||||||
|
const (
|
||||||
|
contact = "tid/uid/contact/cfld/cid"
|
||||||
|
event = "tid/uid/event/eid"
|
||||||
|
mail = "tid/uid/mail/mfld/mid"
|
||||||
|
)
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
deets *backup.Details
|
||||||
|
makeSelector func() *ExchangeRestore
|
||||||
|
expect []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"no refs",
|
||||||
|
makeDeets(),
|
||||||
|
func() *ExchangeRestore {
|
||||||
|
er := NewExchangeRestore("rpid")
|
||||||
|
er.Include(er.Users(All))
|
||||||
|
return er
|
||||||
|
},
|
||||||
|
[]string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"contact only",
|
||||||
|
makeDeets(contact),
|
||||||
|
func() *ExchangeRestore {
|
||||||
|
er := NewExchangeRestore("rpid")
|
||||||
|
er.Include(er.Users(All))
|
||||||
|
return er
|
||||||
|
},
|
||||||
|
[]string{contact},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event only",
|
||||||
|
makeDeets(event),
|
||||||
|
func() *ExchangeRestore {
|
||||||
|
er := NewExchangeRestore("rpid")
|
||||||
|
er.Include(er.Users(All))
|
||||||
|
return er
|
||||||
|
},
|
||||||
|
[]string{event},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mail only",
|
||||||
|
makeDeets(mail),
|
||||||
|
func() *ExchangeRestore {
|
||||||
|
er := NewExchangeRestore("rpid")
|
||||||
|
er.Include(er.Users(All))
|
||||||
|
return er
|
||||||
|
},
|
||||||
|
[]string{mail},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all",
|
||||||
|
makeDeets(contact, event, mail),
|
||||||
|
func() *ExchangeRestore {
|
||||||
|
er := NewExchangeRestore("rpid")
|
||||||
|
er.Include(er.Users(All))
|
||||||
|
return er
|
||||||
|
},
|
||||||
|
[]string{contact, event, mail},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"only match contact",
|
||||||
|
makeDeets(contact, event, mail),
|
||||||
|
func() *ExchangeRestore {
|
||||||
|
er := NewExchangeRestore("rpid")
|
||||||
|
er.Include(er.Contacts("uid", "cfld", "cid"))
|
||||||
|
return er
|
||||||
|
},
|
||||||
|
[]string{contact},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"only match event",
|
||||||
|
makeDeets(contact, event, mail),
|
||||||
|
func() *ExchangeRestore {
|
||||||
|
er := NewExchangeRestore("rpid")
|
||||||
|
er.Include(er.Events("uid", "eid"))
|
||||||
|
return er
|
||||||
|
},
|
||||||
|
[]string{event},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"only match mail",
|
||||||
|
makeDeets(contact, event, mail),
|
||||||
|
func() *ExchangeRestore {
|
||||||
|
er := NewExchangeRestore("rpid")
|
||||||
|
er.Include(er.Mails("uid", "mfld", "mid"))
|
||||||
|
return er
|
||||||
|
},
|
||||||
|
[]string{mail},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exclude contact",
|
||||||
|
makeDeets(contact, event, mail),
|
||||||
|
func() *ExchangeRestore {
|
||||||
|
er := NewExchangeRestore("rpid")
|
||||||
|
er.Include(er.Users(All))
|
||||||
|
er.Exclude(er.Contacts("uid", "cfld", "cid"))
|
||||||
|
return er
|
||||||
|
},
|
||||||
|
[]string{event, mail},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exclude event",
|
||||||
|
makeDeets(contact, event, mail),
|
||||||
|
func() *ExchangeRestore {
|
||||||
|
er := NewExchangeRestore("rpid")
|
||||||
|
er.Include(er.Users(All))
|
||||||
|
er.Exclude(er.Events("uid", "eid"))
|
||||||
|
return er
|
||||||
|
},
|
||||||
|
[]string{contact, mail},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exclude mail",
|
||||||
|
makeDeets(contact, event, mail),
|
||||||
|
func() *ExchangeRestore {
|
||||||
|
er := NewExchangeRestore("rpid")
|
||||||
|
er.Include(er.Users(All))
|
||||||
|
er.Exclude(er.Mails("uid", "mfld", "mid"))
|
||||||
|
return er
|
||||||
|
},
|
||||||
|
[]string{contact, event},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
|
sel := test.makeSelector()
|
||||||
|
results := sel.FilterDetails(test.deets)
|
||||||
|
assert.Equal(t, test.expect, results)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *ExchangeSourceSuite) TestExchangeScopesByCategory() {
|
||||||
|
var (
|
||||||
|
es = NewExchangeRestore("rpid")
|
||||||
|
users = es.Users(All)
|
||||||
|
contacts = es.ContactFolders(All, All)
|
||||||
|
events = es.Events(All, All)
|
||||||
|
mail = es.MailFolders(All, All)
|
||||||
|
)
|
||||||
|
type expect struct {
|
||||||
|
contact int
|
||||||
|
event int
|
||||||
|
mail int
|
||||||
|
}
|
||||||
|
type input []map[string]string
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
scopes input
|
||||||
|
expect expect
|
||||||
|
}{
|
||||||
|
{"users: one of each", input{users}, expect{1, 1, 1}},
|
||||||
|
{"contacts only", input{contacts}, expect{1, 0, 0}},
|
||||||
|
{"events only", input{events}, expect{0, 1, 0}},
|
||||||
|
{"mail only", input{mail}, expect{0, 0, 1}},
|
||||||
|
{"all", input{users, contacts, events, mail}, expect{2, 2, 2}},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
|
result := exchangeScopesByCategory(test.scopes)
|
||||||
|
assert.Equal(t, test.expect.contact, len(result[ExchangeContact.String()]))
|
||||||
|
assert.Equal(t, test.expect.event, len(result[ExchangeEvent.String()]))
|
||||||
|
assert.Equal(t, test.expect.mail, len(result[ExchangeMail.String()]))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *ExchangeSourceSuite) TestMatchExchangeEntry() {
|
||||||
|
const (
|
||||||
|
mail = "mailID"
|
||||||
|
cat = ExchangeMail
|
||||||
|
)
|
||||||
|
include := func(s map[string]string) exchangeScope {
|
||||||
|
return extendExchangeScopeValues(All, exchangeScope(s))
|
||||||
|
}
|
||||||
|
exclude := func(s map[string]string) exchangeScope {
|
||||||
|
return extendExchangeScopeValues(None, exchangeScope(s))
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
es = NewExchangeRestore("rpid")
|
||||||
|
inAll = include(es.Users(All))
|
||||||
|
inNone = include(es.Users(None))
|
||||||
|
inMail = include(es.Mails(All, All, mail))
|
||||||
|
inOtherMail = include(es.Mails(All, All, "smarf"))
|
||||||
|
exAll = exclude(es.Users(All))
|
||||||
|
exNone = exclude(es.Users(None))
|
||||||
|
exMail = exclude(es.Mails(None, None, mail))
|
||||||
|
exOtherMail = exclude(es.Mails(None, None, "smarf"))
|
||||||
|
path = []string{"tid", "user", "mail", "folder", mail}
|
||||||
|
)
|
||||||
|
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
includes []exchangeScope
|
||||||
|
excludes []exchangeScope
|
||||||
|
expect assert.BoolAssertionFunc
|
||||||
|
}{
|
||||||
|
{"empty", []exchangeScope{}, []exchangeScope{}, assert.False},
|
||||||
|
{"in all", []exchangeScope{inAll}, []exchangeScope{}, assert.True},
|
||||||
|
{"in None", []exchangeScope{inNone}, []exchangeScope{}, assert.False},
|
||||||
|
{"in Mail", []exchangeScope{inMail}, []exchangeScope{}, assert.True},
|
||||||
|
{"in Other", []exchangeScope{inOtherMail}, []exchangeScope{}, assert.False},
|
||||||
|
{"ex all", []exchangeScope{inAll}, []exchangeScope{exAll}, assert.False},
|
||||||
|
{"ex None", []exchangeScope{inAll}, []exchangeScope{exNone}, assert.True},
|
||||||
|
{"in Mail", []exchangeScope{inAll}, []exchangeScope{exMail}, assert.False},
|
||||||
|
{"in Other", []exchangeScope{inAll}, []exchangeScope{exOtherMail}, assert.True},
|
||||||
|
{"in and ex mail", []exchangeScope{inMail}, []exchangeScope{exMail}, assert.False},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
|
test.expect(t, matchExchangeEntry(cat, path, test.includes, test.excludes))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user