github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/checkmarxone/checkmarxone_test.go (about) 1 package checkmarxOne 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "io" 8 "net/http" 9 "strings" 10 "testing" 11 12 piperHttp "github.com/SAP/jenkins-library/pkg/http" 13 "github.com/SAP/jenkins-library/pkg/log" 14 "github.com/sirupsen/logrus" 15 "github.com/stretchr/testify/assert" 16 ) 17 18 type senderMock struct { 19 token string 20 httpMethod string 21 httpStatusCode int 22 urlCalled string 23 requestBody string 24 responseBody string 25 header http.Header 26 logger *logrus.Entry 27 errorExp bool 28 } 29 30 func (sm *senderMock) SendRequest(method, url string, body io.Reader, header http.Header, cookies []*http.Cookie) (*http.Response, error) { 31 if sm.errorExp { 32 return &http.Response{}, errors.New("Provoked technical error") 33 } 34 sm.httpMethod = method 35 sm.urlCalled = url 36 sm.header = header 37 if body != nil { 38 buf := new(bytes.Buffer) 39 buf.ReadFrom(body) 40 sm.requestBody = buf.String() 41 } 42 var httpError error 43 if sm.httpStatusCode > 399 { 44 httpError = fmt.Errorf("http error %v", sm.httpStatusCode) 45 } 46 return &http.Response{StatusCode: sm.httpStatusCode, Body: io.NopCloser(strings.NewReader(sm.responseBody))}, httpError 47 } 48 func (sm *senderMock) UploadFile(url, file, fieldName string, header http.Header, cookies []*http.Cookie, uploadType string) (*http.Response, error) { 49 sm.httpMethod = http.MethodPost 50 sm.urlCalled = url 51 sm.header = header 52 return &http.Response{StatusCode: sm.httpStatusCode, Body: io.NopCloser(bytes.NewReader([]byte(sm.responseBody)))}, nil 53 54 } 55 func (sm *senderMock) UploadRequest(method, url, file, fieldName string, header http.Header, cookies []*http.Cookie, uploadType string) (*http.Response, error) { 56 sm.httpMethod = http.MethodPost 57 sm.urlCalled = url 58 sm.header = header 59 return &http.Response{StatusCode: sm.httpStatusCode, Body: io.NopCloser(bytes.NewReader([]byte(sm.responseBody)))}, nil 60 } 61 func (sm *senderMock) Upload(_ piperHttp.UploadRequestData) (*http.Response, error) { 62 return &http.Response{}, fmt.Errorf("not implemented") 63 } 64 func (sm *senderMock) SetOptions(opts piperHttp.ClientOptions) { 65 sm.token = opts.Token 66 } 67 68 func TestSendRequest(t *testing.T) { 69 logger := log.Entry().WithField("package", "SAP/jenkins-library/pkg/checkmarxOne_test") 70 opts := piperHttp.ClientOptions{} 71 t.Run("test success", func(t *testing.T) { 72 myTestClient := senderMock{responseBody: `{"some": "test"}`, httpStatusCode: 200} 73 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 74 myTestClient.SetOptions(opts) 75 76 _, err := sendRequest(&sys, "GET", "/test", nil, nil, []int{}) 77 78 assert.NoError(t, err, "Error occurred but none expected") 79 assert.Equal(t, "https://cx1.server.com/api/test", myTestClient.urlCalled, "Called url incorrect") 80 }) 81 82 t.Run("test error", func(t *testing.T) { 83 myTestClient := senderMock{responseBody: `{"some": "test"}`, httpStatusCode: 400} 84 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 85 myTestClient.SetOptions(opts) 86 _, err := sendRequest(&sys, "GET", "/test", nil, nil, []int{}) 87 88 assert.Error(t, err, "Error expected but none occurred") 89 assert.Equal(t, "https://cx1.server.com/api/test", myTestClient.urlCalled, "Called url incorrect") 90 }) 91 92 t.Run("test technical error", func(t *testing.T) { 93 myTestClient := senderMock{responseBody: `{"some": "test"}`, httpStatusCode: 400} 94 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 95 myTestClient.SetOptions(opts) 96 _, err := sendRequest(&sys, "error", "/test", nil, nil, []int{}) 97 98 assert.Error(t, err, "Error expected but none occurred") 99 }) 100 } 101 102 func TestSendRequestInternal(t *testing.T) { 103 logger := log.Entry().WithField("package", "SAP/jenkins-library/pkg/checkmarxOne_test") 104 opts := piperHttp.ClientOptions{} 105 106 t.Run("test accepted error", func(t *testing.T) { 107 myTestClient := senderMock{responseBody: `{"some": "test"}`, httpStatusCode: 404} 108 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 109 myTestClient.SetOptions(opts) 110 _, err := sendRequestInternal(&sys, "GET", "/test", nil, nil, []int{404}) 111 112 assert.NoError(t, err, "No error expected but error occurred") 113 }) 114 } 115 116 func TestGetOAuthToken(t *testing.T) { 117 logger := log.Entry().WithField("package", "SAP/jenkins-library/pkg/checkmarxOne_test") 118 opts := piperHttp.ClientOptions{} 119 t.Run("test success", func(t *testing.T) { 120 myTestClient := senderMock{responseBody: `{"token_type":"Bearer","access_token":"abcd12345","expires_in":7045634}`, httpStatusCode: 200} 121 sys, _ := NewSystemInstance(&myTestClient, "https://cx1.server.com", "https://cx1iam.server.com", "tenant", "", "client", "secret") 122 myTestClient.SetOptions(opts) 123 124 token, err := sys.getOAuth2Token() 125 126 assert.NoError(t, err, "Error occurred but none expected") 127 assert.Equal(t, "https://cx1iam.server.com/auth/realms/tenant/protocol/openid-connect/token", myTestClient.urlCalled, "Called url incorrect") 128 assert.Equal(t, "Bearer abcd12345", token, "Token incorrect") 129 assert.Equal(t, "client_id=client&client_secret=secret&grant_type=client_credentials", myTestClient.requestBody, "Request body incorrect") 130 }) 131 132 t.Run("test authentication failure", func(t *testing.T) { 133 myTestClient := senderMock{responseBody: `{}`, httpStatusCode: 400} 134 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 135 myTestClient.SetOptions(opts) 136 137 _, err := sys.getOAuth2Token() 138 139 assert.Error(t, err, "Error expected but none occurred") 140 assert.Equal(t, "https://cx1iam.server.com/auth/realms/tenant/protocol/openid-connect/token", myTestClient.urlCalled, "Called url incorrect") 141 }) 142 143 t.Run("test new system", func(t *testing.T) { 144 myTestClient := senderMock{responseBody: `{"token_type":"Bearer","access_token":"abcd12345","expires_in":7045634}`, httpStatusCode: 200} 145 _, err := NewSystemInstance(&myTestClient, "https://cx1.server.com", "https://cx1iam.server.com", "tenant", "", "client", "secret") 146 147 assert.NoError(t, err, "Error occurred but none expected") 148 assert.Equal(t, "https://cx1iam.server.com/auth/realms/tenant/protocol/openid-connect/token", myTestClient.urlCalled, "Called url incorrect") 149 assert.Equal(t, "Bearer abcd12345", myTestClient.token, "Token incorrect") 150 }) 151 152 t.Run("test technical error", func(t *testing.T) { 153 myTestClient := senderMock{responseBody: `{}`, httpStatusCode: 400} 154 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 155 myTestClient.SetOptions(opts) 156 myTestClient.errorExp = true 157 158 _, err := sys.getOAuth2Token() 159 160 assert.Error(t, err, "Error expected but none occurred") 161 }) 162 } 163 164 func TestGetGroups(t *testing.T) { 165 logger := log.Entry().WithField("package", "SAP/jenkins-library/pkg/checkmarxOne_test") 166 opts := piperHttp.ClientOptions{} 167 t.Run("test success", func(t *testing.T) { 168 myTestClient := senderMock{responseBody: `[{"id":"be82031b-a75c-4fc0-894b-fff4deab2854","name":"Group1","path":"/Group1","subGroups":[]},{"id":"b368988c-b124-4151-b507-c8fcad501165","name":"Group2","path":"/Group2","subGroups":[]}]`, httpStatusCode: 200} 169 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 170 myTestClient.SetOptions(opts) 171 172 groups, err := sys.GetGroups() 173 assert.NoError(t, err, "Error occurred but none expected") 174 175 assert.Equal(t, "https://cx1iam.server.com/auth/realms/tenant/pip/groups", myTestClient.urlCalled, "Called url incorrect") 176 assert.Equal(t, 2, len(groups), "Number of Groups incorrect") 177 assert.Equal(t, "Group1", groups[0].Name, "Group name 1 incorrect") 178 assert.Equal(t, "Group2", groups[1].Name, "Group name 2 incorrect") 179 180 t.Run("test filter groups by name", func(t *testing.T) { 181 group2, _ := sys.GetGroupByName("Group2") 182 assert.Equal(t, "Group2", group2.Name, "Group name incorrect") 183 assert.Equal(t, "b368988c-b124-4151-b507-c8fcad501165", group2.GroupID, "Group id incorrect") 184 }) 185 186 t.Run("test Filter groups by ID", func(t *testing.T) { 187 group1, _ := sys.GetGroupByID("be82031b-a75c-4fc0-894b-fff4deab2854") 188 assert.Equal(t, "Group1", group1.Name, "Group name incorrect") 189 assert.Equal(t, "be82031b-a75c-4fc0-894b-fff4deab2854", group1.GroupID, "Group id incorrect") 190 }) 191 192 t.Run("test fail Filter groups by name", func(t *testing.T) { 193 group, err := sys.GetGroupByName("Group") 194 assert.Equal(t, "", group.Name, "Group name incorrect") 195 assert.Contains(t, fmt.Sprint(err), "No group matching") 196 }) 197 }) 198 199 t.Run("test technical error", func(t *testing.T) { 200 myTestClient := senderMock{responseBody: `[{"id":"1", "fullName":"Group1"}, {"id":"2", "fullName":"Group2"}, {"id":"3", "fullName":"Group3"}]`, httpStatusCode: 200} 201 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 202 myTestClient.SetOptions(opts) 203 myTestClient.errorExp = true 204 205 groups, _ := sys.GetGroups() 206 207 assert.Equal(t, 0, len(groups), "Error expected but none occurred") 208 }) 209 } 210 211 func TestGetScanMetadata(t *testing.T) { 212 logger := log.Entry().WithField("package", "SAP/jenkins-library/pkg/checkmarxOne_test") 213 opts := piperHttp.ClientOptions{} 214 t.Run("test success", func(t *testing.T) { 215 myTestClient := senderMock{responseBody: `{"scanId":"03d66397-36df-40b5-8976-f38bcce695a7","projectId":"eac4dc3b-4bbf-4d04-87e5-3b3cedae38fb","loc":158,"fileCount":39,"isIncremental":false,"isIncrementalCanceled":false,"queryPreset":"Checkmarx Default"}`, httpStatusCode: 200} 216 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 217 myTestClient.SetOptions(opts) 218 219 scanmeta, err := sys.GetScanMetadata("03d66397-36df-40b5-8976-f38bcce695a7") 220 assert.NoError(t, err, "Error occurred but none expected") 221 222 assert.Equal(t, "03d66397-36df-40b5-8976-f38bcce695a7", scanmeta.ScanID, "ScanID is incorrect") 223 assert.Equal(t, "eac4dc3b-4bbf-4d04-87e5-3b3cedae38fb", scanmeta.ProjectID, "ProjectID is incorrect") 224 assert.Equal(t, 158, scanmeta.LOC, "LOC is incorrect") 225 assert.Equal(t, 39, scanmeta.FileCount, "FileCount is incorrect") 226 assert.Equal(t, false, scanmeta.IsIncremental, "IsIncremental is incorrect") 227 assert.Equal(t, false, scanmeta.IsIncrementalCanceled, "IsIncrementalCanceled is incorrect") 228 assert.Equal(t, "Checkmarx Default", scanmeta.PresetName, "PresetName is incorrect") 229 }) 230 231 t.Run("test technical error", func(t *testing.T) { 232 myTestClient := senderMock{httpStatusCode: 200} 233 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 234 myTestClient.SetOptions(opts) 235 myTestClient.errorExp = true 236 237 _, err := sys.GetScanMetadata("03d66397-36df-40b5-8976-f38bcce695a7") 238 assert.Contains(t, fmt.Sprint(err), "Provoked technical error") 239 }) 240 } 241 242 func TestGetScan(t *testing.T) { 243 logger := log.Entry().WithField("package", "SAP/jenkins-library/pkg/checkmarxOne_test") 244 opts := piperHttp.ClientOptions{} 245 t.Run("test success", func(t *testing.T) { 246 myTestClient := senderMock{responseBody: `{"id":"7343f9f5-7633-40d5-b000-0a7a3c2c432e","status":"Completed","statusDetails":[{"name":"general","status":"Completed","details":""},{"name":"sast","status":"Completed","details":"","loc":2148}],"branch":"master","createdAt":"2023-03-31T08:35:56.412514Z","updatedAt":"2023-03-31T08:36:53.526569Z","projectId":"e7a7704c-4bfe-4054-9137-d32c156ca641","projectName":"fullScanCycle","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0","initiator":"user@sap.com","tags":{},"metadata":{"id":"7343f9f5-7633-40d5-b000-0a7a3c2c432e","type":"upload","Handler":{"UploadHandler":{"branch":"master","upload_url":"https://cx1.server.com/storage/st-gcp-9k90xv-uploads/b68ee5ba-3657-424f-9b68-05452300d5d7/271b80e3-b0d4-4be6-9f66-9469126b624f?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Credential=ast%2F20230331%2Fus-east-1%2Fs3%2Faws4_request\u0026X-Amz-Date=20230331T083556Z\u0026X-Amz-Expires=86400\u0026X-Amz-Signature=94d74276d93945c37243f7ccec3d1e30b15d4d6ec79a869d3d9e46622fd89acd\u0026X-Amz-SignedHeaders=host"}},"configs":[{"type":"sast","value":{"presetName":"Checkmarx Default","incremental":"true","languageMode":"primary"}}],"project":{"id":"e7a7704c-4bfe-4054-9137-d32c156ca641"},"created_at":{"nanos":387074846,"seconds":1680251756}},"engines":["sast"],"sourceType":"zip","sourceOrigin":"Mozilla"}`, httpStatusCode: 200} 247 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 248 myTestClient.SetOptions(opts) 249 250 scan, err := sys.GetScan("7343f9f5-7633-40d5-b000-0a7a3c2c432e") 251 assert.NoError(t, err, "Error occurred but none expected") 252 assert.Equal(t, "7343f9f5-7633-40d5-b000-0a7a3c2c432e", scan.ScanID, "ScanID is incorrect") 253 assert.Equal(t, "master", scan.Branch, "Branch is incorrect") 254 assert.Equal(t, 2, len(scan.StatusDetails), "StatusDetails is incorrect") 255 }) 256 257 t.Run("test technical error", func(t *testing.T) { 258 myTestClient := senderMock{httpStatusCode: 200} 259 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 260 myTestClient.SetOptions(opts) 261 myTestClient.errorExp = true 262 263 _, err := sys.GetScan("7343f9f5-7633-40d5-b000-0a7a3c2c432e") 264 assert.Contains(t, fmt.Sprint(err), "Provoked technical error") 265 }) 266 } 267 268 func TestGetApplicationByName(t *testing.T) { 269 logger := log.Entry().WithField("package", "SAP/jenkins-library/pkg/checkmarxOne_test") 270 opts := piperHttp.ClientOptions{} 271 t.Run("test success", func(t *testing.T) { 272 myTestClient := senderMock{responseBody: `{"totalCount":6,"filteredTotalCount":6,"applications":[{"id":"8cf83fcf-ac61-4e32-b988-47cde3cc818c","name":"test_dev2","description":"","criticality":3,"rules":[],"projectIds":[],"tags":{},"createdAt":"2023-04-06T13:57:00.082719Z","updatedAt":"2023-04-06T13:57:00.082719Z"},{"id":"dee8573b-c58e-4945-a97c-a66884380093","name":"test_dev1","description":"","criticality":3,"rules":[],"projectIds":[],"tags":{},"createdAt":"2023-04-06T13:44:32.212065Z","updatedAt":"2023-04-06T13:44:32.212065Z"},{"id":"0ff00c77-b7e6-4d27-bd88-9e14520e06e6","name":"test_dev","description":"","criticality":3,"rules":[],"projectIds":[],"tags":{},"createdAt":"2023-04-06T13:24:36.459375Z","updatedAt":"2023-04-06T13:24:36.459375Z"},{"id":"5d482cfc-27ae-43e1-ba45-68d557df8423","name":"SSBA","description":"","criticality":3,"rules":[{"id":"e00a5b13-93d0-4128-8c32-9d6a46db85b0","type":"project.name.in","value":"ssba-zip;ssba-git;cx_cli_ssba_test"}],"projectIds":["2d75e828-6db9-4cfa-87e7-b953ad59ea25","f00a9d02-b552-4461-835a-c701e30957d8","f61cf5f0-fa91-4563-b87b-8154a4fd2408"],"tags":{},"createdAt":"2023-03-15T13:44:31.831175Z","updatedAt":"2023-03-15T13:44:31.831175Z"},{"id":"68f2f996-e7eb-495e-8829-8996241eb84e","name":"test_1","description":"","criticality":3,"rules":[{"id":"3a08b06e-a76a-4a48-bcde-1b43b9890f31","type":"project.name.in","value":"OAuth-CLI-test;test-piper-1;cx_cli_ssba_test"}],"projectIds":["2d75e828-6db9-4cfa-87e7-b953ad59ea25","db82605a-26e4-4693-a59c-ec1d584840d0","31c44a7c-0c68-492a-9921-052d336e5d5a"],"tags":{"TEST_APP":""},"createdAt":"2023-02-20T13:12:02.927562Z","updatedAt":"2023-02-20T13:12:02.927562Z"},{"id":"095dced0-60b0-4dd6-b1e8-0063fa04eaa7","name":"TEST","description":"","criticality":3,"rules":[{"id":"fc02a324-0706-4522-a89f-e24bcbf76cf7","type":"project.tag.key.exists","value":"test"}],"projectIds":["db82605a-26e4-4693-a59c-ec1d584840d0"],"tags":{"TEST_APP":""},"createdAt":"2023-01-12T13:22:38.222789Z","updatedAt":"2023-01-12T13:22:38.222789Z"}]}`, httpStatusCode: 200} 273 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 274 myTestClient.SetOptions(opts) 275 276 apps, err := sys.GetApplicationsByName("test", 10) 277 assert.NoError(t, err, "Error occurred but none expected") 278 assert.Equal(t, 6, len(apps), "TotalCount is incorrect") 279 280 app1, _ := sys.GetApplicationByName("test_dev2") 281 assert.Equal(t, "8cf83fcf-ac61-4e32-b988-47cde3cc818c", app1.ApplicationID, "ApplicationID is incorrect") 282 283 _, err = sys.GetApplicationByName("ssba") 284 assert.Contains(t, fmt.Sprint(err), "no application found named ssba") 285 }) 286 287 t.Run("test technical error", func(t *testing.T) { 288 myTestClient := senderMock{httpStatusCode: 200} 289 sys := SystemInstance{serverURL: "https://cx1.server.com", iamURL: "https://cx1iam.server.com", tenant: "tenant", client: &myTestClient, logger: logger} 290 myTestClient.SetOptions(opts) 291 myTestClient.errorExp = true 292 293 _, err := sys.GetApplicationsByName("test", 10) 294 assert.Contains(t, fmt.Sprint(err), "Provoked technical error") 295 }) 296 }