github.com/argoproj/argo-cd/v2@v2.10.9/applicationset/generators/pull_request_test.go (about) 1 package generators 2 3 import ( 4 "context" 5 "fmt" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 corev1 "k8s.io/api/core/v1" 10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 "sigs.k8s.io/controller-runtime/pkg/client/fake" 12 13 pullrequest "github.com/argoproj/argo-cd/v2/applicationset/services/pull_request" 14 argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" 15 ) 16 17 func TestPullRequestGithubGenerateParams(t *testing.T) { 18 ctx := context.Background() 19 cases := []struct { 20 selectFunc func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) 21 expected []map[string]interface{} 22 expectedErr error 23 applicationSet argoprojiov1alpha1.ApplicationSet 24 }{ 25 { 26 selectFunc: func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) { 27 return pullrequest.NewFakeService( 28 ctx, 29 []*pullrequest.PullRequest{ 30 { 31 Number: 1, 32 Branch: "branch1", 33 TargetBranch: "master", 34 HeadSHA: "089d92cbf9ff857a39e6feccd32798ca700fb958", 35 }, 36 }, 37 nil, 38 ) 39 }, 40 expected: []map[string]interface{}{ 41 { 42 "number": "1", 43 "branch": "branch1", 44 "branch_slug": "branch1", 45 "target_branch": "master", 46 "target_branch_slug": "master", 47 "head_sha": "089d92cbf9ff857a39e6feccd32798ca700fb958", 48 "head_short_sha": "089d92cb", 49 "head_short_sha_7": "089d92c", 50 }, 51 }, 52 expectedErr: nil, 53 }, 54 { 55 selectFunc: func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) { 56 return pullrequest.NewFakeService( 57 ctx, 58 []*pullrequest.PullRequest{ 59 { 60 Number: 2, 61 Branch: "feat/areally+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", 62 TargetBranch: "feat/anotherreally+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", 63 HeadSHA: "9b34ff5bd418e57d58891eb0aa0728043ca1e8be", 64 }, 65 }, 66 nil, 67 ) 68 }, 69 expected: []map[string]interface{}{ 70 { 71 "number": "2", 72 "branch": "feat/areally+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", 73 "branch_slug": "feat-areally-long-pull-request-name-to-test-argo", 74 "target_branch": "feat/anotherreally+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", 75 "target_branch_slug": "feat-anotherreally-long-pull-request-name-to-test", 76 "head_sha": "9b34ff5bd418e57d58891eb0aa0728043ca1e8be", 77 "head_short_sha": "9b34ff5b", 78 "head_short_sha_7": "9b34ff5", 79 }, 80 }, 81 expectedErr: nil, 82 }, 83 { 84 selectFunc: func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) { 85 return pullrequest.NewFakeService( 86 ctx, 87 []*pullrequest.PullRequest{ 88 { 89 Number: 1, 90 Branch: "a-very-short-sha", 91 TargetBranch: "master", 92 HeadSHA: "abcd", 93 }, 94 }, 95 nil, 96 ) 97 }, 98 expected: []map[string]interface{}{ 99 { 100 "number": "1", 101 "branch": "a-very-short-sha", 102 "branch_slug": "a-very-short-sha", 103 "target_branch": "master", 104 "target_branch_slug": "master", 105 "head_sha": "abcd", 106 "head_short_sha": "abcd", 107 "head_short_sha_7": "abcd", 108 }, 109 }, 110 expectedErr: nil, 111 }, 112 { 113 selectFunc: func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) { 114 return pullrequest.NewFakeService( 115 ctx, 116 nil, 117 fmt.Errorf("fake error"), 118 ) 119 }, 120 expected: nil, 121 expectedErr: fmt.Errorf("error listing repos: fake error"), 122 }, 123 { 124 selectFunc: func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) { 125 return pullrequest.NewFakeService( 126 ctx, 127 []*pullrequest.PullRequest{ 128 { 129 Number: 1, 130 Branch: "branch1", 131 TargetBranch: "master", 132 HeadSHA: "089d92cbf9ff857a39e6feccd32798ca700fb958", 133 Labels: []string{"preview"}, 134 }, 135 }, 136 nil, 137 ) 138 }, 139 expected: []map[string]interface{}{ 140 { 141 "number": "1", 142 "branch": "branch1", 143 "branch_slug": "branch1", 144 "target_branch": "master", 145 "target_branch_slug": "master", 146 "head_sha": "089d92cbf9ff857a39e6feccd32798ca700fb958", 147 "head_short_sha": "089d92cb", 148 "head_short_sha_7": "089d92c", 149 "labels": []string{"preview"}, 150 }, 151 }, 152 expectedErr: nil, 153 applicationSet: argoprojiov1alpha1.ApplicationSet{ 154 Spec: argoprojiov1alpha1.ApplicationSetSpec{ 155 // Application set is using Go Template. 156 GoTemplate: true, 157 }, 158 }, 159 }, 160 { 161 selectFunc: func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) { 162 return pullrequest.NewFakeService( 163 ctx, 164 []*pullrequest.PullRequest{ 165 { 166 Number: 1, 167 Branch: "branch1", 168 TargetBranch: "master", 169 HeadSHA: "089d92cbf9ff857a39e6feccd32798ca700fb958", 170 Labels: []string{"preview"}, 171 }, 172 }, 173 nil, 174 ) 175 }, 176 expected: []map[string]interface{}{ 177 { 178 "number": "1", 179 "branch": "branch1", 180 "branch_slug": "branch1", 181 "target_branch": "master", 182 "target_branch_slug": "master", 183 "head_sha": "089d92cbf9ff857a39e6feccd32798ca700fb958", 184 "head_short_sha": "089d92cb", 185 "head_short_sha_7": "089d92c", 186 }, 187 }, 188 expectedErr: nil, 189 applicationSet: argoprojiov1alpha1.ApplicationSet{ 190 Spec: argoprojiov1alpha1.ApplicationSetSpec{ 191 // Application set is using fasttemplate. 192 GoTemplate: false, 193 }, 194 }, 195 }, 196 } 197 198 for _, c := range cases { 199 gen := PullRequestGenerator{ 200 selectServiceProviderFunc: c.selectFunc, 201 } 202 generatorConfig := argoprojiov1alpha1.ApplicationSetGenerator{ 203 PullRequest: &argoprojiov1alpha1.PullRequestGenerator{}, 204 } 205 206 got, gotErr := gen.GenerateParams(&generatorConfig, &c.applicationSet) 207 assert.Equal(t, c.expectedErr, gotErr) 208 assert.ElementsMatch(t, c.expected, got) 209 } 210 } 211 212 func TestPullRequestGetSecretRef(t *testing.T) { 213 secret := &corev1.Secret{ 214 ObjectMeta: metav1.ObjectMeta{Name: "test-secret", Namespace: "test"}, 215 Data: map[string][]byte{ 216 "my-token": []byte("secret"), 217 }, 218 } 219 gen := &PullRequestGenerator{client: fake.NewClientBuilder().WithObjects(secret).Build()} 220 ctx := context.Background() 221 222 cases := []struct { 223 name, namespace, token string 224 ref *argoprojiov1alpha1.SecretRef 225 hasError bool 226 }{ 227 { 228 name: "valid ref", 229 ref: &argoprojiov1alpha1.SecretRef{SecretName: "test-secret", Key: "my-token"}, 230 namespace: "test", 231 token: "secret", 232 hasError: false, 233 }, 234 { 235 name: "nil ref", 236 ref: nil, 237 namespace: "test", 238 token: "", 239 hasError: false, 240 }, 241 { 242 name: "wrong name", 243 ref: &argoprojiov1alpha1.SecretRef{SecretName: "other", Key: "my-token"}, 244 namespace: "test", 245 token: "", 246 hasError: true, 247 }, 248 { 249 name: "wrong key", 250 ref: &argoprojiov1alpha1.SecretRef{SecretName: "test-secret", Key: "other-token"}, 251 namespace: "test", 252 token: "", 253 hasError: true, 254 }, 255 { 256 name: "wrong namespace", 257 ref: &argoprojiov1alpha1.SecretRef{SecretName: "test-secret", Key: "my-token"}, 258 namespace: "other", 259 token: "", 260 hasError: true, 261 }, 262 } 263 264 for _, c := range cases { 265 t.Run(c.name, func(t *testing.T) { 266 token, err := gen.getSecretRef(ctx, c.ref, c.namespace) 267 if c.hasError { 268 assert.NotNil(t, err) 269 } else { 270 assert.Nil(t, err) 271 } 272 assert.Equal(t, c.token, token) 273 }) 274 } 275 } 276 277 func TestAllowedSCMProviderPullRequest(t *testing.T) { 278 cases := []struct { 279 name string 280 providerConfig *argoprojiov1alpha1.PullRequestGenerator 281 expectedError error 282 }{ 283 { 284 name: "Error Github", 285 providerConfig: &argoprojiov1alpha1.PullRequestGenerator{ 286 Github: &argoprojiov1alpha1.PullRequestGeneratorGithub{ 287 API: "https://myservice.mynamespace.svc.cluster.local", 288 }, 289 }, 290 expectedError: &ErrDisallowedSCMProvider{}, 291 }, 292 { 293 name: "Error Gitlab", 294 providerConfig: &argoprojiov1alpha1.PullRequestGenerator{ 295 GitLab: &argoprojiov1alpha1.PullRequestGeneratorGitLab{ 296 API: "https://myservice.mynamespace.svc.cluster.local", 297 }, 298 }, 299 expectedError: &ErrDisallowedSCMProvider{}, 300 }, 301 { 302 name: "Error Gitea", 303 providerConfig: &argoprojiov1alpha1.PullRequestGenerator{ 304 Gitea: &argoprojiov1alpha1.PullRequestGeneratorGitea{ 305 API: "https://myservice.mynamespace.svc.cluster.local", 306 }, 307 }, 308 expectedError: &ErrDisallowedSCMProvider{}, 309 }, 310 { 311 name: "Error Bitbucket", 312 providerConfig: &argoprojiov1alpha1.PullRequestGenerator{ 313 BitbucketServer: &argoprojiov1alpha1.PullRequestGeneratorBitbucketServer{ 314 API: "https://myservice.mynamespace.svc.cluster.local", 315 }, 316 }, 317 expectedError: &ErrDisallowedSCMProvider{}, 318 }, 319 } 320 321 for _, testCase := range cases { 322 testCaseCopy := testCase 323 324 t.Run(testCaseCopy.name, func(t *testing.T) { 325 t.Parallel() 326 327 pullRequestGenerator := NewPullRequestGenerator(nil, SCMAuthProviders{}, "", []string{ 328 "github.myorg.com", 329 "gitlab.myorg.com", 330 "gitea.myorg.com", 331 "bitbucket.myorg.com", 332 "azuredevops.myorg.com", 333 }, true) 334 335 applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ 336 ObjectMeta: metav1.ObjectMeta{ 337 Name: "set", 338 }, 339 Spec: argoprojiov1alpha1.ApplicationSetSpec{ 340 Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{ 341 PullRequest: testCaseCopy.providerConfig, 342 }}, 343 }, 344 } 345 346 _, err := pullRequestGenerator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo) 347 348 assert.Error(t, err, "Must return an error") 349 assert.ErrorAs(t, err, testCaseCopy.expectedError) 350 }) 351 } 352 } 353 354 func TestSCMProviderDisabled_PRGenerator(t *testing.T) { 355 generator := NewPullRequestGenerator(nil, SCMAuthProviders{}, "", []string{}, false) 356 357 applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ 358 ObjectMeta: metav1.ObjectMeta{ 359 Name: "set", 360 }, 361 Spec: argoprojiov1alpha1.ApplicationSetSpec{ 362 Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{ 363 PullRequest: &argoprojiov1alpha1.PullRequestGenerator{ 364 Github: &argoprojiov1alpha1.PullRequestGeneratorGithub{ 365 API: "https://myservice.mynamespace.svc.cluster.local", 366 }, 367 }, 368 }}, 369 }, 370 } 371 372 _, err := generator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo) 373 assert.ErrorIs(t, err, ErrSCMProvidersDisabled) 374 }