/* Copyright © The ESO Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package beyondtrustworkloadcredentials import ( "context" "encoding/json" "fmt" "path" "strings" "testing" "github.com/google/go-cmp/cmp" esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1" "github.com/external-secrets/external-secrets/providers/v1/beyondtrustworkloadcredentials/fake" btwcutil "github.com/external-secrets/external-secrets/providers/v1/beyondtrustworkloadcredentials/util" ) const ( validSecretName = "apikey" validFolderPath = "valid/folder/path" invalidSecretName = "INVALID_NAME" invalidFolderPath = "INVALID_PATH" ) /////////////////////// // test case structs // /////////////////////// type beyondtrustworkloadcredentialsGetSecretTestCase struct { label string fakeBtsecretsClient *fake.BeyondtrustWorkloadCredentialsClient ctx context.Context name *string folderPath *string remoteRef esv1.ExternalSecretDataRemoteRef fakeBtsecretsResponse *btwcutil.KV fakeBtsecretsError *string expectedError *string expectedResponse []byte } type beyondtrustworkloadcredentialsGetAllSecretsTestCase struct { label string fakeBtsecretsClient *fake.BeyondtrustWorkloadCredentialsClient ctx context.Context name *string names []string folderPath *string remoteRef esv1.ExternalSecretFind fakeBtsecretsGetResponse *btwcutil.KV fakeBtsecretsGetResponses []btwcutil.KV fakeBtsecretsListResponse []btwcutil.KVListItem fakeBtsecretsGetError *string fakeBtsecretsListError *string expectedError *string expectedResponse map[string][]byte } //////////// // makers // //////////// // makeValidGetSecretTestCase creates a valid test case for GetSecret tests. func makeValidGetSecretTestCase() *beyondtrustworkloadcredentialsGetSecretTestCase { return &beyondtrustworkloadcredentialsGetSecretTestCase{ fakeBtsecretsClient: &fake.BeyondtrustWorkloadCredentialsClient{}, ctx: context.Background(), name: new(validSecretName), folderPath: new(validFolderPath), remoteRef: esv1.ExternalSecretDataRemoteRef{Key: validSecretName, Property: ""}, } } // makeValidGetAllSecretsTestCase creates a valid test case for GetSecrets tests. func makeValidGetAllSecretsTestCase() *beyondtrustworkloadcredentialsGetAllSecretsTestCase { return &beyondtrustworkloadcredentialsGetAllSecretsTestCase{ fakeBtsecretsClient: &fake.BeyondtrustWorkloadCredentialsClient{}, ctx: context.Background(), name: new(validSecretName), folderPath: new(validFolderPath), remoteRef: esv1.ExternalSecretFind{}, } } // makeValidGetSecretTestCaseWithValues injects values into the faked BeyondtrustWorkloadCredentialsClient for GetSecret tests. func makeValidGetSecretTestCaseWithValues(tweaks ...func(tc *beyondtrustworkloadcredentialsGetSecretTestCase)) *beyondtrustworkloadcredentialsGetSecretTestCase { vtc := makeValidGetSecretTestCase() for _, fn := range tweaks { fn(vtc) } vtc.fakeBtsecretsClient.WithValues(vtc.ctx, vtc.name, vtc.folderPath, vtc.fakeBtsecretsResponse, nil, vtc.fakeBtsecretsError, nil) return vtc } // makeValidGetAllSecretsTestCaseWithValues injects values into the faked BeyondtrustWorkloadCredentialsClient for GetSecrets tests. func makeValidGetAllSecretsTestCaseWithValues(tweaks ...func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase)) *beyondtrustworkloadcredentialsGetAllSecretsTestCase { vtc := makeValidGetAllSecretsTestCase() for _, fn := range tweaks { fn(vtc) } vtc.fakeBtsecretsClient.WithValues(vtc.ctx, vtc.name, vtc.folderPath, vtc.fakeBtsecretsGetResponse, vtc.fakeBtsecretsListResponse, vtc.fakeBtsecretsGetError, vtc.fakeBtsecretsListError) return vtc } // makeValidGetAllSecretsTestCaseWithMultiValues injects values with multiple GET responses into the faked BeyondtrustWorkloadCredentialsClient for GetSecrets tests. func makeValidGetAllSecretsTestCaseWithMultiValues(tweaks ...func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase)) *beyondtrustworkloadcredentialsGetAllSecretsTestCase { vtc := makeValidGetAllSecretsTestCase() for _, fn := range tweaks { fn(vtc) } vtc.fakeBtsecretsClient.WithMultiValues(vtc.ctx, vtc.names, vtc.folderPath, vtc.fakeBtsecretsGetResponses, vtc.fakeBtsecretsListResponse, vtc.fakeBtsecretsGetError, vtc.fakeBtsecretsListError) return vtc } /////////// // tests // /////////// func TestGetSecret(t *testing.T) { // happy paths validSecret := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName), Secret: map[string]any{"valid": "test"}, } fakeKVBytes, err := json.Marshal(fakeKV.Secret) if err != nil { t.Errorf("failed to marshal fake KV: %#v, error: %q", fakeKV, err.Error()) } tc.label = "GetSecret - Valid" tc.fakeBtsecretsResponse = fakeKV tc.expectedResponse = fakeKVBytes } validSecretProperty := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) { propertyValue := "test" fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName), Secret: map[string]any{"valid": propertyValue, "doNotInclude": "this"}, } tc.label = "GetSecret - Valid Property" tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: validSecretName, Property: "valid"} tc.fakeBtsecretsResponse = fakeKV tc.expectedResponse = []byte(propertyValue) } // sad paths clientError := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) { tc.label = "GetSecret - Client Error" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName} tc.fakeBtsecretsError = new("beyondtrustworkloadcredentials error") tc.expectedError = new("failed to get secret") } nilSecret := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName), } tc.label = "GetSecret - Nil Secret" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName} tc.fakeBtsecretsResponse = fakeKV tc.expectedError = new("secret value is nil") } invalidSecretProperty := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName), Secret: map[string]any{"invalid": "test"}, } ref := esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName, Property: "nonexistant"} tc.label = "GetSecret - Invalid Property" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.remoteRef = ref tc.fakeBtsecretsResponse = fakeKV tc.expectedError = new(fmt.Sprintf("property %s not found in secret", ref.Property)) } invalidSecret := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName), Secret: map[string]any{"invalid": func() {}}, } tc.label = "GetSecret - Invalid" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName} tc.fakeBtsecretsResponse = fakeKV tc.expectedError = new("failed to marshal secret") } testCases := []*beyondtrustworkloadcredentialsGetSecretTestCase{ // happy paths makeValidGetSecretTestCaseWithValues(validSecret), makeValidGetSecretTestCaseWithValues(validSecretProperty), // sad paths makeValidGetSecretTestCaseWithValues(clientError), makeValidGetSecretTestCaseWithValues(nilSecret), makeValidGetSecretTestCaseWithValues(invalidSecretProperty), makeValidGetSecretTestCaseWithValues(invalidSecret), } c := Client{store: &esv1.BeyondtrustWorkloadCredentialsProvider{}} for i, tc := range testCases { t.Run(tc.label, func(t *testing.T) { c.beyondtrustWorkloadCredentialsClient = tc.fakeBtsecretsClient c.store.FolderPath = *tc.folderPath out, err := c.GetSecret(context.Background(), tc.remoteRef) // assert error if tc.expectedError == nil && err != nil { t.Errorf("[%d] unexpected error: expected nil, got %q", i, err.Error()) } if tc.expectedError != nil && !ErrorContains(err, *tc.expectedError) { t.Errorf("[%d] unexpected error: expected %q, got %q", i, *tc.expectedError, err) } // assert response if tc.expectedResponse == nil && out != nil { t.Errorf("[%d] unexpected response: expected nil, got %#v", i, out) } if tc.expectedResponse != nil && !cmp.Equal(out, tc.expectedResponse) { t.Errorf("[%d] unexpected response: expected %#v, got %#v", i, tc.expectedResponse, out) } }) } } func ErrorContains(out error, want string) bool { if out == nil { return want == "" } if want == "" { return false } return strings.Contains(out.Error(), want) } func TestGetAllSecrets(t *testing.T) { // happy paths validSecretKVs := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName), Secret: map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"}, } fakeListItem := btwcutil.KVListItem{ Path: fakeKV.Path, } fakeKVBytes := map[string][]byte{ fakeKV.Path + "/key1": []byte("val1"), fakeKV.Path + "/key2": []byte("val2"), fakeKV.Path + "/key3": []byte("val3"), } tc.label = "GetAllSecrets - Secret KVs - Valid" tc.remoteRef = esv1.ExternalSecretFind{Path: new(validFolderPath)} tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{fakeListItem} tc.fakeBtsecretsGetResponse = fakeKV tc.expectedResponse = fakeKVBytes } validNamedSecrets := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) { findName := fmt.Sprintf("%s-include", validSecretName) fakeKV1 := btwcutil.KV{ Path: fmt.Sprintf("%s/%s-fakeKV1", validFolderPath, findName), Secret: map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"}, } fakeKV2 := btwcutil.KV{ Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName), } fakeKV3 := btwcutil.KV{ Path: fmt.Sprintf("%s/%s-fakeKV3", validFolderPath, findName), Secret: map[string]any{"key6": "val6"}, } fakeListItem1 := btwcutil.KVListItem{ Path: fakeKV1.Path, } fakeListItem2 := btwcutil.KVListItem{ Path: fakeKV2.Path, } fakeListItem3 := btwcutil.KVListItem{ Path: fakeKV3.Path, } fakeResponseBytes := map[string][]byte{ fakeKV1.Path + "/key1": []byte("val1"), fakeKV1.Path + "/key2": []byte("val2"), fakeKV1.Path + "/key3": []byte("val3"), fakeKV3.Path + "/key6": []byte("val6"), } _, name1 := path.Split(fakeListItem1.Path) _, name3 := path.Split(fakeListItem3.Path) tc.label = "GetAllSecrets - Secret KVs - Valid Find RegExp" tc.names = []string{name1, name3} tc.remoteRef = esv1.ExternalSecretFind{Name: &esv1.FindName{RegExp: fmt.Sprintf("^%s.*", findName)}} tc.fakeBtsecretsGetResponses = []btwcutil.KV{fakeKV1, fakeKV3} tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{fakeListItem1, fakeListItem2, fakeListItem3} tc.expectedResponse = fakeResponseBytes } validAllSecrets := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) { findPath := fmt.Sprintf("%s/%s-include", validFolderPath, validSecretName) fakeKV1 := btwcutil.KV{ Path: fmt.Sprintf("%s-fakeKV1", findPath), Secret: map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"}, } fakeKV2 := btwcutil.KV{ Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName), Secret: map[string]any{"key4": "val4", "key5": "val5"}, } fakeKV3 := btwcutil.KV{ Path: fmt.Sprintf("%s-fakeKV3", findPath), Secret: map[string]any{"key6": "val6"}, } fakeListItem1 := btwcutil.KVListItem{ Path: fmt.Sprintf("%s-fakeKV1", findPath), } fakeListItem2 := btwcutil.KVListItem{ Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName), } fakeListItem3 := btwcutil.KVListItem{ Path: fmt.Sprintf("%s-fakeKV3", findPath), } fakeResponseBytes := map[string][]byte{ fakeKV1.Path + "/key1": []byte("val1"), fakeKV1.Path + "/key2": []byte("val2"), fakeKV1.Path + "/key3": []byte("val3"), fakeKV2.Path + "/key4": []byte("val4"), fakeKV2.Path + "/key5": []byte("val5"), fakeKV3.Path + "/key6": []byte("val6"), } _, name1 := path.Split(fakeListItem1.Path) _, name2 := path.Split(fakeListItem2.Path) _, name3 := path.Split(fakeListItem3.Path) tc.label = "GetAllSecrets - List Secrets - Valid" tc.names = []string{name1, name2, name3} tc.fakeBtsecretsGetResponses = []btwcutil.KV{fakeKV1, fakeKV2, fakeKV3} tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{fakeListItem1, fakeListItem2, fakeListItem3} tc.expectedResponse = fakeResponseBytes } // sad paths clientGetError := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) { tc.label = "GetAllSecrets - Secret KVs - Client Error" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.remoteRef = esv1.ExternalSecretFind{Path: new(invalidFolderPath)} tc.fakeBtsecretsListError = new("beyondtrustworkloadcredentials list error") tc.expectedError = new("failed to list secrets:") } nilSecret := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName), } fakeListItem := btwcutil.KVListItem{ Path: fakeKV.Path, } tc.label = "GetAllSecrets - Secret KVs - Nil Secret" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.remoteRef = esv1.ExternalSecretFind{Path: new(invalidFolderPath)} tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{fakeListItem} tc.fakeBtsecretsGetResponse = fakeKV // Provider now returns NoSecretError when no results are found tc.expectedError = new("Secret does not exist") } invalidSecret := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName), Secret: map[string]any{"invalid": func() {}}, } fakeListItem := btwcutil.KVListItem{ Path: fakeKV.Path, } tc.label = "GetAllSecrets - Secret KVs - Invalid Secret" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.remoteRef = esv1.ExternalSecretFind{Path: new(invalidFolderPath)} tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{fakeListItem} tc.fakeBtsecretsGetResponse = fakeKV tc.expectedError = new("failed to marshal secret value for key") } clientListError := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) { tc.label = "GetAllSecrets - List Secrets - Client Error" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.fakeBtsecretsListError = new("beyondtrustworkloadcredentials list error") tc.expectedError = new("failed to list secrets:") } invalidFindRegex := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) { tc.label = "GetAllSecrets - List Secrets - Invalid Find RegExp" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.remoteRef = esv1.ExternalSecretFind{Name: &esv1.FindName{RegExp: "[invalid-regex"}} tc.expectedError = new("invalid name regexp") } clientGetErrorInList := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) { tc.label = "GetAllSecrets - List Secrets - Get KVs - Client Error" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{{}} tc.fakeBtsecretsGetError = new("beyondtrustworkloadcredentials get error in list") tc.expectedError = new("failed to get secret at path") } nilSecretInList := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName), } tc.label = "GetAllSecrets - List Secrets - Get KVs - Nil Secret" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.fakeBtsecretsGetResponse = fakeKV tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{{Path: fakeKV.Path}} // In list mode, skip missing entries; when no results are found, return NoSecretError tc.expectedError = new("Secret does not exist") } invalidSecretInList := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName), Secret: map[string]any{"invalid": func() {}}, } tc.label = "GetAllSecrets - List Secrets - Get KVs - Invalid" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.fakeBtsecretsGetResponse = fakeKV tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{{Path: fakeKV.Path}} tc.expectedError = new("failed to marshal secret value for key") } testCases := []*beyondtrustworkloadcredentialsGetAllSecretsTestCase{ // happy paths makeValidGetAllSecretsTestCaseWithValues(validSecretKVs), makeValidGetAllSecretsTestCaseWithMultiValues(validNamedSecrets), makeValidGetAllSecretsTestCaseWithMultiValues(validAllSecrets), // sad paths makeValidGetAllSecretsTestCaseWithValues(clientGetError), makeValidGetAllSecretsTestCaseWithValues(nilSecret), makeValidGetAllSecretsTestCaseWithValues(invalidSecret), makeValidGetAllSecretsTestCaseWithValues(clientListError), makeValidGetAllSecretsTestCaseWithValues(invalidFindRegex), makeValidGetAllSecretsTestCaseWithValues(clientGetErrorInList), makeValidGetAllSecretsTestCaseWithValues(nilSecretInList), makeValidGetAllSecretsTestCaseWithValues(invalidSecretInList), } c := Client{store: &esv1.BeyondtrustWorkloadCredentialsProvider{}} for i, tc := range testCases { t.Run(tc.label, func(t *testing.T) { c.beyondtrustWorkloadCredentialsClient = tc.fakeBtsecretsClient c.store.FolderPath = *tc.folderPath out, err := c.GetAllSecrets(context.Background(), tc.remoteRef) // assert error if tc.expectedError == nil && err != nil { t.Errorf("[%d] unexpected error: expected nil, got %q", i, err.Error()) } if tc.expectedError != nil && !ErrorContains(err, *tc.expectedError) { t.Errorf("[%d] unexpected error: expected %q, got %q", i, *tc.expectedError, err) } // assert response if tc.expectedResponse == nil && out != nil { t.Errorf("[%d] unexpected response: expected nil, got %#v", i, out) } if tc.expectedResponse != nil && !cmp.Equal(out, tc.expectedResponse) { t.Errorf("[%d] unexpected response: expected %#v, got %#v", i, tc.expectedResponse, out) } }) } } func TestGetSecretMap(t *testing.T) { // happy paths validSecretMap := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName), Secret: map[string]any{"username": "admin", "password": "secret123", "port": 5432}, } tc.label = "GetSecretMap - Valid" tc.fakeBtsecretsResponse = fakeKV // For GetSecretMap tests, we use a map comparison, not a single byte response // This test will use a custom comparison below } validSecretMapWithTypes := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName), Secret: map[string]any{ "username": "admin", "config": map[string]string{"env": "prod", "region": "us-east-1"}, }, } tc.label = "GetSecretMap - Valid With Complex Types" tc.fakeBtsecretsResponse = fakeKV } // sad paths clientError := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) { tc.label = "GetSecretMap - Client Error" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName} tc.fakeBtsecretsError = new("beyondtrustworkloadcredentials error") tc.expectedError = new("failed to get secret") } nilSecret := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName), } tc.label = "GetSecretMap - Nil Secret" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName} tc.fakeBtsecretsResponse = fakeKV tc.expectedError = new("secret value is nil") } invalidSecret := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) { fakeKV := &btwcutil.KV{ Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName), Secret: map[string]any{ "valid": "test", "invalid": func() {}, // Unmarshalable type }, } tc.label = "GetSecretMap - Invalid" tc.name = new(invalidSecretName) tc.folderPath = new(invalidFolderPath) tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName} tc.fakeBtsecretsResponse = fakeKV tc.expectedError = new("failed to marshal secret value for key") } testCases := []*beyondtrustworkloadcredentialsGetSecretTestCase{ // happy paths makeValidGetSecretTestCaseWithValues(validSecretMap), makeValidGetSecretTestCaseWithValues(validSecretMapWithTypes), // sad paths makeValidGetSecretTestCaseWithValues(clientError), makeValidGetSecretTestCaseWithValues(nilSecret), makeValidGetSecretTestCaseWithValues(invalidSecret), } c := Client{store: &esv1.BeyondtrustWorkloadCredentialsProvider{}} for i, tc := range testCases { t.Run(tc.label, func(t *testing.T) { c.beyondtrustWorkloadCredentialsClient = tc.fakeBtsecretsClient c.store.FolderPath = *tc.folderPath out, err := c.GetSecretMap(context.Background(), tc.remoteRef) // assert error if tc.expectedError == nil && err != nil { t.Errorf("[%d] unexpected error: expected nil, got %q", i, err.Error()) } if tc.expectedError != nil && !ErrorContains(err, *tc.expectedError) { t.Errorf("[%d] unexpected error: expected %q, got %q", i, *tc.expectedError, err) } // For happy path tests with complex types, just verify no error and non-nil response if i < 2 && tc.expectedError == nil { if out == nil { t.Errorf("[%d] unexpected response: expected non-nil map, got nil", i) } if len(out) == 0 { t.Errorf("[%d] unexpected response: expected non-empty map, got empty", i) } } }) } }