Expand selectors package Reduce tests (#925)
## Description Add test data and more complex tests for the selectors package. This helps codify the interface behavior of selectors which can help avoid surprises in the future ## Type of change <!--- Please check the type of change your PR introduces: ---> - [ ] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [x] 🤖 Test - [ ] 💻 CI/Deployment - [ ] 🐹 Trivial/Minor ## Issue(s) * #913 ## Test Plan <!-- How will this be tested prior to merging.--> - [ ] 💪 Manual - [x] ⚡ Unit test - [ ] 💚 E2E
This commit is contained in:
parent
c1a6086a2a
commit
f2e767b3c7
@ -36,6 +36,8 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ Reducer = &ExchangeRestore{}
|
||||||
|
|
||||||
// NewExchange produces a new Selector with the service set to ServiceExchange.
|
// NewExchange produces a new Selector with the service set to ServiceExchange.
|
||||||
func NewExchangeBackup() *ExchangeBackup {
|
func NewExchangeBackup() *ExchangeBackup {
|
||||||
src := ExchangeBackup{
|
src := ExchangeBackup{
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
package selectors
|
package selectors
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||||
"github.com/alcionai/corso/src/pkg/filters"
|
"github.com/alcionai/corso/src/pkg/filters"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -53,6 +55,10 @@ var (
|
|||||||
// It is not used aside from printing resources.
|
// It is not used aside from printing resources.
|
||||||
const All = "All"
|
const All = "All"
|
||||||
|
|
||||||
|
type Reducer interface {
|
||||||
|
Reduce(context.Context, *details.Details) *details.Details
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Selector
|
// Selector
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
179
src/pkg/selectors/selectors_reduce_test.go
Normal file
179
src/pkg/selectors/selectors_reduce_test.go
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
package selectors_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/src/internal/common"
|
||||||
|
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||||
|
"github.com/alcionai/corso/src/pkg/selectors"
|
||||||
|
"github.com/alcionai/corso/src/pkg/selectors/testdata"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SelectorReduceSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSelectorReduceSuite(t *testing.T) {
|
||||||
|
suite.Run(t, new(SelectorReduceSuite))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *SelectorReduceSuite) TestReduce() {
|
||||||
|
ctx := context.Background()
|
||||||
|
allDetails := testdata.GetDetailsSet()
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
selFunc func() selectors.Reducer
|
||||||
|
expected []details.DetailsEntry
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "ExchangeAllMail",
|
||||||
|
selFunc: func() selectors.Reducer {
|
||||||
|
sel := selectors.NewExchangeRestore()
|
||||||
|
sel.Include(sel.Mails(
|
||||||
|
selectors.Any(),
|
||||||
|
selectors.Any(),
|
||||||
|
selectors.Any(),
|
||||||
|
))
|
||||||
|
|
||||||
|
return sel
|
||||||
|
},
|
||||||
|
expected: testdata.ExchangeEmailItems,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ExchangeMailSubject",
|
||||||
|
selFunc: func() selectors.Reducer {
|
||||||
|
sel := selectors.NewExchangeRestore()
|
||||||
|
sel.Filter(sel.MailSubject("foo"))
|
||||||
|
|
||||||
|
return sel
|
||||||
|
},
|
||||||
|
expected: []details.DetailsEntry{testdata.ExchangeEmailItems[0]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ExchangeMailSubjectExcludeItem",
|
||||||
|
selFunc: func() selectors.Reducer {
|
||||||
|
sel := selectors.NewExchangeRestore()
|
||||||
|
sel.Filter(sel.MailSender("a-person"))
|
||||||
|
sel.Exclude(sel.Mails(
|
||||||
|
selectors.Any(),
|
||||||
|
selectors.Any(),
|
||||||
|
[]string{testdata.ExchangeEmailItemPath2.ShortRef()},
|
||||||
|
))
|
||||||
|
|
||||||
|
return sel
|
||||||
|
},
|
||||||
|
expected: []details.DetailsEntry{testdata.ExchangeEmailItems[0]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ExchangeMailSender",
|
||||||
|
selFunc: func() selectors.Reducer {
|
||||||
|
sel := selectors.NewExchangeRestore()
|
||||||
|
sel.Filter(sel.MailSender("a-person"))
|
||||||
|
|
||||||
|
return sel
|
||||||
|
},
|
||||||
|
expected: testdata.ExchangeEmailItems,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ExchangeMailReceivedTime",
|
||||||
|
selFunc: func() selectors.Reducer {
|
||||||
|
sel := selectors.NewExchangeRestore()
|
||||||
|
sel.Filter(sel.MailReceivedBefore(
|
||||||
|
common.FormatTime(testdata.Time1.Add(time.Second)),
|
||||||
|
))
|
||||||
|
|
||||||
|
return sel
|
||||||
|
},
|
||||||
|
expected: []details.DetailsEntry{testdata.ExchangeEmailItems[0]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ExchangeMailID",
|
||||||
|
selFunc: func() selectors.Reducer {
|
||||||
|
sel := selectors.NewExchangeRestore()
|
||||||
|
sel.Include(sel.Mails(
|
||||||
|
selectors.Any(),
|
||||||
|
selectors.Any(),
|
||||||
|
[]string{testdata.ExchangeEmailItemPath1.Item()},
|
||||||
|
))
|
||||||
|
|
||||||
|
return sel
|
||||||
|
},
|
||||||
|
expected: []details.DetailsEntry{testdata.ExchangeEmailItems[0]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ExchangeMailShortRef",
|
||||||
|
selFunc: func() selectors.Reducer {
|
||||||
|
sel := selectors.NewExchangeRestore()
|
||||||
|
sel.Include(sel.Mails(
|
||||||
|
selectors.Any(),
|
||||||
|
selectors.Any(),
|
||||||
|
[]string{testdata.ExchangeEmailItemPath1.ShortRef()},
|
||||||
|
))
|
||||||
|
|
||||||
|
return sel
|
||||||
|
},
|
||||||
|
expected: []details.DetailsEntry{testdata.ExchangeEmailItems[0]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ExchangeAllEventsAndMailWithSubject",
|
||||||
|
selFunc: func() selectors.Reducer {
|
||||||
|
sel := selectors.NewExchangeRestore()
|
||||||
|
sel.Include(sel.Events(
|
||||||
|
selectors.Any(),
|
||||||
|
selectors.Any(),
|
||||||
|
selectors.Any(),
|
||||||
|
))
|
||||||
|
sel.Filter(sel.MailSubject("foo"))
|
||||||
|
|
||||||
|
return sel
|
||||||
|
},
|
||||||
|
expected: []details.DetailsEntry{testdata.ExchangeEmailItems[0]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ExchangeEventsAndMailWithSubject",
|
||||||
|
selFunc: func() selectors.Reducer {
|
||||||
|
sel := selectors.NewExchangeRestore()
|
||||||
|
sel.Filter(sel.EventSubject("foo"))
|
||||||
|
sel.Filter(sel.MailSubject("foo"))
|
||||||
|
|
||||||
|
return sel
|
||||||
|
},
|
||||||
|
expected: []details.DetailsEntry{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ExchangeAll",
|
||||||
|
selFunc: func() selectors.Reducer {
|
||||||
|
sel := selectors.NewExchangeRestore()
|
||||||
|
sel.Include(sel.Users(
|
||||||
|
selectors.Any(),
|
||||||
|
))
|
||||||
|
|
||||||
|
return sel
|
||||||
|
},
|
||||||
|
expected: append(
|
||||||
|
append(
|
||||||
|
append(
|
||||||
|
[]details.DetailsEntry{},
|
||||||
|
testdata.ExchangeEmailItems...),
|
||||||
|
testdata.ExchangeContactsItems...),
|
||||||
|
testdata.ExchangeEventsItems...,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
|
test := test
|
||||||
|
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
output := test.selFunc().Reduce(ctx, allDetails)
|
||||||
|
assert.ElementsMatch(t, test.expected, output.Entries)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
216
src/pkg/selectors/testdata/details.go
vendored
Normal file
216
src/pkg/selectors/testdata/details.go
vendored
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
package testdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
stdpath "path"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/src/internal/path"
|
||||||
|
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||||
|
)
|
||||||
|
|
||||||
|
// mustParsePath takes a string representing a resource path and returns a path
|
||||||
|
// instance. Panics if the path cannot be parsed. Useful for simple variable
|
||||||
|
// assignments.
|
||||||
|
func mustParsePath(ref string, isItem bool) path.Path {
|
||||||
|
p, err := path.FromDataLayerPath(ref, isItem)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// mustAppendPath takes a Path, string representing a path element, and whether
|
||||||
|
// the element is an item and returns a path instance representing the original
|
||||||
|
// path with the element appended to it. Panics if the path cannot be parsed.
|
||||||
|
// Useful for simple variable assignments.
|
||||||
|
func mustAppendPath(p path.Path, newElement string, isItem bool) path.Path {
|
||||||
|
newP, err := p.Append(newElement, isItem)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return newP
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
ItemName1 = "item1"
|
||||||
|
ItemName2 = "item2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Time1 = time.Date(2022, 9, 21, 10, 0, 0, 0, time.UTC)
|
||||||
|
Time2 = time.Date(2022, 10, 21, 10, 0, 0, 0, time.UTC)
|
||||||
|
|
||||||
|
ExchangeEmailBasePath = mustParsePath("tenant-id/exchange/user-id/email/Inbox/subfolder", false)
|
||||||
|
ExchangeEmailItemPath1 = mustAppendPath(ExchangeEmailBasePath, ItemName1, true)
|
||||||
|
ExchangeEmailItemPath2 = mustAppendPath(ExchangeEmailBasePath, ItemName2, true)
|
||||||
|
|
||||||
|
ExchangeEmailItems = []details.DetailsEntry{
|
||||||
|
{
|
||||||
|
RepoRef: ExchangeEmailItemPath1.String(),
|
||||||
|
ShortRef: ExchangeEmailItemPath1.ShortRef(),
|
||||||
|
ParentRef: ExchangeEmailItemPath1.ToBuilder().Dir().ShortRef(),
|
||||||
|
ItemInfo: details.ItemInfo{
|
||||||
|
Exchange: &details.ExchangeInfo{
|
||||||
|
ItemType: details.ExchangeMail,
|
||||||
|
Sender: "a-person",
|
||||||
|
Subject: "foo",
|
||||||
|
Received: Time1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RepoRef: ExchangeEmailItemPath2.String(),
|
||||||
|
ShortRef: ExchangeEmailItemPath2.ShortRef(),
|
||||||
|
ParentRef: ExchangeEmailItemPath2.ToBuilder().Dir().ShortRef(),
|
||||||
|
ItemInfo: details.ItemInfo{
|
||||||
|
Exchange: &details.ExchangeInfo{
|
||||||
|
ItemType: details.ExchangeMail,
|
||||||
|
Sender: "a-person",
|
||||||
|
Subject: "bar",
|
||||||
|
Received: Time2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ExchangeContactsBasePath = mustParsePath("tenant-id/exchange/user-id/contacts/contacts", false)
|
||||||
|
ExchangeContactsItemPath1 = mustAppendPath(ExchangeContactsBasePath, ItemName1, true)
|
||||||
|
ExchangeContactsItemPath2 = mustAppendPath(ExchangeContactsBasePath, ItemName2, true)
|
||||||
|
|
||||||
|
ExchangeContactsItems = []details.DetailsEntry{
|
||||||
|
{
|
||||||
|
RepoRef: ExchangeContactsItemPath1.String(),
|
||||||
|
ShortRef: ExchangeContactsItemPath1.ShortRef(),
|
||||||
|
ParentRef: ExchangeContactsItemPath1.ToBuilder().Dir().ShortRef(),
|
||||||
|
ItemInfo: details.ItemInfo{
|
||||||
|
Exchange: &details.ExchangeInfo{
|
||||||
|
ItemType: details.ExchangeContact,
|
||||||
|
ContactName: "a-person",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RepoRef: ExchangeContactsItemPath2.String(),
|
||||||
|
ShortRef: ExchangeContactsItemPath2.ShortRef(),
|
||||||
|
ParentRef: ExchangeContactsItemPath2.ToBuilder().Dir().ShortRef(),
|
||||||
|
ItemInfo: details.ItemInfo{
|
||||||
|
Exchange: &details.ExchangeInfo{
|
||||||
|
ItemType: details.ExchangeContact,
|
||||||
|
ContactName: "another-person",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ExchangeEventsBasePath = mustParsePath("tenant-id/exchange/user-id/events/holidays", false)
|
||||||
|
ExchangeEventsItemPath1 = mustAppendPath(ExchangeEventsBasePath, ItemName1, true)
|
||||||
|
ExchangeEventsItemPath2 = mustAppendPath(ExchangeEventsBasePath, ItemName2, true)
|
||||||
|
|
||||||
|
ExchangeEventsItems = []details.DetailsEntry{
|
||||||
|
{
|
||||||
|
RepoRef: ExchangeEventsItemPath1.String(),
|
||||||
|
ShortRef: ExchangeEventsItemPath1.ShortRef(),
|
||||||
|
ParentRef: ExchangeEventsItemPath1.ToBuilder().Dir().ShortRef(),
|
||||||
|
ItemInfo: details.ItemInfo{
|
||||||
|
Exchange: &details.ExchangeInfo{
|
||||||
|
ItemType: details.ExchangeEvent,
|
||||||
|
Organizer: "a-person",
|
||||||
|
Subject: "foo",
|
||||||
|
EventStart: Time1,
|
||||||
|
EventRecurs: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RepoRef: ExchangeEventsItemPath2.String(),
|
||||||
|
ShortRef: ExchangeEventsItemPath2.ShortRef(),
|
||||||
|
ParentRef: ExchangeEventsItemPath2.ToBuilder().Dir().ShortRef(),
|
||||||
|
ItemInfo: details.ItemInfo{
|
||||||
|
Exchange: &details.ExchangeInfo{
|
||||||
|
ItemType: details.ExchangeEvent,
|
||||||
|
Organizer: "a-person",
|
||||||
|
Subject: "foo",
|
||||||
|
EventStart: Time2,
|
||||||
|
EventRecurs: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
OneDriveBasePath = mustParsePath("tenant-id/onedrive/user-id/files/folder/subfolder", false)
|
||||||
|
OneDriveItemPath1 = mustAppendPath(OneDriveBasePath, ItemName1, true)
|
||||||
|
OneDriveItemPath2 = mustAppendPath(OneDriveBasePath, ItemName2, true)
|
||||||
|
|
||||||
|
OneDriveItems = []details.DetailsEntry{
|
||||||
|
{
|
||||||
|
RepoRef: OneDriveItemPath1.String(),
|
||||||
|
ShortRef: OneDriveItemPath1.ShortRef(),
|
||||||
|
ParentRef: OneDriveItemPath1.ToBuilder().Dir().ShortRef(),
|
||||||
|
ItemInfo: details.ItemInfo{
|
||||||
|
OneDrive: &details.OneDriveInfo{
|
||||||
|
ItemType: details.OneDriveItem,
|
||||||
|
ParentPath: stdpath.Join(
|
||||||
|
append(
|
||||||
|
[]string{
|
||||||
|
"drives",
|
||||||
|
"foo",
|
||||||
|
"root:",
|
||||||
|
},
|
||||||
|
OneDriveItemPath1.Folders()...,
|
||||||
|
)...,
|
||||||
|
),
|
||||||
|
ItemName: OneDriveItemPath1.Item() + "name",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RepoRef: OneDriveItemPath2.String(),
|
||||||
|
ShortRef: OneDriveItemPath2.ShortRef(),
|
||||||
|
ParentRef: OneDriveItemPath2.ToBuilder().Dir().ShortRef(),
|
||||||
|
ItemInfo: details.ItemInfo{
|
||||||
|
OneDrive: &details.OneDriveInfo{
|
||||||
|
ItemType: details.OneDriveItem,
|
||||||
|
ParentPath: stdpath.Join(
|
||||||
|
append(
|
||||||
|
[]string{
|
||||||
|
"drives",
|
||||||
|
"foo",
|
||||||
|
"root:",
|
||||||
|
},
|
||||||
|
OneDriveItemPath2.Folders()...,
|
||||||
|
)...,
|
||||||
|
),
|
||||||
|
ItemName: OneDriveItemPath2.Item() + "name",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetDetailsSet() *details.Details {
|
||||||
|
entries := []details.DetailsEntry{}
|
||||||
|
|
||||||
|
for _, e := range ExchangeEmailItems {
|
||||||
|
entries = append(entries, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, e := range ExchangeContactsItems {
|
||||||
|
entries = append(entries, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, e := range ExchangeEventsItems {
|
||||||
|
entries = append(entries, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, e := range OneDriveItems {
|
||||||
|
entries = append(entries, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &details.Details{
|
||||||
|
DetailsModel: details.DetailsModel{
|
||||||
|
Entries: entries,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user