Add way to extract reason from tags

Helper functions to store reason information as tags in a backup model
and extract them. Also add tests for this.
This commit is contained in:
Ashlie Martinez 2023-10-05 13:06:05 -07:00
parent 0ebd6c8eec
commit 9b8ee4f3f6
2 changed files with 195 additions and 0 deletions

View File

@ -2,6 +2,7 @@ package backup
import (
"context"
"errors"
"fmt"
"strconv"
"strings"
@ -12,6 +13,7 @@ import (
"github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/common/errs"
"github.com/alcionai/corso/src/internal/common/str"
"github.com/alcionai/corso/src/internal/model"
"github.com/alcionai/corso/src/internal/stats"
@ -242,6 +244,48 @@ func (b Backup) Bases() (PersistedBaseSet, error) {
return res, nil
}
func (b Backup) Tenant() (string, error) {
t := b.Tags[tenantIDKey]
if len(t) == 0 {
return "", clues.Wrap(errs.NotFound, "getting tenant")
}
return t, nil
}
// Reasons returns the set of services and categories this backup encompassed
// for the tenant and protected resource.
func (b Backup) Reasons() ([]identity.Reasoner, error) {
tenant, err := b.Tenant()
if err != nil {
return nil, clues.Stack(err)
}
var res []identity.Reasoner
for tag := range b.Tags {
service, cat, err := serviceCatStringToTypes(tag)
if err != nil {
// Assume it's just not one of the Reason tags.
if errors.Is(err, errMissingPrefix) {
continue
}
return nil, clues.Wrap(err, "parsing reasons")
}
res = append(
res,
identity.NewReason(
tenant,
str.First(b.ProtectedResourceID, b.Selector.DiscreteOwner),
service,
cat))
}
return res, nil
}
// --------------------------------------------------------------------------------
// CLI Output
// --------------------------------------------------------------------------------

View File

@ -13,6 +13,7 @@ import (
"golang.org/x/exp/maps"
"github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/common/errs"
"github.com/alcionai/corso/src/internal/model"
"github.com/alcionai/corso/src/internal/stats"
"github.com/alcionai/corso/src/internal/tester"
@ -283,6 +284,156 @@ func (suite *BackupUnitSuite) TestBackup_Bases() {
}
}
func (suite *BackupUnitSuite) TestBackup_Tenant() {
const tenant = "tenant-id"
stub := stubBackup(time.Now(), "user-id", "user-name")
table := []struct {
name string
inputKey string
inputValue string
expectErr assert.ErrorAssertionFunc
expect string
}{
{
name: "ProperlyFormatted",
inputKey: tenantIDKey,
inputValue: tenant,
expectErr: assert.NoError,
expect: tenant,
},
{
name: "WrongKey",
inputKey: "foo",
inputValue: tenant,
expectErr: assert.Error,
},
{
name: "EmptyValue",
inputKey: tenantIDKey,
inputValue: "",
expectErr: assert.Error,
},
}
for _, test := range table {
suite.Run(test.name, func() {
t := suite.T()
b := stub
b.Tags = map[string]string{test.inputKey: test.inputValue}
gotTenant, err := b.Tenant()
test.expectErr(t, err, clues.ToCore(err))
if err != nil {
assert.ErrorIs(t, err, errs.NotFound)
return
}
assert.Equal(t, test.expect, gotTenant)
})
}
}
func (suite *BackupUnitSuite) TestBackup_Reasons() {
const (
tenantID = "tenant-id"
userID = "user-id"
)
stub := stubBackup(time.Now(), userID, "user-name")
defaultEmailReason := identity.NewReason(
tenantID,
stub.ProtectedResourceID,
path.ExchangeService,
path.EmailCategory)
defaultContactsReason := identity.NewReason(
tenantID,
stub.ProtectedResourceID,
path.ExchangeService,
path.ContactsCategory)
table := []struct {
name string
getBackup func() *Backup
expectErr assert.ErrorAssertionFunc
expect []identity.Reasoner
}{
{
name: "SingleReason",
getBackup: func() *Backup {
res := stub
res.Tags = map[string]string{}
for k, v := range reasonTags(defaultEmailReason) {
res.Tags[k] = v
}
return &res
},
expectErr: assert.NoError,
expect: []identity.Reasoner{defaultEmailReason},
},
{
name: "MultipleReasons",
getBackup: func() *Backup {
res := stub
res.Tags = map[string]string{}
for _, reason := range []identity.Reasoner{defaultEmailReason, defaultContactsReason} {
for k, v := range reasonTags(reason) {
res.Tags[k] = v
}
}
return &res
},
expectErr: assert.NoError,
expect: []identity.Reasoner{
defaultEmailReason,
defaultContactsReason,
},
},
{
name: "SingleReason OtherTags",
getBackup: func() *Backup {
res := stub
res.Tags = map[string]string{}
for k, v := range reasonTags(defaultEmailReason) {
res.Tags[k] = v
}
res.Tags["foo"] = "bar"
return &res
},
expectErr: assert.NoError,
expect: []identity.Reasoner{defaultEmailReason},
},
}
for _, test := range table {
suite.Run(test.name, func() {
t := suite.T()
bup := test.getBackup()
got, err := bup.Reasons()
test.expectErr(t, err, clues.ToCore(err))
if err != nil {
return
}
assert.ElementsMatch(t, test.expect, got)
})
}
}
func (suite *BackupUnitSuite) TestBackup_HeadersValues() {
var (
t = suite.T()