github.com/google/osv-scalibr@v0.4.1/veles/secrets/gitbasicauth/codecatalyst/validator_test.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package codecatalyst_test 16 17 import ( 18 "context" 19 "net/http" 20 "net/http/httptest" 21 "net/url" 22 "strings" 23 "testing" 24 25 "github.com/google/go-cmp/cmp" 26 "github.com/google/go-cmp/cmp/cmpopts" 27 "github.com/google/osv-scalibr/veles" 28 "github.com/google/osv-scalibr/veles/secrets/gitbasicauth/codecatalyst" 29 ) 30 31 var ( 32 validatorTestURL = "https://user:pat@git.region.codecatalyst.aws/v1/space/project/repo" 33 validatorTestBadCredsURL = "https://user:bad_pat@git.region.codecatalyst.aws/v1/space/project/repo" 34 validatorTestBadRepoURL = "https://user:pat@git.region.codecatalyst.aws/v1/space/project/bad-repo" 35 ) 36 37 type redirectTransport struct { 38 url string 39 } 40 41 func (t *redirectTransport) RoundTrip(req *http.Request) (*http.Response, error) { 42 if strings.HasSuffix(req.URL.Host, ".codecatalyst.aws") { 43 newURL, err := url.Parse(t.url) 44 if err != nil { 45 return nil, err 46 } 47 req.URL.Scheme = newURL.Scheme 48 req.URL.Host = newURL.Host 49 } 50 return http.DefaultTransport.RoundTrip(req) 51 } 52 53 func mockCodeCatalystHandler(t *testing.T, status int) http.HandlerFunc { 54 t.Helper() 55 return func(w http.ResponseWriter, r *http.Request) { 56 if r.Method != http.MethodGet { 57 t.Errorf("r.Method = %s, want %s", r.Method, http.MethodGet) 58 } 59 auth := r.Header.Get("Authorization") 60 if !strings.HasPrefix(auth, "Basic") { 61 t.Errorf("should use basic auth") 62 } 63 if status == 200 { 64 w.WriteHeader(status) 65 return 66 } 67 w.WriteHeader(status) 68 _, _ = w.Write([]byte(`<InvalidRequestException> 69 <Message>The resource either does not exist, or you don’t have permission to access it.</Message> 70 </InvalidRequestException>`)) 71 } 72 } 73 74 func TestValidator(t *testing.T) { 75 cancelledContext, cancel := context.WithCancel(t.Context()) 76 cancel() 77 78 cases := []struct { 79 //nolint:containedctx 80 ctx context.Context 81 name string 82 url string 83 httpStatus int 84 want veles.ValidationStatus 85 wantErr error 86 }{ 87 { 88 name: "cancelled_context", 89 url: validatorTestURL, 90 want: veles.ValidationFailed, 91 ctx: cancelledContext, 92 httpStatus: http.StatusOK, 93 wantErr: cmpopts.AnyError, 94 }, 95 { 96 name: "valid_credentials", 97 url: validatorTestURL, 98 httpStatus: http.StatusOK, 99 want: veles.ValidationValid, 100 }, 101 { 102 name: "invalid_creds", 103 url: validatorTestBadCredsURL, 104 httpStatus: http.StatusBadRequest, 105 want: veles.ValidationInvalid, 106 }, 107 { 108 name: "bad_repository", 109 url: validatorTestBadRepoURL, 110 httpStatus: http.StatusBadRequest, 111 want: veles.ValidationInvalid, 112 }, 113 } 114 115 for _, tt := range cases { 116 t.Run(tt.name, func(t *testing.T) { 117 if tt.ctx == nil { 118 tt.ctx = t.Context() 119 } 120 server := httptest.NewServer(mockCodeCatalystHandler(t, tt.httpStatus)) 121 defer server.Close() 122 123 client := &http.Client{ 124 Transport: &redirectTransport{ 125 url: server.URL, 126 }, 127 } 128 129 v := codecatalyst.NewValidator() 130 v.HTTPC = client 131 132 got, err := v.Validate(tt.ctx, codecatalyst.Credentials{FullURL: tt.url}) 133 134 if !cmp.Equal(tt.wantErr, err, cmpopts.EquateErrors()) { 135 t.Fatalf("Validate() error: %v, want %v", err, tt.wantErr) 136 } 137 138 if diff := cmp.Diff(tt.want, got); diff != "" { 139 t.Errorf("v.Validate() returned diff (-want +got):\n%s", diff) 140 } 141 }) 142 } 143 }