You've already forked sap-jenkins-library
							
							
				mirror of
				https://github.com/SAP/jenkins-library.git
				synced 2025-10-30 23:57:50 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			633 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			633 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package blackduck
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"io/ioutil"
 | |
| 	"net/http"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http"
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| )
 | |
| 
 | |
| type httpMockClient struct {
 | |
| 	responseBodyForURL map[string]string
 | |
| 	errorMessageForURL map[string]string
 | |
| 	header             map[string]http.Header
 | |
| }
 | |
| 
 | |
| func (c *httpMockClient) SetOptions(opts piperhttp.ClientOptions) {}
 | |
| func (c *httpMockClient) SendRequest(method, url string, body io.Reader, header http.Header, cookies []*http.Cookie) (*http.Response, error) {
 | |
| 	c.header[url] = header
 | |
| 	response := http.Response{
 | |
| 		StatusCode: 200,
 | |
| 		Body:       ioutil.NopCloser(bytes.NewReader([]byte(""))),
 | |
| 	}
 | |
| 
 | |
| 	if c.errorMessageForURL[url] != "" {
 | |
| 		response.StatusCode = 400
 | |
| 		return &response, fmt.Errorf(c.errorMessageForURL[url])
 | |
| 	}
 | |
| 
 | |
| 	if c.responseBodyForURL[url] != "" {
 | |
| 		response.Body = ioutil.NopCloser(bytes.NewReader([]byte(c.responseBodyForURL[url])))
 | |
| 		return &response, nil
 | |
| 	}
 | |
| 
 | |
| 	return &response, nil
 | |
| }
 | |
| 
 | |
| const (
 | |
| 	authContent = `{
 | |
| 		"bearerToken":"bearerTestToken",
 | |
| 		"expiresInMilliseconds":7199997
 | |
| 	}`
 | |
| 	projectContent = `{
 | |
| 		"totalCount": 1,
 | |
| 		"items": [
 | |
| 			{
 | |
| 				"name": "SHC-PiperTest",
 | |
| 				"_meta": {
 | |
| 					"href": "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf",
 | |
| 					"links": [
 | |
| 						{
 | |
| 							"rel": "versions",
 | |
| 							"href": "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions"
 | |
| 						}
 | |
| 					]
 | |
| 				}
 | |
| 			}
 | |
| 		]
 | |
| 	}`
 | |
| 	projectVersionContent = `{
 | |
| 		"totalCount": 1,
 | |
| 		"items": [
 | |
| 			{
 | |
| 				"versionName": "1.0",
 | |
| 				"_meta": {
 | |
| 					"href": "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36",
 | |
| 					"links": [
 | |
| 						{
 | |
| 							"rel": "components",
 | |
| 							"href": "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/components"
 | |
| 						},
 | |
| 						{
 | |
| 							"rel": "vulnerable-components",
 | |
| 							"href": "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/vunlerable-bom-components"
 | |
| 						},
 | |
| 						{
 | |
| 							"rel": "policy-status",
 | |
| 							"href": "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/policy-status"
 | |
| 						}
 | |
| 					]
 | |
| 				}
 | |
| 			}
 | |
| 		]
 | |
| 	}`
 | |
| )
 | |
| 
 | |
| func TestGetProject(t *testing.T) {
 | |
| 	t.Run("success", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":             authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest": projectContent,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 		project, err := bdClient.GetProject("SHC-PiperTest")
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.Equal(t, "SHC-PiperTest", project.Name)
 | |
| 		assert.Equal(t, "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions", project.Metadata.Links[0].Href)
 | |
| 		headerExpected := http.Header{"Authorization": []string{"Bearer bearerTestToken"}, "Accept": {"application/vnd.blackducksoftware.project-detail-4+json"}}
 | |
| 		assert.Equal(t, headerExpected, myTestClient.header["https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest"])
 | |
| 	})
 | |
| 
 | |
| 	t.Run("failure - not found", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate": authContent,
 | |
| 			},
 | |
| 			errorMessageForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest": "not found",
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 		_, err := bdClient.GetProject("SHC-PiperTest")
 | |
| 		assert.Contains(t, fmt.Sprint(err), "failed to get project 'SHC-PiperTest'")
 | |
| 	})
 | |
| 
 | |
| 	t.Run("failure - 0 results", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate": authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest": `{
 | |
| 					"totalCount": 0,
 | |
| 					"items": []
 | |
| 				}`,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 		_, err := bdClient.GetProject("SHC-PiperTest")
 | |
| 		assert.Contains(t, fmt.Sprint(err), "project 'SHC-PiperTest' not found")
 | |
| 	})
 | |
| 
 | |
| 	t.Run("failure - unmarshalling", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":             authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest": "",
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 		_, err := bdClient.GetProject("SHC-PiperTest")
 | |
| 		assert.Contains(t, fmt.Sprint(err), "failed to retrieve details for project 'SHC-PiperTest'")
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestGetProjectVersion(t *testing.T) {
 | |
| 	t.Run("success", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                       authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                           projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0": projectVersionContent,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 		projectVersion, err := bdClient.GetProjectVersion("SHC-PiperTest", "1.0")
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.Equal(t, "1.0", projectVersion.Name)
 | |
| 		assert.Equal(t, "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36", projectVersion.Metadata.Href)
 | |
| 		headerExpected := http.Header{"Authorization": []string{"Bearer bearerTestToken"}, "Accept": {"application/vnd.blackducksoftware.project-detail-4+json"}}
 | |
| 		assert.Equal(t, headerExpected, myTestClient.header["https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0"])
 | |
| 	})
 | |
| 
 | |
| 	t.Run("failure - project not found", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate": authContent,
 | |
| 			},
 | |
| 			errorMessageForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest": "not found",
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 		_, err := bdClient.GetProjectVersion("SHC-PiperTest", "1.0")
 | |
| 		assert.Contains(t, fmt.Sprint(err), "failed to get project 'SHC-PiperTest'")
 | |
| 	})
 | |
| 
 | |
| 	t.Run("failure - version not found", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":             authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest": projectContent,
 | |
| 			},
 | |
| 			errorMessageForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0": "not found",
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 		_, err := bdClient.GetProjectVersion("SHC-PiperTest", "1.0")
 | |
| 		assert.Contains(t, fmt.Sprint(err), "failed to get project version 'SHC-PiperTest:1.0'")
 | |
| 	})
 | |
| 
 | |
| 	t.Run("failure - 0 results", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":             authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest": projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0": `{
 | |
| 					"totalCount": 0,
 | |
| 					"items": []
 | |
| 				}`,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 		_, err := bdClient.GetProjectVersion("SHC-PiperTest", "1.0")
 | |
| 		assert.Contains(t, fmt.Sprint(err), "project version 'SHC-PiperTest:1.0' not found")
 | |
| 	})
 | |
| 
 | |
| 	t.Run("failure - unmarshalling", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                       authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                           projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0": "",
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 		_, err := bdClient.GetProjectVersion("SHC-PiperTest", "1.0")
 | |
| 		assert.Contains(t, fmt.Sprint(err), "failed to retrieve details for project version 'SHC-PiperTest:1.0'")
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestGetVulnerabilities(t *testing.T) {
 | |
| 	t.Run("success", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                       authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                           projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0": projectVersionContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/vunlerable-bom-components?limit=999&offset=0": `{
 | |
| 					"totalCount": 1,
 | |
| 					"items": [
 | |
| 						{
 | |
| 							"componentName": "Spring Framework",
 | |
| 							"componentVersionName": "5.3.2",
 | |
| 							"vulnerabilityWithRemediation" : {
 | |
| 								"vulnerabilityName" : "BDSA-2019-2021",
 | |
| 								"baseScore" : 1.0,
 | |
|       							"overallScore" : 1.0,
 | |
| 								"severity" : "HIGH",
 | |
| 								"remediationStatus" : "IGNORED",
 | |
| 								"description" : "description"
 | |
| 							}
 | |
| 						}
 | |
| 					]
 | |
| 				}`,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("token", "https://my.blackduck.system", &myTestClient)
 | |
| 		vulns, err := bdClient.GetVulnerabilities("SHC-PiperTest", "1.0")
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.GreaterOrEqual(t, vulns.TotalCount, 1)
 | |
| 	})
 | |
| 
 | |
| 	t.Run("Success - 0 vulns", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                                                                                      authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                                                                                          projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0":                                                                projectVersionContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/vunlerable-bom-components?limit=999&offset=0": `{"totalCount":0,"items":[]}`,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("token", "https://my.blackduck.system", &myTestClient)
 | |
| 		vulns, err := bdClient.GetVulnerabilities("SHC-PiperTest", "1.0")
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.Equal(t, vulns.TotalCount, 0)
 | |
| 	})
 | |
| 
 | |
| 	t.Run("Failure - unmarshalling", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                                                                                      authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                                                                                          projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0":                                                                projectVersionContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/vunlerable-bom-components?limit=999&offset=0": "",
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("token", "https://my.blackduck.system", &myTestClient)
 | |
| 		_, err := bdClient.GetVulnerabilities("SHC-PiperTest", "1.0")
 | |
| 		assert.Contains(t, fmt.Sprint(err), "failed to retrieve Vulnerability details for project version 'SHC-PiperTest:1.0'")
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestGetComponents(t *testing.T) {
 | |
| 	t.Run("success", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                       authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                           projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0": projectVersionContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/components?limit=999&offset=0": `{
 | |
| 					"totalCount": 2,
 | |
| 					"items" : [
 | |
| 						{
 | |
| 							"componentName": "Spring Framework",
 | |
| 							"componentVersionName": "5.3.9"
 | |
| 						}, {
 | |
| 							"componentName": "Apache Tomcat",
 | |
| 							"componentVersionName": "9.0.52"
 | |
| 						}
 | |
| 					]
 | |
| 				}`,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("token", "https://my.blackduck.system", &myTestClient)
 | |
| 		components, err := bdClient.GetComponents("SHC-PiperTest", "1.0")
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.GreaterOrEqual(t, components.TotalCount, 2)
 | |
| 	})
 | |
| 
 | |
| 	t.Run("Failure - 0 components", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                       authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                           projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0": projectVersionContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/components?limit=999&offset=0": `{
 | |
| 					"totalCount": 0,
 | |
| 					"items" : []}`,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("token", "https://my.blackduck.system", &myTestClient)
 | |
| 		components, err := bdClient.GetComponents("SHC-PiperTest", "1.0")
 | |
| 		assert.Contains(t, fmt.Sprint(err), "No Components found for project version 'SHC-PiperTest:1.0'")
 | |
| 		assert.Nilf(t, components, "Expected Components to be nil")
 | |
| 	})
 | |
| 
 | |
| 	t.Run("Failure - unmarshalling", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                                                                       authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                                                                           projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0":                                                 projectVersionContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/components?limit=999&offset=0": "",
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("token", "https://my.blackduck.system", &myTestClient)
 | |
| 		components, err := bdClient.GetComponents("SHC-PiperTest", "1.0")
 | |
| 		assert.Contains(t, fmt.Sprint(err), "failed to retrieve component details for project version 'SHC-PiperTest:1.0'")
 | |
| 		assert.Nilf(t, components, "Expected Components to be nil")
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestGetComponentsWithLicensePolicyRule(t *testing.T) {
 | |
| 	t.Run("success", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                       authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                           projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0": projectVersionContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/components?filter=policyCategory%3Alicense&limit=999&offset=0": `{
 | |
| 					"totalCount": 2,
 | |
| 					"items" : [
 | |
| 						{
 | |
| 							"componentName": "Spring Framework",
 | |
| 							"componentVersionName": "5.3.9",
 | |
| 							"policyStatus": "IN_VIOLATION"
 | |
| 						}, {
 | |
| 							"componentName": "Apache Tomcat",
 | |
| 							"componentVersionName": "9.0.52",
 | |
| 							"policyStatus": "NOT_IN_VIOLATION"
 | |
| 						}
 | |
| 					]
 | |
| 				}`,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("token", "https://my.blackduck.system", &myTestClient)
 | |
| 		components, err := bdClient.GetComponentsWithLicensePolicyRule("SHC-PiperTest", "1.0")
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.GreaterOrEqual(t, components.TotalCount, 2)
 | |
| 		assert.Equal(t, components.Items[0].PolicyStatus, "IN_VIOLATION")
 | |
| 	})
 | |
| 
 | |
| 	t.Run("Failure - 0 components", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                       authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                           projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0": projectVersionContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/components?filter=policyCategory%3Alicense&limit=999&offset=0": `{
 | |
| 					"totalCount": 0,
 | |
| 					"items" : []}`,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("token", "https://my.blackduck.system", &myTestClient)
 | |
| 		components, err := bdClient.GetComponentsWithLicensePolicyRule("SHC-PiperTest", "1.0")
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.NotNil(t, components)
 | |
| 		assert.Equal(t, components.TotalCount, 0)
 | |
| 	})
 | |
| 
 | |
| 	t.Run("Failure - unmarshalling", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                       authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                           projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0": projectVersionContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/components?filter=policyCategory%3Alicense&limit=999&offset=0": "",
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("token", "https://my.blackduck.system", &myTestClient)
 | |
| 		components, err := bdClient.GetComponentsWithLicensePolicyRule("SHC-PiperTest", "1.0")
 | |
| 		assert.Contains(t, fmt.Sprint(err), "failed to retrieve component details for project version 'SHC-PiperTest:1.0'")
 | |
| 		assert.Nilf(t, components, "Expected Components to be nil")
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestGetPolicyStatus(t *testing.T) {
 | |
| 	t.Run("success", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                       authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                           projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0": projectVersionContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/policy-status": `{
 | |
| 					"overallStatus": "IN_VIOLATION",
 | |
| 					"componentVersionPolicyViolationDetails": {
 | |
| 						"name": "IN_VIOLATION",
 | |
| 						"severityLevels": [
 | |
| 						  {	"name": "BLOCKER", "value": 16 },
 | |
| 						  { "name": "CRITICAL", "value": 1 },
 | |
| 						  { "name": "MAJOR", "value": 0 },
 | |
| 						  { "name": "MINOR", "value": 0 },
 | |
| 						  { "name": "TRIVIAL", "value": 0 },
 | |
| 						  { "name": "UNSPECIFIED", "value": 0 },
 | |
| 						  { "name": "OK", "value": 0}
 | |
| 						]
 | |
| 					  }
 | |
| 				}`,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("token", "https://my.blackduck.system", &myTestClient)
 | |
| 		policyStatus, err := bdClient.GetPolicyStatus("SHC-PiperTest", "1.0")
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.Equal(t, policyStatus.OverallStatus, "IN_VIOLATION")
 | |
| 		assert.Equal(t, len(policyStatus.PolicyVersionDetails.SeverityLevels), 7)
 | |
| 		assert.Equal(t, policyStatus.PolicyVersionDetails.Name, "IN_VIOLATION")
 | |
| 	})
 | |
| 
 | |
| 	t.Run("Failure - unmarshalling", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                                                       authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                                                           projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0":                                 projectVersionContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36/policy-status": "",
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("token", "https://my.blackduck.system", &myTestClient)
 | |
| 		policyStatus, err := bdClient.GetPolicyStatus("SHC-PiperTest", "1.0")
 | |
| 		assert.Contains(t, fmt.Sprint(err), "failed to retrieve Policy violation details for project version 'SHC-PiperTest:1.0'")
 | |
| 		assert.Nilf(t, policyStatus, "Expected Components to be nil")
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestGetProjectVersionLink(t *testing.T) {
 | |
| 	t.Run("Success Case", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate":                                                       authContent,
 | |
| 				"https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest":                                           projectContent,
 | |
| 				"https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions?limit=100&offset=0": projectVersionContent,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("token", "https://my.blackduck.system", &myTestClient)
 | |
| 		link, err := bdClient.GetProjectVersionLink("SHC-PiperTest", "1.0")
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.Equal(t, link, "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36")
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestAuthenticate(t *testing.T) {
 | |
| 	t.Run("success", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate": authContent,
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 		err := bdClient.authenticate()
 | |
| 		assert.NoError(t, err)
 | |
| 		headerExpected := http.Header{"Authorization": {"token myTestToken"}, "Accept": {"application/vnd.blackducksoftware.user-4+json"}}
 | |
| 		assert.Equal(t, headerExpected, myTestClient.header["https://my.blackduck.system/api/tokens/authenticate"])
 | |
| 	})
 | |
| 
 | |
| 	t.Run("authentication failure", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			errorMessageForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate": "not authorized",
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 		err := bdClient.authenticate()
 | |
| 		assert.EqualError(t, err, "authentication to BlackDuck API failed: request to BlackDuck API failed: not authorized")
 | |
| 	})
 | |
| 
 | |
| 	t.Run("parse failure", func(t *testing.T) {
 | |
| 		myTestClient := httpMockClient{
 | |
| 			responseBodyForURL: map[string]string{
 | |
| 				"https://my.blackduck.system/api/tokens/authenticate": "",
 | |
| 			},
 | |
| 			header: map[string]http.Header{},
 | |
| 		}
 | |
| 		bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 		err := bdClient.authenticate()
 | |
| 		assert.Contains(t, fmt.Sprint(err), "failed to parse BlackDuck response")
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestSendRequest(t *testing.T) {
 | |
| 	myTestClient := httpMockClient{
 | |
| 		responseBodyForURL: map[string]string{
 | |
| 			"https://my.blackduck.system/api/endpoint":        "testContent",
 | |
| 			"https://my.blackduck.system/api/endpoint?q=test": "testContentQuery",
 | |
| 		},
 | |
| 		header: map[string]http.Header{},
 | |
| 	}
 | |
| 	bdClient := NewClient("myTestToken", "https://my.blackduck.system", &myTestClient)
 | |
| 
 | |
| 	t.Run("simple", func(t *testing.T) {
 | |
| 		responseBody, err := bdClient.sendRequest(http.MethodGet, "api/endpoint", map[string]string{}, nil, http.Header{})
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.Equal(t, "testContent", string(responseBody))
 | |
| 	})
 | |
| 
 | |
| 	t.Run("with query params and bearer", func(t *testing.T) {
 | |
| 		bdClient.BearerToken = "testBearer"
 | |
| 		responseBody, err := bdClient.sendRequest(http.MethodGet, "api/endpoint", map[string]string{"q": "test"}, nil, http.Header{})
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.Equal(t, "testContentQuery", string(responseBody))
 | |
| 		assert.Equal(t, http.Header{"Authorization": {"Bearer testBearer"}}, myTestClient.header["https://my.blackduck.system/api/endpoint?q=test"])
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestApiURL(t *testing.T) {
 | |
| 	tt := []struct {
 | |
| 		description string
 | |
| 		apiEndpoint string
 | |
| 		client      Client
 | |
| 		expected    string
 | |
| 	}{
 | |
| 		{
 | |
| 			description: "trailing / in path",
 | |
| 			apiEndpoint: "/my/path/",
 | |
| 			client:      Client{serverURL: "https://my.test.server"},
 | |
| 			expected:    "https://my.test.server/my/path",
 | |
| 		},
 | |
| 		{
 | |
| 			description: "trailing / in server",
 | |
| 			apiEndpoint: "/my/path",
 | |
| 			client:      Client{serverURL: "https://my.test.server/"},
 | |
| 			expected:    "https://my.test.server/my/path",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, test := range tt {
 | |
| 		res, err := test.client.apiURL(test.apiEndpoint)
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.Equalf(t, test.expected, res.String(), test.description)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestAuthenticationValid(t *testing.T) {
 | |
| 	tt := []struct {
 | |
| 		description string
 | |
| 		now         time.Time
 | |
| 		client      Client
 | |
| 		expected    bool
 | |
| 	}{
 | |
| 		{
 | |
| 			description: "login still valid",
 | |
| 			now:         time.Date(2020, time.January, 1, 12, 0, 0, 0, time.UTC),
 | |
| 			client:      Client{BearerExpiresInMilliseconds: 120000, lastAuthentication: time.Date(2020, time.January, 01, 11, 59, 0, 0, time.UTC)},
 | |
| 			expected:    true,
 | |
| 		},
 | |
| 		{
 | |
| 			description: "login still valid - edge",
 | |
| 			now:         time.Date(2020, time.January, 1, 12, 0, 0, 0, time.UTC),
 | |
| 			client:      Client{BearerExpiresInMilliseconds: 120000, lastAuthentication: time.Date(2020, time.January, 01, 11, 58, 1, 0, time.UTC)},
 | |
| 			expected:    true,
 | |
| 		},
 | |
| 		{
 | |
| 			description: "login expired",
 | |
| 			now:         time.Date(2020, time.January, 1, 12, 0, 0, 0, time.UTC),
 | |
| 			client:      Client{BearerExpiresInMilliseconds: 120000, lastAuthentication: time.Date(2020, time.January, 01, 11, 57, 0, 0, time.UTC)},
 | |
| 			expected:    false,
 | |
| 		},
 | |
| 		{
 | |
| 			description: "login expired - edge",
 | |
| 			now:         time.Date(2020, time.January, 1, 12, 0, 0, 0, time.UTC),
 | |
| 			client:      Client{BearerExpiresInMilliseconds: 120000, lastAuthentication: time.Date(2020, time.January, 01, 11, 58, 0, 0, time.UTC)},
 | |
| 			expected:    false,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, test := range tt {
 | |
| 		assert.Equalf(t, test.expected, test.client.authenticationValid(test.now), test.description)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestUrlPath(t *testing.T) {
 | |
| 	assert.Equal(t, "/this/is/the/path", urlPath("https://the.server.domain:8080/this/is/the/path"))
 | |
| }
 |