github.com/argoproj/argo-cd/v3@v3.2.1/applicationset/services/scm_provider/bitbucket_server_test.go (about) 1 package scm_provider 2 3 import ( 4 "crypto/x509" 5 "encoding/pem" 6 "io" 7 "net/http" 8 "net/http/httptest" 9 "testing" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func defaultHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { 16 t.Helper() 17 return func(w http.ResponseWriter, r *http.Request) { 18 w.Header().Set("Content-Type", "application/json") 19 var err error 20 switch r.RequestURI { 21 case "/rest/api/1.0/projects/PROJECT/repos?limit=100": 22 _, err = io.WriteString(w, `{ 23 "size": 1, 24 "limit": 100, 25 "isLastPage": true, 26 "values": [ 27 { 28 "id": 1, 29 "name": "REPO", 30 "project": { 31 "key": "PROJECT" 32 }, 33 "links": { 34 "clone": [ 35 { 36 "href": "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 37 "name": "ssh" 38 }, 39 { 40 "href": "https://mycompany.bitbucket.org/scm/PROJECT/REPO.git", 41 "name": "http" 42 } 43 ] 44 } 45 } 46 ], 47 "start": 0 48 }`) 49 case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches?limit=100": 50 _, err = io.WriteString(w, `{ 51 "size": 1, 52 "limit": 100, 53 "isLastPage": true, 54 "values": [ 55 { 56 "id": "refs/heads/main", 57 "displayId": "main", 58 "type": "BRANCH", 59 "latestCommit": "8d51122def5632836d1cb1026e879069e10a1e13", 60 "latestChangeset": "8d51122def5632836d1cb1026e879069e10a1e13", 61 "isDefault": true 62 } 63 ], 64 "start": 0 65 }`) 66 case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default": 67 _, err = io.WriteString(w, `{ 68 "id": "refs/heads/main", 69 "displayId": "main", 70 "type": "BRANCH", 71 "latestCommit": "8d51122def5632836d1cb1026e879069e10a1e13", 72 "latestChangeset": "8d51122def5632836d1cb1026e879069e10a1e13", 73 "isDefault": true 74 }`) 75 default: 76 t.Fail() 77 } 78 if err != nil { 79 t.Fail() 80 } 81 } 82 } 83 84 func verifyDefaultRepo(t *testing.T, err error, repos []*Repository) { 85 t.Helper() 86 require.NoError(t, err) 87 assert.Len(t, repos, 1) 88 assert.Equal(t, Repository{ 89 Organization: "PROJECT", 90 Repository: "REPO", 91 URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 92 Branch: "main", 93 SHA: "8d51122def5632836d1cb1026e879069e10a1e13", 94 Labels: []string{}, 95 RepositoryId: 1, 96 }, *repos[0]) 97 } 98 99 func TestListReposNoAuth(t *testing.T) { 100 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 101 assert.Empty(t, r.Header.Get("Authorization")) 102 defaultHandler(t)(w, r) 103 })) 104 defer ts.Close() 105 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil) 106 require.NoError(t, err) 107 repos, err := provider.ListRepos(t.Context(), "ssh") 108 verifyDefaultRepo(t, err, repos) 109 } 110 111 func TestListReposPagination(t *testing.T) { 112 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 113 assert.Empty(t, r.Header.Get("Authorization")) 114 var err error 115 switch r.RequestURI { 116 case "/rest/api/1.0/projects/PROJECT/repos?limit=100": 117 _, err = io.WriteString(w, `{ 118 "size": 1, 119 "limit": 100, 120 "isLastPage": false, 121 "values": [ 122 { 123 "id": 100, 124 "name": "REPO", 125 "project": { 126 "key": "PROJECT" 127 }, 128 "links": { 129 "clone": [ 130 { 131 "href": "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 132 "name": "ssh" 133 }, 134 { 135 "href": "https://mycompany.bitbucket.org/scm/PROJECT/REPO.git", 136 "name": "http" 137 } 138 ] 139 } 140 } 141 ], 142 "start": 0, 143 "nextPageStart": 200 144 }`) 145 case "/rest/api/1.0/projects/PROJECT/repos?limit=100&start=200": 146 _, err = io.WriteString(w, `{ 147 "size": 1, 148 "limit": 100, 149 "isLastPage": true, 150 "values": [ 151 { 152 "id": 200, 153 "name": "REPO2", 154 "project": { 155 "key": "PROJECT" 156 }, 157 "links": { 158 "clone": [ 159 { 160 "href": "ssh://git@mycompany.bitbucket.org/PROJECT/REPO2.git", 161 "name": "ssh" 162 }, 163 { 164 "href": "https://mycompany.bitbucket.org/scm/PROJECT/REPO2.git", 165 "name": "http" 166 } 167 ] 168 } 169 } 170 ], 171 "start": 200 172 }`) 173 case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default": 174 _, err = io.WriteString(w, `{ 175 "id": "refs/heads/main", 176 "displayId": "main", 177 "type": "BRANCH", 178 "latestCommit": "8d51122def5632836d1cb1026e879069e10a1e13", 179 "isDefault": true 180 }`) 181 case "/rest/api/1.0/projects/PROJECT/repos/REPO2/branches/default": 182 _, err = io.WriteString(w, `{ 183 "id": "refs/heads/development", 184 "displayId": "development", 185 "type": "BRANCH", 186 "latestCommit": "2d51122def5632836d1cb1026e879069e10a1e13", 187 "isDefault": true 188 }`) 189 default: 190 t.Fail() 191 } 192 if err != nil { 193 t.Fail() 194 } 195 })) 196 defer ts.Close() 197 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil) 198 require.NoError(t, err) 199 repos, err := provider.ListRepos(t.Context(), "ssh") 200 require.NoError(t, err) 201 assert.Len(t, repos, 2) 202 assert.Equal(t, Repository{ 203 Organization: "PROJECT", 204 Repository: "REPO", 205 URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 206 Branch: "main", 207 SHA: "8d51122def5632836d1cb1026e879069e10a1e13", 208 Labels: []string{}, 209 RepositoryId: 100, 210 }, *repos[0]) 211 212 assert.Equal(t, Repository{ 213 Organization: "PROJECT", 214 Repository: "REPO2", 215 URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO2.git", 216 Branch: "development", 217 SHA: "2d51122def5632836d1cb1026e879069e10a1e13", 218 Labels: []string{}, 219 RepositoryId: 200, 220 }, *repos[1]) 221 } 222 223 func TestGetBranchesBranchPagination(t *testing.T) { 224 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 225 assert.Empty(t, r.Header.Get("Authorization")) 226 switch r.RequestURI { 227 case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches?limit=100": 228 _, err := io.WriteString(w, `{ 229 "size": 1, 230 "limit": 100, 231 "isLastPage": false, 232 "values": [ 233 { 234 "id": "refs/heads/main", 235 "displayId": "main", 236 "type": "BRANCH", 237 "latestCommit": "8d51122def5632836d1cb1026e879069e10a1e13", 238 "latestChangeset": "8d51122def5632836d1cb1026e879069e10a1e13", 239 "isDefault": true 240 } 241 ], 242 "start": 0, 243 "nextPageStart": 200 244 }`) 245 if err != nil { 246 t.Fail() 247 } 248 return 249 case "/rest/api/1.0/projects/PROJECT/repos/REPO/branches?limit=100&start=200": 250 _, err := io.WriteString(w, `{ 251 "size": 1, 252 "limit": 100, 253 "isLastPage": true, 254 "values": [ 255 { 256 "id": "refs/heads/feature", 257 "displayId": "feature", 258 "type": "BRANCH", 259 "latestCommit": "9d51122def5632836d1cb1026e879069e10a1e13", 260 "latestChangeset": "9d51122def5632836d1cb1026e879069e10a1e13", 261 "isDefault": true 262 } 263 ], 264 "start": 200 265 }`) 266 if err != nil { 267 t.Fail() 268 } 269 return 270 } 271 defaultHandler(t)(w, r) 272 })) 273 defer ts.Close() 274 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil) 275 require.NoError(t, err) 276 repos, err := provider.GetBranches(t.Context(), &Repository{ 277 Organization: "PROJECT", 278 Repository: "REPO", 279 URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 280 Labels: []string{}, 281 RepositoryId: 1, 282 }) 283 require.NoError(t, err) 284 assert.Len(t, repos, 2) 285 assert.Equal(t, Repository{ 286 Organization: "PROJECT", 287 Repository: "REPO", 288 URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 289 Branch: "main", 290 SHA: "8d51122def5632836d1cb1026e879069e10a1e13", 291 Labels: []string{}, 292 RepositoryId: 1, 293 }, *repos[0]) 294 295 assert.Equal(t, Repository{ 296 Organization: "PROJECT", 297 Repository: "REPO", 298 URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 299 Branch: "feature", 300 SHA: "9d51122def5632836d1cb1026e879069e10a1e13", 301 Labels: []string{}, 302 RepositoryId: 1, 303 }, *repos[1]) 304 } 305 306 func TestGetBranchesDefaultOnly(t *testing.T) { 307 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 308 assert.Empty(t, r.Header.Get("Authorization")) 309 if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { 310 _, err := io.WriteString(w, `{ 311 "id": "refs/heads/default", 312 "displayId": "default", 313 "type": "BRANCH", 314 "latestCommit": "ab51122def5632836d1cb1026e879069e10a1e13", 315 "latestChangeset": "ab51122def5632836d1cb1026e879069e10a1e13", 316 "isDefault": true 317 }`) 318 if err != nil { 319 t.Fail() 320 } 321 return 322 } 323 defaultHandler(t)(w, r) 324 })) 325 defer ts.Close() 326 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) 327 require.NoError(t, err) 328 repos, err := provider.GetBranches(t.Context(), &Repository{ 329 Organization: "PROJECT", 330 Repository: "REPO", 331 URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 332 Labels: []string{}, 333 RepositoryId: 1, 334 }) 335 require.NoError(t, err) 336 assert.Len(t, repos, 1) 337 assert.Equal(t, Repository{ 338 Organization: "PROJECT", 339 Repository: "REPO", 340 URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 341 Branch: "default", 342 SHA: "ab51122def5632836d1cb1026e879069e10a1e13", 343 Labels: []string{}, 344 RepositoryId: 1, 345 }, *repos[0]) 346 } 347 348 func TestGetBranchesMissingDefault(t *testing.T) { 349 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 350 assert.Empty(t, r.Header.Get("Authorization")) 351 if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { 352 http.Error(w, "Not found", http.StatusNotFound) 353 return 354 } 355 defaultHandler(t)(w, r) 356 })) 357 defer ts.Close() 358 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) 359 require.NoError(t, err) 360 repos, err := provider.GetBranches(t.Context(), &Repository{ 361 Organization: "PROJECT", 362 Repository: "REPO", 363 URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 364 Labels: []string{}, 365 RepositoryId: 1, 366 }) 367 require.NoError(t, err) 368 assert.Empty(t, repos) 369 } 370 371 func TestGetBranchesEmptyRepo(t *testing.T) { 372 ts := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) { 373 assert.Empty(t, r.Header.Get("Authorization")) 374 if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { 375 return 376 } 377 })) 378 defer ts.Close() 379 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) 380 require.NoError(t, err) 381 repos, err := provider.GetBranches(t.Context(), &Repository{ 382 Organization: "PROJECT", 383 Repository: "REPO", 384 URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 385 Labels: []string{}, 386 RepositoryId: 1, 387 }) 388 assert.Empty(t, repos) 389 require.NoError(t, err) 390 } 391 392 func TestGetBranchesErrorDefaultBranch(t *testing.T) { 393 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 394 assert.Empty(t, r.Header.Get("Authorization")) 395 if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { 396 http.Error(w, "Internal server error", http.StatusInternalServerError) 397 return 398 } 399 defaultHandler(t)(w, r) 400 })) 401 defer ts.Close() 402 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) 403 require.NoError(t, err) 404 _, err = provider.GetBranches(t.Context(), &Repository{ 405 Organization: "PROJECT", 406 Repository: "REPO", 407 URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 408 Labels: []string{}, 409 RepositoryId: 1, 410 }) 411 require.Error(t, err) 412 } 413 414 func TestListReposTLS(t *testing.T) { 415 tests := []struct { 416 name string 417 tlsInsecure bool 418 passCerts bool 419 requireErr bool 420 }{ 421 { 422 name: "TLS Insecure: true, No Certs", 423 tlsInsecure: true, 424 passCerts: false, 425 requireErr: false, 426 }, 427 { 428 name: "TLS Insecure: true, With Certs", 429 tlsInsecure: true, 430 passCerts: true, 431 requireErr: false, 432 }, 433 { 434 name: "TLS Insecure: false, With Certs", 435 tlsInsecure: false, 436 passCerts: true, 437 requireErr: false, 438 }, 439 { 440 name: "TLS Insecure: false, No Certs", 441 tlsInsecure: false, 442 passCerts: false, 443 requireErr: true, 444 }, 445 } 446 447 for _, test := range tests { 448 test := test 449 t.Run(test.name, func(t *testing.T) { 450 ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 451 defaultHandler(t)(w, r) 452 })) 453 defer ts.Close() 454 455 var certs []byte 456 if test.passCerts { 457 for _, cert := range ts.TLS.Certificates { 458 for _, c := range cert.Certificate { 459 parsedCert, err := x509.ParseCertificate(c) 460 require.NoError(t, err, "Failed to parse certificate") 461 certs = append(certs, pem.EncodeToMemory(&pem.Block{ 462 Type: "CERTIFICATE", 463 Bytes: parsedCert.Raw, 464 })...) 465 } 466 } 467 } 468 469 provider, err := NewBitbucketServerProviderBasicAuth(t.Context(), "user", "password", ts.URL, "PROJECT", true, "", test.tlsInsecure, certs) 470 require.NoError(t, err) 471 _, err = provider.ListRepos(t.Context(), "ssh") 472 if test.requireErr { 473 require.Error(t, err) 474 } else { 475 require.NoError(t, err) 476 } 477 }) 478 } 479 } 480 481 func TestListReposBasicAuth(t *testing.T) { 482 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 483 assert.Equal(t, "Basic dXNlcjpwYXNzd29yZA==", r.Header.Get("Authorization")) 484 assert.Equal(t, "no-check", r.Header.Get("X-Atlassian-Token")) 485 defaultHandler(t)(w, r) 486 })) 487 defer ts.Close() 488 provider, err := NewBitbucketServerProviderBasicAuth(t.Context(), "user", "password", ts.URL, "PROJECT", true, "", false, nil) 489 require.NoError(t, err) 490 repos, err := provider.ListRepos(t.Context(), "ssh") 491 verifyDefaultRepo(t, err, repos) 492 } 493 494 func TestListReposBearerAuth(t *testing.T) { 495 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 496 assert.Equal(t, "Bearer tolkien", r.Header.Get("Authorization")) 497 assert.Equal(t, "no-check", r.Header.Get("X-Atlassian-Token")) 498 defaultHandler(t)(w, r) 499 })) 500 defer ts.Close() 501 provider, err := NewBitbucketServerProviderBearerToken(t.Context(), "tolkien", ts.URL, "PROJECT", true, "", false, nil) 502 require.NoError(t, err) 503 repos, err := provider.ListRepos(t.Context(), "ssh") 504 verifyDefaultRepo(t, err, repos) 505 } 506 507 func TestListReposDefaultBranch(t *testing.T) { 508 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 509 assert.Empty(t, r.Header.Get("Authorization")) 510 if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { 511 _, err := io.WriteString(w, `{ 512 "id": "refs/heads/default", 513 "displayId": "default", 514 "type": "BRANCH", 515 "latestCommit": "1d51122def5632836d1cb1026e879069e10a1e13", 516 "latestChangeset": "1d51122def5632836d1cb1026e879069e10a1e13", 517 "isDefault": true 518 }`) 519 if err != nil { 520 t.Fail() 521 } 522 return 523 } 524 defaultHandler(t)(w, r) 525 })) 526 defer ts.Close() 527 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) 528 require.NoError(t, err) 529 repos, err := provider.ListRepos(t.Context(), "ssh") 530 require.NoError(t, err) 531 assert.Len(t, repos, 1) 532 assert.Equal(t, Repository{ 533 Organization: "PROJECT", 534 Repository: "REPO", 535 URL: "ssh://git@mycompany.bitbucket.org/PROJECT/REPO.git", 536 Branch: "default", 537 SHA: "1d51122def5632836d1cb1026e879069e10a1e13", 538 Labels: []string{}, 539 RepositoryId: 1, 540 }, *repos[0]) 541 } 542 543 func TestListReposMissingDefaultBranch(t *testing.T) { 544 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 545 assert.Empty(t, r.Header.Get("Authorization")) 546 if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { 547 http.Error(w, "Not found", http.StatusNotFound) 548 return 549 } 550 defaultHandler(t)(w, r) 551 })) 552 defer ts.Close() 553 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) 554 require.NoError(t, err) 555 repos, err := provider.ListRepos(t.Context(), "ssh") 556 require.NoError(t, err) 557 assert.Empty(t, repos) 558 } 559 560 func TestListReposErrorDefaultBranch(t *testing.T) { 561 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 562 assert.Empty(t, r.Header.Get("Authorization")) 563 if r.RequestURI == "/rest/api/1.0/projects/PROJECT/repos/REPO/branches/default" { 564 http.Error(w, "Internal server error", http.StatusInternalServerError) 565 return 566 } 567 defaultHandler(t)(w, r) 568 })) 569 defer ts.Close() 570 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", false, "", false, nil) 571 require.NoError(t, err) 572 _, err = provider.ListRepos(t.Context(), "ssh") 573 require.Error(t, err) 574 } 575 576 func TestListReposCloneProtocol(t *testing.T) { 577 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 578 assert.Empty(t, r.Header.Get("Authorization")) 579 defaultHandler(t)(w, r) 580 })) 581 defer ts.Close() 582 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil) 583 require.NoError(t, err) 584 repos, err := provider.ListRepos(t.Context(), "https") 585 require.NoError(t, err) 586 assert.Len(t, repos, 1) 587 assert.Equal(t, Repository{ 588 Organization: "PROJECT", 589 Repository: "REPO", 590 URL: "https://mycompany.bitbucket.org/scm/PROJECT/REPO.git", 591 Branch: "main", 592 SHA: "8d51122def5632836d1cb1026e879069e10a1e13", 593 Labels: []string{}, 594 RepositoryId: 1, 595 }, *repos[0]) 596 } 597 598 func TestListReposUnknownProtocol(t *testing.T) { 599 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 600 assert.Empty(t, r.Header.Get("Authorization")) 601 defaultHandler(t)(w, r) 602 })) 603 defer ts.Close() 604 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil) 605 require.NoError(t, err) 606 _, errProtocol := provider.ListRepos(t.Context(), "http") 607 require.Error(t, errProtocol) 608 } 609 610 func TestBitbucketServerHasPath(t *testing.T) { 611 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 612 var err error 613 switch r.RequestURI { 614 case "/rest/api/1.0/projects/PROJECT/repos/REPO/browse/pkg?at=main&limit=100&type=true": 615 _, err = io.WriteString(w, `{"type":"DIRECTORY"}`) 616 case "/rest/api/1.0/projects/PROJECT/repos/REPO/browse/pkg/?at=main&limit=100&type=true": 617 _, err = io.WriteString(w, `{"type":"DIRECTORY"}`) 618 case "/rest/api/1.0/projects/PROJECT/repos/REPO/browse/anotherpkg/file.txt?at=main&limit=100&type=true": 619 _, err = io.WriteString(w, `{"type":"FILE"}`) 620 621 case "/rest/api/1.0/projects/PROJECT/repos/REPO/browse/anotherpkg/missing.txt?at=main&limit=100&type=true": 622 http.Error(w, "The path \"anotherpkg/missing.txt\" does not exist at revision \"main\"", http.StatusNotFound) 623 case "/rest/api/1.0/projects/PROJECT/repos/REPO/browse/notathing?at=main&limit=100&type=true": 624 http.Error(w, "The path \"notathing\" does not exist at revision \"main\"", http.StatusNotFound) 625 626 case "/rest/api/1.0/projects/PROJECT/repos/REPO/browse/return-redirect?at=main&limit=100&type=true": 627 http.Redirect(w, r, "http://"+r.Host+"/rest/api/1.0/projects/PROJECT/repos/REPO/browse/redirected?at=main&limit=100&type=true", http.StatusMovedPermanently) 628 case "/rest/api/1.0/projects/PROJECT/repos/REPO/browse/redirected?at=main&limit=100&type=true": 629 _, err = io.WriteString(w, `{"type":"DIRECTORY"}`) 630 631 case "/rest/api/1.0/projects/PROJECT/repos/REPO/browse/unauthorized-response?at=main&limit=100&type=true": 632 http.Error(w, "Authentication failed", http.StatusUnauthorized) 633 634 default: 635 t.Fail() 636 } 637 if err != nil { 638 t.Fail() 639 } 640 })) 641 defer ts.Close() 642 provider, err := NewBitbucketServerProviderNoAuth(t.Context(), ts.URL, "PROJECT", true, "", false, nil) 643 require.NoError(t, err) 644 repo := &Repository{ 645 Organization: "PROJECT", 646 Repository: "REPO", 647 Branch: "main", 648 } 649 ok, err := provider.RepoHasPath(t.Context(), repo, "pkg") 650 require.NoError(t, err) 651 assert.True(t, ok) 652 653 ok, err = provider.RepoHasPath(t.Context(), repo, "pkg/") 654 require.NoError(t, err) 655 assert.True(t, ok) 656 657 ok, err = provider.RepoHasPath(t.Context(), repo, "anotherpkg/file.txt") 658 require.NoError(t, err) 659 assert.True(t, ok) 660 661 ok, err = provider.RepoHasPath(t.Context(), repo, "anotherpkg/missing.txt") 662 require.NoError(t, err) 663 assert.False(t, ok) 664 665 ok, err = provider.RepoHasPath(t.Context(), repo, "notathing") 666 require.NoError(t, err) 667 assert.False(t, ok) 668 669 ok, err = provider.RepoHasPath(t.Context(), repo, "return-redirect") 670 require.NoError(t, err) 671 assert.True(t, ok) 672 673 _, err = provider.RepoHasPath(t.Context(), repo, "unauthorized-response") 674 require.Error(t, err) 675 }