1// +build !integration
2
3package common
4
5import (
6	"testing"
7
8	"github.com/stretchr/testify/assert"
9	"github.com/stretchr/testify/mock"
10	"github.com/stretchr/testify/require"
11)
12
13func TestDefaultResolver_Resolve(t *testing.T) {
14	variableKey := "TEST_VARIABLE"
15	returnValue := "test"
16	secrets := Secrets{
17		variableKey: Secret{
18			Vault: &VaultSecret{
19				Server: VaultServer{
20					URL: "url",
21					Auth: VaultAuth{
22						Name: "name",
23						Path: "path",
24						Data: VaultAuthData{"data": "data"},
25					},
26				},
27				Engine: VaultEngine{
28					Name: "name",
29					Path: "path",
30				},
31				Path:  "path",
32				Field: "field",
33			},
34		},
35	}
36
37	composeSecrets := func(file bool) Secrets {
38		secret := secrets[variableKey]
39		secret.File = &file
40
41		return Secrets{variableKey: secret}
42	}
43
44	getLogger := func(t *testing.T) (logger, func()) {
45		logger := new(mockLogger)
46		logger.On("Println", mock.Anything).Maybe()
47
48		return logger, func() { logger.AssertExpectations(t) }
49	}
50
51	tests := map[string]struct {
52		getLogger                     func(t *testing.T) (logger, func())
53		supportedResolverPresent      bool
54		secrets                       Secrets
55		resolvedVariable              *JobVariable
56		errorOnSecretResolving        error
57		expectedResolverCreationError error
58		expectedVariables             JobVariables
59		expectedError                 error
60	}{
61		"resolver creation error": {
62			getLogger: func(t *testing.T) (logger, func()) {
63				return nil, func() {}
64			},
65			expectedResolverCreationError: ErrMissingLogger,
66		},
67		"no secrets to resolve": {
68			getLogger:                getLogger,
69			supportedResolverPresent: true,
70			secrets:                  nil,
71			expectedVariables:        nil,
72			expectedError:            nil,
73		},
74		"error on secret resolving": {
75			getLogger:                getLogger,
76			supportedResolverPresent: true,
77			secrets:                  secrets,
78			errorOnSecretResolving:   assert.AnError,
79			expectedVariables:        nil,
80			expectedError:            assert.AnError,
81		},
82		"secret resolved properly - file not defined": {
83			getLogger:                getLogger,
84			supportedResolverPresent: true,
85			secrets:                  secrets,
86			expectedVariables: JobVariables{
87				{
88					Key:   variableKey,
89					Value: returnValue,
90					File:  true,
91				},
92			},
93			expectedError: nil,
94		},
95		"secret resolved properly - file set to true": {
96			getLogger:                getLogger,
97			supportedResolverPresent: true,
98			secrets:                  composeSecrets(true),
99			expectedVariables: JobVariables{
100				{
101					Key:   variableKey,
102					Value: returnValue,
103					File:  true,
104				},
105			},
106			expectedError: nil,
107		},
108		"secret resolved properly - file set to false": {
109			getLogger:                getLogger,
110			supportedResolverPresent: true,
111			secrets:                  composeSecrets(false),
112			expectedVariables: JobVariables{
113				{
114					Key:   variableKey,
115					Value: returnValue,
116					File:  false,
117				},
118			},
119			expectedError: nil,
120		},
121		"no supported resolvers present": {
122			getLogger: func(t *testing.T) (logger, func()) {
123				logger := new(mockLogger)
124				logger.On("Println", mock.Anything).Maybe()
125				logger.On("Warningln", mock.Anything).Maybe()
126
127				return logger, func() { logger.AssertExpectations(t) }
128			},
129			supportedResolverPresent: false,
130			secrets:                  secrets,
131			expectedVariables:        JobVariables{},
132			expectedError:            nil,
133		},
134	}
135
136	for tn, tt := range tests {
137		t.Run(tn, func(t *testing.T) {
138			unsupportedResolver := new(MockSecretResolver)
139			defer unsupportedResolver.AssertExpectations(t)
140			supportedResolver := new(MockSecretResolver)
141			defer supportedResolver.AssertExpectations(t)
142
143			if tt.secrets != nil {
144				unsupportedResolver.On("IsSupported").
145					Return(false).
146					Once()
147
148				supportedResolver.On("IsSupported").
149					Return(tt.supportedResolverPresent).
150					Once()
151				supportedResolver.On("Name").
152					Return("supported_resolver").
153					Maybe()
154				if tt.supportedResolverPresent {
155					supportedResolver.On("Resolve").
156						Return(returnValue, tt.errorOnSecretResolving).
157						Once()
158				}
159			}
160
161			registry := new(defaultSecretResolverRegistry)
162			registry.Register(func(secret Secret) SecretResolver { return unsupportedResolver })
163			registry.Register(func(secret Secret) SecretResolver { return supportedResolver })
164
165			logger, loggerCleanup := tt.getLogger(t)
166			defer loggerCleanup()
167
168			r, err := newSecretsResolver(logger, registry)
169			if tt.expectedResolverCreationError != nil {
170				assert.ErrorAs(t, err, &tt.expectedResolverCreationError)
171				return
172			}
173			require.NoError(t, err)
174
175			variables, err := r.Resolve(tt.secrets)
176
177			if tt.expectedError != nil {
178				assert.ErrorAs(t, err, &tt.expectedError)
179				return
180			}
181
182			assert.NoError(t, err)
183			assert.Equal(t, tt.expectedVariables, variables)
184		})
185	}
186}
187