diff --git a/src/internal/common/configs.go b/src/internal/common/configs.go new file mode 100644 index 000000000..ce232c2c0 --- /dev/null +++ b/src/internal/common/configs.go @@ -0,0 +1,21 @@ +package common + +type StringConfigurer interface { + StringConfig() (map[string]string, error) +} + +// UnionStringConfigs unions all provided configurers into a single +// map[string]string matching type. +func UnionStringConfigs(cfgs ...StringConfigurer) (map[string]string, error) { + union := map[string]string{} + for _, cfg := range cfgs { + c, err := cfg.StringConfig() + if err != nil { + return nil, err + } + for k, v := range c { + union[k] = v + } + } + return union, nil +} diff --git a/src/internal/common/configs_test.go b/src/internal/common/configs_test.go new file mode 100644 index 000000000..48ef1e3c6 --- /dev/null +++ b/src/internal/common/configs_test.go @@ -0,0 +1,72 @@ +package common_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + + "github.com/alcionai/corso/internal/common" +) + +type CommonConfigsSuite struct { + suite.Suite +} + +func TestCommonConfigsSuite(t *testing.T) { + suite.Run(t, new(CommonConfigsSuite)) +} + +const ( + keyExpect = "expect" + keyExpect2 = "expect2" +) + +type stringConfig struct { + expectA string + err error +} + +func (c stringConfig) StringConfig() (map[string]string, error) { + return map[string]string{keyExpect: c.expectA}, c.err +} + +type stringConfig2 struct { + expectB string + err error +} + +func (c stringConfig2) StringConfig() (map[string]string, error) { + return map[string]string{keyExpect2: c.expectB}, c.err +} + +func (suite *CommonConfigsSuite) TestUnionConfigs_string() { + table := []struct { + name string + ac stringConfig + bc stringConfig2 + errCheck assert.ErrorAssertionFunc + }{ + {"no error", stringConfig{keyExpect, nil}, stringConfig2{keyExpect2, nil}, assert.NoError}, + {"tc error", stringConfig{keyExpect, assert.AnError}, stringConfig2{keyExpect2, nil}, assert.Error}, + {"fc error", stringConfig{keyExpect, nil}, stringConfig2{keyExpect2, assert.AnError}, assert.Error}, + } + for _, test := range table { + suite.T().Run(test.name, func(t *testing.T) { + cs, err := common.UnionStringConfigs(test.ac, test.bc) + test.errCheck(t, err) + // remaining tests depend on error-free state + if test.ac.err != nil || test.bc.err != nil { + return + } + assert.Equalf(t, + test.ac.expectA, + cs[keyExpect], + "expected unioned config to have value [%s] at key [%s], got [%s]", test.ac.expectA, keyExpect, cs[keyExpect]) + assert.Equalf(t, + test.bc.expectB, + cs[keyExpect2], + "expected unioned config to have value [%s] at key [%s], got [%s]", test.bc.expectB, keyExpect2, cs[keyExpect2]) + }) + } +} diff --git a/src/pkg/account/account.go b/src/pkg/account/account.go index faa00a240..dce9fb55c 100644 --- a/src/pkg/account/account.go +++ b/src/pkg/account/account.go @@ -1,6 +1,10 @@ package account -import "errors" +import ( + "errors" + + "github.com/alcionai/corso/internal/common" +) type accountProvider int @@ -15,39 +19,18 @@ var ( errMissingRequired = errors.New("missing required storage configuration") ) -type ( - config map[string]string - configurer interface { - Config() (config, error) - } -) - // Account defines an account provider, along with any credentials // and identifiers requried to set up or communicate with that provider. type Account struct { Provider accountProvider - Config config + Config map[string]string } // NewAccount aggregates all the supplied configurations into a single configuration -func NewAccount(p accountProvider, cfgs ...configurer) (Account, error) { - cs, err := unionConfigs(cfgs...) +func NewAccount(p accountProvider, cfgs ...common.StringConfigurer) (Account, error) { + cs, err := common.UnionStringConfigs(cfgs...) return Account{ Provider: p, Config: cs, }, err } - -func unionConfigs(cfgs ...configurer) (config, error) { - union := config{} - for _, cfg := range cfgs { - c, err := cfg.Config() - if err != nil { - return nil, err - } - for k, v := range c { - union[k] = v - } - } - return union, nil -} diff --git a/src/pkg/account/account_test.go b/src/pkg/account/account_test.go index ec1fcdeb4..a6582fb21 100644 --- a/src/pkg/account/account_test.go +++ b/src/pkg/account/account_test.go @@ -12,8 +12,8 @@ type testConfig struct { err error } -func (c testConfig) Config() (config, error) { - return config{"expect": c.expect}, c.err +func (c testConfig) StringConfig() (map[string]string, error) { + return map[string]string{"expect": c.expect}, c.err } type AccountSuite struct { @@ -55,43 +55,3 @@ func (suite *AccountSuite) TestNewAccount() { }) } } - -type fooConfig struct { - foo string - err error -} - -func (c fooConfig) Config() (config, error) { - return config{"foo": c.foo}, c.err -} - -func (suite *AccountSuite) TestUnionConfigs() { - table := []struct { - name string - tc testConfig - fc fooConfig - errCheck assert.ErrorAssertionFunc - }{ - {"no error", testConfig{"test", nil}, fooConfig{"foo", nil}, assert.NoError}, - {"tc error", testConfig{"test", assert.AnError}, fooConfig{"foo", nil}, assert.Error}, - {"fc error", testConfig{"test", nil}, fooConfig{"foo", assert.AnError}, assert.Error}, - } - for _, test := range table { - suite.T().Run(test.name, func(t *testing.T) { - cs, err := unionConfigs(test.tc, test.fc) - test.errCheck(t, err) - // remaining tests depend on error-free state - if test.tc.err != nil || test.fc.err != nil { - return - } - assert.Equalf(t, - test.tc.expect, - cs["expect"], - "expected unioned config to have value [%s] at key [expect], got [%s]", test.tc.expect, cs["expect"]) - assert.Equalf(t, - test.fc.foo, - cs["foo"], - "expected unioned config to have value [%s] at key [foo], got [%s]", test.fc.foo, cs["foo"]) - }) - } -} diff --git a/src/pkg/account/m365.go b/src/pkg/account/m365.go index bbcd2ff13..5260b2680 100644 --- a/src/pkg/account/m365.go +++ b/src/pkg/account/m365.go @@ -24,8 +24,8 @@ const ( // (todo) TenantID = "TENANT_ID" ) -func (c M365Config) Config() (config, error) { - cfg := config{ +func (c M365Config) StringConfig() (map[string]string, error) { + cfg := map[string]string{ keyM365ClientID: c.ClientID, keyM365ClientSecret: c.ClientSecret, keyM365TenantID: c.TenantID, diff --git a/src/pkg/account/m365_test.go b/src/pkg/account/m365_test.go index fee798bf2..2ff9ddb16 100644 --- a/src/pkg/account/m365_test.go +++ b/src/pkg/account/m365_test.go @@ -29,7 +29,7 @@ var goodM365Config = account.M365Config{ func (suite *M365CfgSuite) TestM365Config_Config() { m365 := goodM365Config - c, err := m365.Config() + c, err := m365.StringConfig() require.NoError(suite.T(), err) table := []struct { diff --git a/src/pkg/storage/common.go b/src/pkg/storage/common.go index fdc3320bc..17defb5da 100644 --- a/src/pkg/storage/common.go +++ b/src/pkg/storage/common.go @@ -15,8 +15,8 @@ const ( keyCommonCorsoPassword = "common_corsoPassword" ) -func (c CommonConfig) Config() (config, error) { - cfg := config{ +func (c CommonConfig) StringConfig() (map[string]string, error) { + cfg := map[string]string{ keyCommonCorsoPassword: c.CorsoPassword, } return cfg, c.validate() diff --git a/src/pkg/storage/common_test.go b/src/pkg/storage/common_test.go index 5aec0b7e3..a84f59c7b 100644 --- a/src/pkg/storage/common_test.go +++ b/src/pkg/storage/common_test.go @@ -26,7 +26,7 @@ var goodCommonConfig = storage.CommonConfig{ func (suite *CommonCfgSuite) TestCommonConfig_Config() { cfg := goodCommonConfig - c, err := cfg.Config() + c, err := cfg.StringConfig() assert.NoError(suite.T(), err) table := []struct { diff --git a/src/pkg/storage/s3.go b/src/pkg/storage/s3.go index 26cf8e732..14bc97c16 100644 --- a/src/pkg/storage/s3.go +++ b/src/pkg/storage/s3.go @@ -31,8 +31,8 @@ const ( Prefix = "prefix" ) -func (c S3Config) Config() (config, error) { - cfg := config{ +func (c S3Config) StringConfig() (map[string]string, error) { + cfg := map[string]string{ keyS3AccessKey: c.AccessKey, keyS3Bucket: c.Bucket, keyS3Endpoint: c.Endpoint, diff --git a/src/pkg/storage/s3_test.go b/src/pkg/storage/s3_test.go index 4adc25f20..08e2e19bc 100644 --- a/src/pkg/storage/s3_test.go +++ b/src/pkg/storage/s3_test.go @@ -31,7 +31,7 @@ var goodS3Config = storage.S3Config{ func (suite *S3CfgSuite) TestS3Config_Config() { s3 := goodS3Config - c, err := s3.Config() + c, err := s3.StringConfig() assert.NoError(suite.T(), err) table := []struct { diff --git a/src/pkg/storage/storage.go b/src/pkg/storage/storage.go index 12a86d05c..66c196e01 100644 --- a/src/pkg/storage/storage.go +++ b/src/pkg/storage/storage.go @@ -3,6 +3,8 @@ package storage import ( "errors" "fmt" + + "github.com/alcionai/corso/internal/common" ) type storageProvider int @@ -18,43 +20,22 @@ var ( errMissingRequired = errors.New("missing required storage configuration") ) -type ( - config map[string]any - configurer interface { - Config() (config, error) - } -) - // Storage defines a storage provider, along with any configuration // requried to set up or communicate with that provider. type Storage struct { Provider storageProvider - Config config + Config map[string]string } // NewStorage aggregates all the supplied configurations into a single configuration. -func NewStorage(p storageProvider, cfgs ...configurer) (Storage, error) { - cs, err := unionConfigs(cfgs...) +func NewStorage(p storageProvider, cfgs ...common.StringConfigurer) (Storage, error) { + cs, err := common.UnionStringConfigs(cfgs...) return Storage{ Provider: p, Config: cs, }, err } -func unionConfigs(cfgs ...configurer) (config, error) { - union := config{} - for _, cfg := range cfgs { - c, err := cfg.Config() - if err != nil { - return nil, err - } - for k, v := range c { - union[k] = v - } - } - return union, nil -} - // Helper for parsing the values in a config object. // If the value is nil or not a string, returns an empty string. func orEmptyString(v any) string { diff --git a/src/pkg/storage/storage_test.go b/src/pkg/storage/storage_test.go index 0960ecbea..c87817b49 100644 --- a/src/pkg/storage/storage_test.go +++ b/src/pkg/storage/storage_test.go @@ -12,8 +12,8 @@ type testConfig struct { err error } -func (c testConfig) Config() (config, error) { - return config{"expect": c.expect}, c.err +func (c testConfig) StringConfig() (map[string]string, error) { + return map[string]string{"expect": c.expect}, c.err } type StorageSuite struct { @@ -55,43 +55,3 @@ func (suite *StorageSuite) TestNewStorage() { }) } } - -type fooConfig struct { - foo string - err error -} - -func (c fooConfig) Config() (config, error) { - return config{"foo": c.foo}, c.err -} - -func (suite *StorageSuite) TestUnionConfigs() { - table := []struct { - name string - tc testConfig - fc fooConfig - errCheck assert.ErrorAssertionFunc - }{ - {"no error", testConfig{"test", nil}, fooConfig{"foo", nil}, assert.NoError}, - {"tc error", testConfig{"test", assert.AnError}, fooConfig{"foo", nil}, assert.Error}, - {"fc error", testConfig{"test", nil}, fooConfig{"foo", assert.AnError}, assert.Error}, - } - for _, test := range table { - suite.T().Run(test.name, func(t *testing.T) { - cs, err := unionConfigs(test.tc, test.fc) - test.errCheck(t, err) - // remaining tests depend on error-free state - if test.tc.err != nil || test.fc.err != nil { - return - } - assert.Equalf(t, - test.tc.expect, - cs["expect"], - "expected unioned config to have value [%s] at key [expect], got [%s]", test.tc.expect, cs["expect"]) - assert.Equalf(t, - test.fc.foo, - cs["foo"], - "expected unioned config to have value [%s] at key [foo], got [%s]", test.fc.foo, cs["foo"]) - }) - } -}