1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-14 11:03:09 +02:00
sap-jenkins-library/pkg/fortify/fortify_test.go
Sven Merk f149292374
[fix]fortifyExecuteScan: disable fulltextsearch (#2527)
* FF disable fulltextsearch

# Conflicts:
#	pkg/fortify/fortify.go
#	pkg/fortify/fortify_test.go

* Completely avoid interacting with fulltextsearch

* Remove also from version lookup
2021-01-21 16:20:46 +01:00

1288 lines
66 KiB
Go

package fortify
import (
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
"time"
"github.com/go-openapi/strfmt"
ff "github.com/piper-validation/fortify-client-go/fortify"
"github.com/piper-validation/fortify-client-go/models"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
piperHttp "github.com/SAP/jenkins-library/pkg/http"
)
func spinUpServer(f func(http.ResponseWriter, *http.Request)) (*SystemInstance, *httptest.Server) {
server := httptest.NewServer(http.HandlerFunc(f))
parts := strings.Split(server.URL, "://")
client := ff.NewHTTPClientWithConfig(strfmt.Default, &ff.TransportConfig{
Host: parts[1],
Schemes: []string{parts[0]},
BasePath: ""},
)
httpClient := &piperHttp.Client{}
httpClientOptions := piperHttp.ClientOptions{Token: "test2456", TransportTimeout: 60 * time.Second}
httpClient.SetOptions(httpClientOptions)
sys := NewSystemInstanceForClient(client, httpClient, server.URL, "test2456", 60*time.Second)
return sys, server
}
func TestCreateTransportConfig(t *testing.T) {
t.Run("Valid URL", func(t *testing.T) {
config := createTransportConfig("http://some.fortify.host.com/ssc", "/api/v2")
assert.Equal(t, []string{"http"}, config.Schemes)
assert.Equal(t, "some.fortify.host.com", config.Host)
assert.Equal(t, "ssc/api/v2", config.BasePath)
})
t.Run("Slashes are trimmed", func(t *testing.T) {
config := createTransportConfig("http://some.fortify.host.com/ssc//", "//api/v2/")
assert.Equal(t, []string{"http"}, config.Schemes)
assert.Equal(t, "some.fortify.host.com", config.Host)
assert.Equal(t, "ssc/api/v2", config.BasePath)
})
t.Run("URL missing scheme results in no error", func(t *testing.T) {
config := createTransportConfig("some.fortify.host.com/ssc", "api/v1")
assert.Equal(t, []string{"https"}, config.Schemes)
assert.Equal(t, "some.fortify.host.com", config.Host)
assert.Equal(t, "ssc/api/v1", config.BasePath)
})
t.Run("URL with more than one slash is accepted", func(t *testing.T) {
config := createTransportConfig("https://some.fortify.host.com/some/path/ssc", "api/v1")
assert.Equal(t, []string{"https"}, config.Schemes)
assert.Equal(t, "some.fortify.host.com", config.Host)
assert.Equal(t, "some/path/ssc/api/v1", config.BasePath)
})
}
func TestNewSystemInstance(t *testing.T) {
t.Run("fields are initialized", func(t *testing.T) {
sys := NewSystemInstance("https://some.fortify.host.com/ssc", "api/v1", "akjhskjhks", 10*time.Second)
assert.IsType(t, ff.Fortify{}, *sys.client, "Expected to get a Fortify client instance")
assert.IsType(t, piperHttp.Client{}, *sys.httpClient, "Expected to get a HTTP client instance")
assert.IsType(t, logrus.Entry{}, *sys.logger, "Expected to get a logrus entry instance")
assert.Equal(t, 10*time.Second, sys.timeout, "Expected different timeout value")
assert.Equal(t, "akjhskjhks", sys.token, "Expected different token value")
assert.Equal(t, "https://some.fortify.host.com/ssc", sys.serverURL)
})
t.Run("SSC URL is trimmed", func(t *testing.T) {
sys := NewSystemInstance("https://some.fortify.host.com/ssc/", "api/v1", "akjhskjhks", 10*time.Second)
assert.Equal(t, "https://some.fortify.host.com/ssc", sys.serverURL)
})
}
func TestGetProjectByName(t *testing.T) {
// Start a local HTTP server
autocreateCalled := false
commitCalled := false
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projects" && req.URL.RawQuery == "q=name%3Dpython-test" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(
`{"data": [{"_href": "https://fortify/ssc/api/v1/projects/4711","createdBy": "someUser","name": "python-test",
"description": "","id": 4711,"creationDate": "2018-12-03T06:29:38.197+0000","issueTemplateId": "dasdasdasdsadasdasdasdasdas"}],
"count": 1,"responseCode": 200,"links": {"last": {"href": "https://fortify/ssc/api/v1/projects?q=name%A3python-test&start=0"},
"first": {"href": "https://fortify/ssc/api/v1/projects?q=name%A3python-test&start=0"}}}`))
return
}
if req.URL.Path == "/projects" && req.URL.RawQuery == "q=name%3Dpython-empty" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(
`{"data": [],"count": 0,"responseCode": 404,"links": {}}`))
return
}
if req.URL.Path == "/projects" && req.URL.RawQuery == "q=name%3Dpython-error" {
rw.WriteHeader(400)
return
}
if req.URL.Path == "/projectVersions" && req.Method == "POST" {
autocreateCalled = true
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(201)
rw.Write([]byte(
`{"data":{"latestScanId":null,"serverVersion":17.2,"tracesOutOfDate":false,"attachmentsOutOfDate":false,"description":"",
"project":{"id":815,"name":"autocreate","description":"","creationDate":"2018-12-03T06:29:38.197+0000","createdBy":"someUser",
"issueTemplateId":"dasdasdasdsadasdasdasdasdas"},"sourceBasePath":null,"mode":"BASIC","masterAttrGuid":"sddasdasda","obfuscatedId":null,
"id":10172,"customTagValuesAutoApply":null,"issueTemplateId":"dasdasdasdsadasdasdasdasdas","loadProperties":null,"predictionPolicy":null,
"bugTrackerPluginId":null,"owner":"admin","_href":"https://fortify.mo.sap.corp/ssc/api/v1/projectVersions/10172",
"committed":true,"bugTrackerEnabled":false,"active":true,"snapshotOutOfDate":false,"issueTemplateModifiedTime":1578411924701,
"securityGroup":null,"creationDate":"2018-02-09T16:59:41.297+0000","refreshRequired":false,"issueTemplateName":"someTemplate",
"migrationVersion":null,"createdBy":"admin","name":"0","siteId":null,"staleIssueTemplate":false,"autoPredict":null,
"currentState":{"id":10172,"committed":true,"attentionRequired":false,"analysisResultsExist":true,"auditEnabled":true,
"lastFprUploadDate":"2018-02-09T16:59:53.497+0000","extraMessage":null,"analysisUploadEnabled":true,"batchBugSubmissionExists":false,
"hasCustomIssues":false,"metricEvaluationDate":"2018-03-10T00:02:45.553+0000","deltaPeriod":7,"issueCountDelta":0,"percentAuditedDelta":0.0,
"criticalPriorityIssueCountDelta":0,"percentCriticalPriorityIssuesAuditedDelta":0.0},"assignedIssuesCount":0,"status":null},
"count":1,"responseCode":200,"links":{"last":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/815/versions?start=0"},
"first":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/815/versions?start=0"}}}`))
return
}
if req.URL.Path == "/projectVersions/10172" {
commitCalled = true
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(
`{"data": {"_href": "https://fortify/ssc/api/v1/projects/815", "committed": true,"createdBy": "someUser","name": "autocreate",
"description": "","id": 815,"creationDate": "2018-12-03T06:29:38.197+0000","issueTemplateId": "dasdasdasdsadasdasdasdasdas"},
"count": 1,"responseCode": 200,"links": {"last": {"href": "https://fortify/ssc/api/v1/projects?q=name%A3python-test&start=0"},
"first": {"href": ""}}}`))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
result, err := sys.GetProjectByName("python-test", false, "")
assert.NoError(t, err, "GetProjectByName call not successful")
assert.Equal(t, "python-test", strings.ToLower(*result.Name), "Expected to get python-test")
})
t.Run("test empty", func(t *testing.T) {
_, err := sys.GetProjectByName("python-empty", false, "")
assert.Error(t, err, "Expected error but got success")
})
t.Run("test error", func(t *testing.T) {
_, err := sys.GetProjectByName("python-error", false, "")
assert.Error(t, err, "Expected error but got success")
})
t.Run("test auto create success", func(t *testing.T) {
result, err := sys.GetProjectByName("autocreate", true, "123456")
assert.NoError(t, err, "GetProjectByName call not successful")
assert.Equal(t, true, autocreateCalled, "Expected autocreation function to be called but wasn't")
assert.Equal(t, true, commitCalled, "Expected commit function to be called but wasn't")
assert.Equal(t, "autocreate", strings.ToLower(*result.Name), "Expected to get autocreate project")
})
}
func TestGetProjectVersionDetailsByProjectIDAndVersionName(t *testing.T) {
// Start a local HTTP server
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projects/4711/versions" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(
`{"data":[{"latestScanId":null,"serverVersion":17.2,"tracesOutOfDate":false,"attachmentsOutOfDate":false,"description":"",
"project":{"id":4711,"name":"python-test","description":"","creationDate":"2018-12-03T06:29:38.197+0000","createdBy":"someUser",
"issueTemplateId":"dasdasdasdsadasdasdasdasdas"},"sourceBasePath":null,"mode":"BASIC","masterAttrGuid":"sddasdasda","obfuscatedId":null,
"id":10172,"customTagValuesAutoApply":null,"issueTemplateId":"dasdasdasdsadasdasdasdasdas","loadProperties":null,"predictionPolicy":null,
"bugTrackerPluginId":null,"owner":"admin","_href":"https://fortify.mo.sap.corp/ssc/api/v1/projectVersions/10172",
"committed":true,"bugTrackerEnabled":false,"active":true,"snapshotOutOfDate":false,"issueTemplateModifiedTime":1578411924701,
"securityGroup":null,"creationDate":"2018-02-09T16:59:41.297+0000","refreshRequired":false,"issueTemplateName":"someTemplate",
"migrationVersion":null,"createdBy":"admin","name":"0","siteId":null,"staleIssueTemplate":false,"autoPredict":null,
"currentState":{"id":10172,"committed":true,"attentionRequired":false,"analysisResultsExist":true,"auditEnabled":true,
"lastFprUploadDate":"2018-02-09T16:59:53.497+0000","extraMessage":null,"analysisUploadEnabled":true,"batchBugSubmissionExists":false,
"hasCustomIssues":false,"metricEvaluationDate":"2018-03-10T00:02:45.553+0000","deltaPeriod":7,"issueCountDelta":0,"percentAuditedDelta":0.0,
"criticalPriorityIssueCountDelta":0,"percentCriticalPriorityIssuesAuditedDelta":0.0},"assignedIssuesCount":0,"status":null}],
"count":1,"responseCode":200,"links":{"last":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/4711/versions?start=0"},
"first":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/4711/versions?start=0"}}}`))
return
}
if req.URL.Path == "/projects/777/versions" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(
`{"data": [],"count": 0,"responseCode": 404,"links": {}}`))
return
}
if req.URL.Path == "/projects/999/versions" {
rw.WriteHeader(500)
return
}
if req.URL.Path == "/projectVersions" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(201)
rw.Write([]byte(
`{"data":{"latestScanId":null,"serverVersion":17.2,"tracesOutOfDate":false,"attachmentsOutOfDate":false,"description":"",
"project":{"id":815,"name":"autocreate","description":"","creationDate":"2018-12-03T06:29:38.197+0000","createdBy":"someUser",
"issueTemplateId":"dasdasdasdsadasdasdasdasdas"},"sourceBasePath":null,"mode":"BASIC","masterAttrGuid":"sddasdasda","obfuscatedId":null,
"id":10172,"customTagValuesAutoApply":null,"issueTemplateId":"dasdasdasdsadasdasdasdasdas","loadProperties":null,"predictionPolicy":null,
"bugTrackerPluginId":null,"owner":"admin","_href":"https://fortify.mo.sap.corp/ssc/api/v1/projectVersions/10172",
"committed":true,"bugTrackerEnabled":false,"active":true,"snapshotOutOfDate":false,"issueTemplateModifiedTime":1578411924701,
"securityGroup":null,"creationDate":"2018-02-09T16:59:41.297+0000","refreshRequired":false,"issueTemplateName":"someTemplate",
"migrationVersion":null,"createdBy":"admin","name":"0","siteId":null,"staleIssueTemplate":false,"autoPredict":null,
"currentState":{"id":10172,"committed":true,"attentionRequired":false,"analysisResultsExist":true,"auditEnabled":true,
"lastFprUploadDate":"2018-02-09T16:59:53.497+0000","extraMessage":null,"analysisUploadEnabled":true,"batchBugSubmissionExists":false,
"hasCustomIssues":false,"metricEvaluationDate":"2018-03-10T00:02:45.553+0000","deltaPeriod":7,"issueCountDelta":0,"percentAuditedDelta":0.0,
"criticalPriorityIssueCountDelta":0,"percentCriticalPriorityIssuesAuditedDelta":0.0},"assignedIssuesCount":0,"status":null},
"count":1,"responseCode":200,"links":{"last":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/815/versions?start=0"},
"first":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/815/versions?start=0"}}}`))
return
}
if req.URL.Path == "/projectVersions/0" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(
`{"data":{"latestScanId":null,"serverVersion":17.2,"tracesOutOfDate":false,"attachmentsOutOfDate":false,"description":"",
"project":{"id":815,"name":"autocreate","description":"","creationDate":"2018-12-03T06:29:38.197+0000","createdBy":"someUser",
"issueTemplateId":"dasdasdasdsadasdasdasdasdas"},"sourceBasePath":null,"mode":"BASIC","masterAttrGuid":"sddasdasda","obfuscatedId":null,
"id":10172,"customTagValuesAutoApply":null,"issueTemplateId":"dasdasdasdsadasdasdasdasdas","loadProperties":null,"predictionPolicy":null,
"bugTrackerPluginId":null,"owner":"admin","_href":"https://fortify.mo.sap.corp/ssc/api/v1/projectVersions/10172",
"committed":true,"bugTrackerEnabled":false,"active":true,"snapshotOutOfDate":false,"issueTemplateModifiedTime":1578411924701,
"securityGroup":null,"creationDate":"2018-02-09T16:59:41.297+0000","refreshRequired":false,"issueTemplateName":"someTemplate",
"migrationVersion":null,"createdBy":"admin","name":"0","siteId":null,"staleIssueTemplate":false,"autoPredict":null,
"currentState":{"id":10172,"committed":true,"attentionRequired":false,"analysisResultsExist":true,"auditEnabled":true,
"lastFprUploadDate":"2018-02-09T16:59:53.497+0000","extraMessage":null,"analysisUploadEnabled":true,"batchBugSubmissionExists":false,
"hasCustomIssues":false,"metricEvaluationDate":"2018-03-10T00:02:45.553+0000","deltaPeriod":7,"issueCountDelta":0,"percentAuditedDelta":0.0,
"criticalPriorityIssueCountDelta":0,"percentCriticalPriorityIssuesAuditedDelta":0.0},"assignedIssuesCount":0,"status":null},
"count":1,"responseCode":200,"links":{"last":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/815/versions?start=0"},
"first":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/815/versions?start=0"}}}`))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
result, err := sys.GetProjectVersionDetailsByProjectIDAndVersionName(4711, "0", false, "")
assert.NoError(t, err, "GetProjectVersionDetailsByNameAndProjectID call not successful")
assert.Equal(t, "0", *result.Name, "Expected to get project version with different name")
})
t.Run("test empty", func(t *testing.T) {
_, err := sys.GetProjectVersionDetailsByProjectIDAndVersionName(777, "python-empty", false, "")
assert.Error(t, err, "Expected error but got success")
})
t.Run("test HTTP error", func(t *testing.T) {
_, err := sys.GetProjectVersionDetailsByProjectIDAndVersionName(999, "python-http-error", false, "")
assert.Error(t, err, "Expected error but got success")
})
t.Run("test auto create success", func(t *testing.T) {
result, err := sys.GetProjectVersionDetailsByProjectIDAndVersionName(815, "0", true, "autocreate")
assert.NoError(t, err, "GetProjectVersionDetailsByNameAndProjectID call not successful")
assert.Equal(t, "0", *result.Name, "Expected to get project version with different name")
assert.Equal(t, "autocreate", *result.Project.Name, "Expected to get project with different name")
})
}
func TestGetProjectVersionAttributesByProjectVersionID(t *testing.T) {
// Start a local HTTP server
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/4711/attributes" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(
`{"data": [{"_href": "https://fortify.mo.sap.corp/ssc/api/v1/projectVersions/4711/attributes/4712","attributeDefinitionId": 31,
"values": null,"guid": "gdgfdgfdgfdgfd","id": 4712,"value": "abcd"}],"count": 8,"responseCode": 200}`))
return
}
if req.URL.Path == "/projectVersions/777/attributes" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(
`{"data": [],"count": 0,"responseCode": 404,"links": {}}`))
return
}
if req.URL.Path == "/projectVersions/999/attributes" {
rw.WriteHeader(500)
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
result, err := sys.GetProjectVersionAttributesByProjectVersionID(4711)
assert.NoError(t, err, "GetProjectVersionAttributesByProjectVersionID call not successful")
assert.Equal(t, "abcd", *result[0].Value, "Expected to get attribute with different value")
assert.Equal(t, int64(4712), result[0].ID, "Expected to get attribute with different id")
})
t.Run("test empty", func(t *testing.T) {
result, err := sys.GetProjectVersionAttributesByProjectVersionID(777)
assert.NoError(t, err, "GetProjectVersionAttributesByID call not successful")
assert.Equal(t, 0, len(result), "Expected to not get any attributes")
})
t.Run("test HTTP error", func(t *testing.T) {
_, err := sys.GetProjectVersionAttributesByProjectVersionID(999)
assert.Error(t, err, "Expected error but got success")
})
}
func TestSetProjectVersionAttributesByProjectVersionID(t *testing.T) {
// Start a local HTTP server
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/4711/attributes" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyBytes, _ := ioutil.ReadAll(req.Body)
bodyString := string(bodyBytes)
response := `{"data": `
response += bodyString
response += `,"count": 1,"responseCode": 200}`
rw.WriteHeader(200)
rw.Write([]byte(response))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
value := "abcd"
defID := int64(18)
attributes := []*models.Attribute{{ID: 4712, Value: &value, AttributeDefinitionID: &defID}}
result, err := sys.SetProjectVersionAttributesByProjectVersionID(4711, attributes)
assert.NoError(t, err, "SetProjectVersionAttributesByProjectVersionID call not successful")
assert.Equal(t, 1, len(result), "Expected to get slice with different amount of values")
assert.Equal(t, "abcd", *result[0].Value, "Expected to get attribute with different value")
assert.Equal(t, int64(4712), result[0].ID, "Expected to get attribute with different id")
})
}
func TestCreateProjectVersion(t *testing.T) {
// Start a local HTTP server
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyBytes, _ := ioutil.ReadAll(req.Body)
bodyContent := string(bodyBytes)
responseContent := `{"data": `
responseContent += bodyContent
responseContent += `,"count": 1,"responseCode": 201,"links": {}}`
fmt.Println(responseContent)
rw.WriteHeader(201)
rw.Write([]byte(responseContent))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
int64Value := int64(65)
int32Value := int32(876)
float32Value := float32(19.12)
now := models.NewIso8601MilliDateTime()
enabled := true
disabled := false
name := "Test new PV"
owner := "someUser"
masterGUID := "dsadaoudoiud"
project := models.Project{CreatedBy: &owner, CreationDate: now, Description: name, ID: int64Value, IssueTemplateID: &name, Name: &name}
projectVersionState := models.ProjectVersionState{AnalysisResultsExist: &disabled, AnalysisUploadEnabled: &disabled,
AttentionRequired: &disabled, AuditEnabled: &enabled, BatchBugSubmissionExists: &disabled, Committed: &enabled,
CriticalPriorityIssueCountDelta: &int32Value, DeltaPeriod: &int32Value, ExtraMessage: &name, HasCustomIssues: &disabled,
ID: &int64Value, IssueCountDelta: &int32Value, LastFprUploadDate: &now, MetricEvaluationDate: &now, PercentAuditedDelta: &float32Value,
PercentCriticalPriorityIssuesAuditedDelta: &float32Value}
version := models.ProjectVersion{AssignedIssuesCount: int64Value, Project: &project, Name: &name, Active: &enabled,
Committed: &enabled, AttachmentsOutOfDate: disabled, AutoPredict: disabled, BugTrackerEnabled: &disabled,
CustomTagValuesAutoApply: disabled, RefreshRequired: disabled, Owner: &owner, ServerVersion: &float32Value,
SnapshotOutOfDate: &disabled, StaleIssueTemplate: &disabled, MasterAttrGUID: &masterGUID,
LatestScanID: &int64Value, IssueTemplateName: &name, IssueTemplateModifiedTime: &int64Value,
IssueTemplateID: &name, Description: &name, CreatedBy: &owner, BugTrackerPluginID: &name, Mode: "NONE",
CurrentState: &projectVersionState, ID: int64Value, LoadProperties: "", CreationDate: &now,
MigrationVersion: float32Value, ObfuscatedID: "", PredictionPolicy: "", SecurityGroup: "",
SiteID: "", SourceBasePath: "", Status: "", TracesOutOfDate: false}
result, err := sys.CreateProjectVersion(&version)
assert.NoError(t, err, "CreateProjectVersion call not successful")
assert.Equal(t, name, *result.Name, "Expected to get PV with different value")
assert.Equal(t, int64(65), result.ID, "Expected to get PV with different id")
})
}
func TestProjectVersionCopyFromPartial(t *testing.T) {
// Start a local HTTP server
bodyContent := ""
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/action/copyFromPartial" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyBytes, _ := ioutil.ReadAll(req.Body)
bodyContent = string(bodyBytes)
rw.Write([]byte(
`{"data":[{"latestScanId":null,"serverVersion":17.2,"tracesOutOfDate":false,"attachmentsOutOfDate":false,"description":"",
"project":{"id":4711,"name":"python-test","description":"","creationDate":"2018-12-03T06:29:38.197+0000","createdBy":"someUser",
"issueTemplateId":"dasdasdasdsadasdasdasdasdas"},"sourceBasePath":null,"mode":"BASIC","masterAttrGuid":"sddasdasda","obfuscatedId":null,
"id":10172,"customTagValuesAutoApply":null,"issueTemplateId":"dasdasdasdsadasdasdasdasdas","loadProperties":null,"predictionPolicy":null,
"bugTrackerPluginId":null,"owner":"admin","_href":"https://fortify.mo.sap.corp/ssc/api/v1/projectVersions/10172",
"committed":true,"bugTrackerEnabled":false,"active":true,"snapshotOutOfDate":false,"issueTemplateModifiedTime":1578411924701,
"securityGroup":null,"creationDate":"2018-02-09T16:59:41.297+0000","refreshRequired":false,"issueTemplateName":"someTemplate",
"migrationVersion":null,"createdBy":"admin","name":"0","siteId":null,"staleIssueTemplate":false,"autoPredict":null,
"currentState":{"id":10172,"committed":true,"attentionRequired":false,"analysisResultsExist":true,"auditEnabled":true,
"lastFprUploadDate":"2018-02-09T16:59:53.497+0000","extraMessage":null,"analysisUploadEnabled":true,"batchBugSubmissionExists":false,
"hasCustomIssues":false,"metricEvaluationDate":"2018-03-10T00:02:45.553+0000","deltaPeriod":7,"issueCountDelta":0,"percentAuditedDelta":0.0,
"criticalPriorityIssueCountDelta":0,"percentCriticalPriorityIssuesAuditedDelta":0.0},"assignedIssuesCount":0,"status":null}],
"count":1,"responseCode":200,"links":{"last":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/4711/versions?start=0"},
"first":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/4711/versions?start=0"}}}`))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
expected := `{"copyAnalysisProcessingRules":true,"copyBugTrackerConfiguration":true,"copyCustomTags":true,"previousProjectVersionId":10172,"projectVersionId":10173}
`
err := sys.ProjectVersionCopyFromPartial(10172, 10173)
assert.NoError(t, err, "ProjectVersionCopyFromPartial call not successful")
assert.Equal(t, expected, bodyContent, "Different request content expected")
})
}
func TestProjectVersionCopyCurrentState(t *testing.T) {
// Start a local HTTP server
bodyContent := ""
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/action/copyCurrentState" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyBytes, _ := ioutil.ReadAll(req.Body)
bodyContent = string(bodyBytes)
rw.Write([]byte(
`{"data":[{"latestScanId":null,"serverVersion":17.2,"tracesOutOfDate":false,"attachmentsOutOfDate":false,"description":"",
"project":{"id":4711,"name":"python-test","description":"","creationDate":"2018-12-03T06:29:38.197+0000","createdBy":"someUser",
"issueTemplateId":"dasdasdasdsadasdasdasdasdas"},"sourceBasePath":null,"mode":"BASIC","masterAttrGuid":"sddasdasda","obfuscatedId":null,
"id":10172,"customTagValuesAutoApply":null,"issueTemplateId":"dasdasdasdsadasdasdasdasdas","loadProperties":null,"predictionPolicy":null,
"bugTrackerPluginId":null,"owner":"admin","_href":"https://fortify.mo.sap.corp/ssc/api/v1/projectVersions/10172",
"committed":true,"bugTrackerEnabled":false,"active":true,"snapshotOutOfDate":false,"issueTemplateModifiedTime":1578411924701,
"securityGroup":null,"creationDate":"2018-02-09T16:59:41.297+0000","refreshRequired":false,"issueTemplateName":"someTemplate",
"migrationVersion":null,"createdBy":"admin","name":"0","siteId":null,"staleIssueTemplate":false,"autoPredict":null,
"currentState":{"id":10172,"committed":true,"attentionRequired":false,"analysisResultsExist":true,"auditEnabled":true,
"lastFprUploadDate":"2018-02-09T16:59:53.497+0000","extraMessage":null,"analysisUploadEnabled":true,"batchBugSubmissionExists":false,
"hasCustomIssues":false,"metricEvaluationDate":"2018-03-10T00:02:45.553+0000","deltaPeriod":7,"issueCountDelta":0,"percentAuditedDelta":0.0,
"criticalPriorityIssueCountDelta":0,"percentCriticalPriorityIssuesAuditedDelta":0.0},"assignedIssuesCount":0,"status":null}],
"count":1,"responseCode":200,"links":{"last":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/4711/versions?start=0"},
"first":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/4711/versions?start=0"}}}`))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
expected := `{"previousProjectVersionId":10172,"projectVersionId":10173}
`
err := sys.ProjectVersionCopyCurrentState(10172, 10173)
assert.NoError(t, err, "ProjectVersionCopyCurrentState call not successful")
assert.Equal(t, expected, bodyContent, "Different request content expected")
})
}
func TestProjectVersionCopyPermissions(t *testing.T) {
// Start a local HTTP server
bodyContent := ""
referenceContent := `[{"displayName":"some user","email":"some.one@test.com","entityName":"some_user","firstName":"some","id":589,"lastName":"user","type":"User"}]
`
response := `{"data": `
response += referenceContent
response += `,"count": 1,"responseCode": 200}`
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/10172/authEntities" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(response))
return
}
if req.URL.Path == "/projectVersions/10173/authEntities" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyBytes, _ := ioutil.ReadAll(req.Body)
bodyContent = string(bodyBytes)
rw.Write([]byte(response))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
err := sys.ProjectVersionCopyPermissions(10172, 10173)
assert.NoError(t, err, "ProjectVersionCopyPermissions call not successful")
assert.Equal(t, referenceContent, bodyContent, "Different request content expected")
})
}
func TestCommitProjectVersion(t *testing.T) {
// Start a local HTTP server
bodyContent := ""
referenceContent := `{"active":null,"bugTrackerEnabled":null,"bugTrackerPluginId":null,"committed":true,"createdBy":null,"creationDate":null,"description":null,"issueTemplateId":null,"issueTemplateModifiedTime":null,"issueTemplateName":null,"latestScanId":null,"masterAttrGuid":null,"name":null,"owner":null,"serverVersion":null,"snapshotOutOfDate":null,"staleIssueTemplate":null}
`
response := `{"data": `
response += referenceContent
response += `,"count": 1,"responseCode": 200}`
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/10172" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyBytes, _ := ioutil.ReadAll(req.Body)
bodyContent = string(bodyBytes)
rw.Write([]byte(response))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
result, err := sys.CommitProjectVersion(10172)
assert.NoError(t, err, "CommitProjectVersion call not successful")
assert.Equal(t, true, *result.Committed, "Different result content expected")
assert.Equal(t, referenceContent, bodyContent, "Different request content expected")
})
}
func TestInactivateProjectVersion(t *testing.T) {
// Start a local HTTP server
bodyContent := ""
referenceContent := `{"active":false,"bugTrackerEnabled":null,"bugTrackerPluginId":null,"committed":true,"createdBy":null,"creationDate":null,"description":null,"issueTemplateId":null,"issueTemplateModifiedTime":null,"issueTemplateName":null,"latestScanId":null,"masterAttrGuid":null,"name":null,"owner":null,"serverVersion":null,"snapshotOutOfDate":null,"staleIssueTemplate":null}
`
response := `{"data": `
response += referenceContent
response += `,"count": 1,"responseCode": 200}`
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/10172" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyBytes, _ := ioutil.ReadAll(req.Body)
bodyContent = string(bodyBytes)
rw.Write([]byte(response))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
result, err := sys.inactivateProjectVersion(10172)
assert.NoError(t, err, "InactivateProjectVersion call not successful")
assert.Equal(t, true, *result.Committed, "Different result content expected")
assert.Equal(t, false, *result.Active, "Different result content expected")
assert.Equal(t, referenceContent, bodyContent, "Different request content expected")
})
}
func TestGetArtifactsOfProjectVersion(t *testing.T) {
// Start a local HTTP server
response := `{"data": [{"artifactType": "FPR","fileName": "df54e2ade34c4f6aaddf35679dd87a21.tmp","approvalDate": null,"messageCount": 0,
"scanErrorsCount": 0,"uploadIP": "10.238.8.48","allowApprove": false,"allowPurge": false,"lastScanDate": "2019-11-26T22:37:52.000+0000",
"fileURL": null,"id": 56,"purged": false,"webInspectStatus": "NONE","inModifyingStatus": false,"originalFileName": "result.fpr",
"allowDelete": true,"scaStatus": "PROCESSED","indexed": true,"runtimeStatus": "NONE","userName": "some_user","versionNumber": null,
"otherStatus": "NOT_EXIST","uploadDate": "2019-11-26T22:38:11.813+0000","approvalComment": null,"approvalUsername": null,"fileSize": 984703,
"messages": "","auditUpdated": false,"status": "PROCESS_COMPLETE"}],"count": 1,"responseCode": 200}`
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/10172/artifacts" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(response))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
result, err := sys.GetArtifactsOfProjectVersion(10172)
assert.NoError(t, err, "GetArtifactsOfProjectVersion call not successful")
assert.Equal(t, 1, len(result), "Different result content expected")
assert.Equal(t, int64(56), result[0].ID, "Different result content expected")
})
}
func TestGetFilterSetOfProjectVersionByTitle(t *testing.T) {
// Start a local HTTP server
response := `{"data":[{"defaultFilterSet":true,"folders":[
{"id":1,"guid":"4711","name":"Corporate Security Requirements","color":"000000"},
{"id":2,"guid":"4712","name":"Audit All","color":"ff0000"},
{"id":3,"guid":"4713","name":"Spot Checks of Each Category","color":"ff8000"},
{"id":4,"guid":"4714","name":"Optional","color":"808080"}],"description":"",
"guid":"666","title":"Special"}],"count":1,"responseCode":200}}`
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/10172/filterSets" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(response))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
result, err := sys.GetFilterSetOfProjectVersionByTitle(10172, "Special")
assert.NoError(t, err, "GetFilterSetOfProjectVersionByTitle call not successful")
assert.Equal(t, "Special", result.Title, "Different result content expected")
})
t.Run("test default", func(t *testing.T) {
result, err := sys.GetFilterSetOfProjectVersionByTitle(10172, "")
assert.NoError(t, err, "GetFilterSetOfProjectVersionByTitle call not successful")
assert.Equal(t, "Special", result.Title, "Different result content expected")
})
}
func TestGetIssueFilterSelectorOfProjectVersionByName(t *testing.T) {
// Start a local HTTP server
response := `{"data":{"groupBySet": [{"entityType": "CUSTOMTAG","guid": "adsffghjkl","displayName": "Analysis",
"value": "87f2364f-dcd4-49e6-861d-f8d3f351686b","description": ""},{"entityType": "ISSUE","guid": "lkjhgfd",
"displayName": "Category","value": "11111111-1111-1111-1111-111111111165","description": ""}],"filterBySet":[{
"entityType": "CUSTOMTAG","filterSelectorType": "LIST","guid": "87f2364f-dcd4-49e6-861d-f8d3f351686b","displayName": "Analysis",
"value": "87f2364f-dcd4-49e6-861d-f8d3f351686b","description": "The analysis tag must be set.",
"selectorOptions": []},{"entityType": "FOLDER","filterSelectorType": "LIST","guid": "userAssignment","displayName": "Folder",
"value": "FOLDER","description": "","selectorOptions": []}]},"responseCode":200}}`
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/10172/issueSelectorSet" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(response))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success one", func(t *testing.T) {
result, err := sys.GetIssueFilterSelectorOfProjectVersionByName(10172, []string{"Analysis"}, nil)
assert.NoError(t, err, "GetIssueFilterSelectorOfProjectVersionByName call not successful")
assert.NotNil(t, result, "Expected non nil value")
assert.Equal(t, 1, len(result.FilterBySet), "Different result expected")
assert.Equal(t, 1, len(result.GroupBySet), "Different result expected")
})
t.Run("test success several", func(t *testing.T) {
result, err := sys.GetIssueFilterSelectorOfProjectVersionByName(10172, []string{"Analysis", "Folder"}, nil)
assert.NoError(t, err, "GetIssueFilterSelectorOfProjectVersionByName call not successful")
assert.NotNil(t, result, "Expected non nil value")
assert.Equal(t, 2, len(result.FilterBySet), "Different result expected")
assert.Equal(t, 1, len(result.GroupBySet), "Different result expected")
})
t.Run("test empty", func(t *testing.T) {
result, err := sys.GetIssueFilterSelectorOfProjectVersionByName(10172, []string{"Some", "Other"}, nil)
assert.NoError(t, err, "GetIssueFilterSelectorOfProjectVersionByName call not successful")
assert.NotNil(t, result, "Expected non nil value")
assert.Equal(t, 0, len(result.FilterBySet), "Different result expected")
assert.Equal(t, 0, len(result.GroupBySet), "Different result expected")
})
}
func TestReduceIssueFilterSelectorSet(t *testing.T) {
sys, _ := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {})
name1 := "Special"
name2 := "Other"
guid := "FOLDER"
options := []*models.SelectorOption{{GUID: "1234567", DisplayName: "Test"}, {GUID: "1234568", DisplayName: "Test2"}}
filterSet := models.IssueFilterSelectorSet{FilterBySet: []*models.IssueFilterSelector{}, GroupBySet: []*models.IssueSelector{}}
filterSet.FilterBySet = append(filterSet.FilterBySet, &models.IssueFilterSelector{DisplayName: name1, SelectorOptions: options})
filterSet.FilterBySet = append(filterSet.FilterBySet, &models.IssueFilterSelector{DisplayName: name2})
filterSet.GroupBySet = append(filterSet.GroupBySet, &models.IssueSelector{DisplayName: &name2, GUID: &guid})
reducedFilterSet := sys.ReduceIssueFilterSelectorSet(&filterSet, []string{"Special"}, []string{"Test"})
assert.Equal(t, 1, len(reducedFilterSet.FilterBySet), "Different result expected")
assert.Equal(t, 1, len(reducedFilterSet.FilterBySet[0].SelectorOptions), "Different result expected")
assert.Equal(t, "Test", reducedFilterSet.FilterBySet[0].SelectorOptions[0].DisplayName, "Different result expected")
assert.Equal(t, 0, len(reducedFilterSet.GroupBySet), "Different result expected")
}
func TestGetProjectIssuesByIDAndFilterSetGroupedBySelector(t *testing.T) {
// Start a local HTTP server
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/10172/filterSets" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(`{"data":[{"defaultFilterSet":true,"folders":[
{"id":1,"guid":"4711","name":"Corporate Security Requirements","color":"000000"},
{"id":2,"guid":"4712","name":"Audit All","color":"ff0000"},
{"id":3,"guid":"4713","name":"Spot Checks of Each Category","color":"ff8000"},
{"id":4,"guid":"4714","name":"Optional","color":"808080"}],"description":"",
"guid":"666","title":"Special"}],"count":1,"responseCode":200}}`))
return
}
if req.URL.Path == "/projectVersions/10172/issueGroups" {
assert.Equal(t, "filterset=666&groupingtype=FOLDER&showsuppressed=true", req.URL.RawQuery)
return
}
rw.WriteHeader(400)
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
name := "Special"
guid := "FOLDER"
filterSet := models.IssueFilterSelectorSet{FilterBySet: []*models.IssueFilterSelector{}, GroupBySet: []*models.IssueSelector{}}
filterSet.FilterBySet = append(filterSet.FilterBySet, &models.IssueFilterSelector{DisplayName: name})
filterSet.GroupBySet = append(filterSet.GroupBySet, &models.IssueSelector{DisplayName: &name, GUID: &guid})
_, err := sys.GetProjectIssuesByIDAndFilterSetGroupedBySelector(10172, "", "666", &filterSet)
assert.NoError(t, err, "GetProjectIssuesByIDAndFilterSetGroupedByFolder call not successful")
})
}
func TestGetProjectIssuesByIDAndFilterSetGroupedByCategory(t *testing.T) {
// Start a local HTTP server
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/10172/filterSets" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(`{"data":[{"defaultFilterSet":true,"folders":[
{"id":1,"guid":"4711","name":"Corporate Security Requirements","color":"000000"},
{"id":2,"guid":"4712","name":"Audit All","color":"ff0000"},
{"id":3,"guid":"4713","name":"Spot Checks of Each Category","color":"ff8000"},
{"id":4,"guid":"4714","name":"Optional","color":"808080"}],"description":"",
"guid":"666","title":"Special"}],"count":1,"responseCode":200}}`))
return
}
if req.URL.Path == "/projectVersions/10172/issueGroups" {
assert.Equal(t, "filter=4713&filterset=666&groupingtype=11111111-1111-1111-1111-111111111165&showsuppressed=true", req.URL.RawQuery)
return
}
rw.WriteHeader(400)
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
name := "Special"
guid := "11111111-1111-1111-1111-111111111165"
filterSet := models.IssueFilterSelectorSet{FilterBySet: []*models.IssueFilterSelector{}, GroupBySet: []*models.IssueSelector{}}
filterSet.FilterBySet = append(filterSet.FilterBySet, &models.IssueFilterSelector{DisplayName: name})
filterSet.GroupBySet = append(filterSet.GroupBySet, &models.IssueSelector{DisplayName: &name, GUID: &guid})
_, err := sys.GetProjectIssuesByIDAndFilterSetGroupedBySelector(10172, "4713", "666", &filterSet)
assert.NoError(t, err, "GetProjectIssuesByIDAndFilterSetGroupedByCategory call not successful")
})
}
func TestGetProjectIssuesByIDAndFilterSetGroupedByAnalysis(t *testing.T) {
// Start a local HTTP server
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/10172/filterSets" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(`{"data":[{"defaultFilterSet":true,"folders":[
{"id":1,"guid":"4711","name":"Corporate Security Requirements","color":"000000"},
{"id":2,"guid":"4712","name":"Audit All","color":"ff0000"},
{"id":3,"guid":"4713","name":"Spot Checks of Each Category","color":"ff8000"},
{"id":4,"guid":"4714","name":"Optional","color":"808080"}],"description":"",
"guid":"666","title":"Special"}],"count":1,"responseCode":200}}`))
return
}
if req.URL.Path == "/projectVersions/10172/issueGroups" {
assert.Equal(t, "filterset=666&groupingtype=87f2364f-dcd4-49e6-861d-f8d3f351686b&showsuppressed=true", req.URL.RawQuery)
return
}
rw.WriteHeader(400)
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
name := "Special"
guid := "87f2364f-dcd4-49e6-861d-f8d3f351686b"
filterSet := models.IssueFilterSelectorSet{FilterBySet: []*models.IssueFilterSelector{}, GroupBySet: []*models.IssueSelector{}}
filterSet.FilterBySet = append(filterSet.FilterBySet, &models.IssueFilterSelector{DisplayName: name})
filterSet.GroupBySet = append(filterSet.GroupBySet, &models.IssueSelector{DisplayName: &name, GUID: &guid})
_, err := sys.GetProjectIssuesByIDAndFilterSetGroupedBySelector(10172, "", "666", &filterSet)
assert.NoError(t, err, "GetProjectIssuesByIDAndFilterSetGroupedByAnalysis call not successful")
})
}
func TestGetIssueStatisticsOfProjectVersion(t *testing.T) {
// Start a local HTTP server
response := `{"data": [{"filterSetId": 3887,"hiddenCount": 0,"suppressedDisplayableCount": 0,"suppressedCount": 11,"hiddenDisplayableCount": 0,"projectVersionId": 10172,
"removedDisplayableCount": 0,"removedCount": 747}],"count": 1,"responseCode": 200}`
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projectVersions/10172/issueStatistics" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(response))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
result, err := sys.GetIssueStatisticsOfProjectVersion(10172)
assert.NoError(t, err, "GetArtifactsOfProjectVersion call not successful")
assert.Equal(t, 1, len(result), "Different result content expected")
assert.Equal(t, int64(10172), *result[0].ProjectVersionID, "Different result content expected")
assert.Equal(t, int32(11), *result[0].SuppressedCount, "Different result content expected")
})
}
func TestGenerateQGateReport(t *testing.T) {
// Start a local HTTP server
data := ""
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/reports" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyBytes, _ := ioutil.ReadAll(req.Body)
data = string(bodyBytes)
response := `{"data": `
response += data
response += `,"responseCode": 201}`
rw.WriteHeader(201)
rw.Write([]byte(response))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
result, err := sys.GenerateQGateReport(2837, 17540, 18, "Fortify", "develop", "PDF")
assert.NoError(t, err, "GetArtifactsOfProjectVersion call not successful")
assert.Equal(t, int64(2837), result.Projects[0].ID, "Different result content expected")
assert.Equal(t, int64(17540), result.Projects[0].Versions[0].ID, "Different result content expected")
assert.Equal(t, int64(18), *result.ReportDefinitionID, "Different result content expected")
})
}
func TestGetReportDetails(t *testing.T) {
// Start a local HTTP server
response := `{"data": {"id":999,"name":"FortifyReport","note":"","type":"PORTFOLIO","reportDefinitionId":18,"format":"PDF",
"projects":[{"id":2837,"name":"Fortify","versions":[{"id":17540,"name":"develop"}]}],"projectVersionDisplayName":"develop",
"inputReportParameters":[{"name":"Q-gate-report","identifier":"projectVersionId","paramValue":17540,"type":"SINGLE_PROJECT"}]},"count": 1,"responseCode": 200}`
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/reports/999" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(response))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
result, err := sys.GetReportDetails(999)
assert.NoError(t, err, "GetReportDetails call not successful")
assert.Equal(t, int64(999), result.ID, "Different result content expected")
})
}
func TestGetFileToken(t *testing.T) {
// Start a local HTTP server
bodyContent := ""
reference := `{"fileTokenType":"TOKEN_TYPE"}
`
response := `{"data": {"fileTokenType": "TOKEN_TYPE","token": "ZjE1OTdjZjEtMjAzNS00NTFmLThiOWItNzBkYzI0MWEzZGNj"},"responseCode": 201}`
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/fileTokens" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyBytes, _ := ioutil.ReadAll(req.Body)
bodyContent = string(bodyBytes)
rw.WriteHeader(201)
rw.Write([]byte(response))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
result, err := sys.getFileToken("TOKEN_TYPE")
assert.NoError(t, err)
assert.Equal(t, "ZjE1OTdjZjEtMjAzNS00NTFmLThiOWItNzBkYzI0MWEzZGNj", result.Token)
assert.Equal(t, reference, bodyContent)
})
}
func TestInvalidateFileToken(t *testing.T) {
// Start a local HTTP server
response := `{"responseCode": 200}`
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/fileTokens" && req.Method == "DELETE" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(200)
rw.Write([]byte(response))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
err := sys.invalidateFileTokens()
assert.NoError(t, err, "invalidateFileTokens call not successful")
})
}
func TestUploadResultFile(t *testing.T) {
// Start a local HTTP server
bodyContent := ""
getTokenCalled := false
invalidateTokenCalled := false
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/fileTokens" && req.Method == "DELETE" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(200)
rw.Write([]byte(`{"responseCode": 200}`))
invalidateTokenCalled = true
return
}
if req.URL.Path == "/fileTokens" && req.Method == "POST" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(201)
rw.Write([]byte(`{"data": {"token": "89ee873"}, "responseCode": 201}`))
getTokenCalled = true
return
}
if req.URL.Path == "/upload/resultFileUpload.html" && req.URL.RawQuery == "mat=89ee873" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyBytes, _ := ioutil.ReadAll(req.Body)
bodyContent = string(bodyBytes)
rw.WriteHeader(200)
rw.Write([]byte("OK"))
return
}
})
// Close the server when test finishes
defer server.Close()
testFile, err := ioutil.TempFile("", "result.fpr")
if err != nil {
t.FailNow()
}
defer os.RemoveAll(testFile.Name()) // clean up
t.Run("test success", func(t *testing.T) {
err := sys.UploadResultFile("/upload/resultFileUpload.html", testFile.Name(), 10770)
assert.NoError(t, err, "UploadFile call not successful")
assert.Contains(t, bodyContent, `Content-Disposition: form-data; name="file"; filename=`, "Expected different content in request body")
assert.Contains(t, bodyContent, `Content-Disposition: form-data; name="entityId"`, "Expected different content in request body")
assert.Contains(t, bodyContent, `10770`, "Expected different content in request body")
assert.Equal(t, true, getTokenCalled, "Expected GetUploadToken to be called")
assert.Equal(t, true, invalidateTokenCalled, "Expected InvalidateFileTokens to be called")
})
}
func TestDownloadResultFile(t *testing.T) {
// Start a local HTTP server
bodyContent := ""
getTokenCalled := false
invalidateTokenCalled := false
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/fileTokens" && req.Method == "DELETE" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(200)
rw.Write([]byte(`{"responseCode": 200}`))
invalidateTokenCalled = true
return
}
if req.URL.Path == "/fileTokens" && req.Method == "POST" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(201)
rw.Write([]byte(`{"data": {"token": "89ee873"}, "responseCode": 201}`))
getTokenCalled = true
return
}
if req.URL.Path == "/download/currentStateFprDownload.html" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyContent = req.URL.RawQuery
rw.WriteHeader(200)
rw.Write([]byte("OK"))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
data, err := sys.DownloadResultFile("/download/currentStateFprDownload.html", 10775)
assert.NoError(t, err, "DownloadResultFile call not successful")
assert.Equal(t, "id=10775&mat=89ee873", bodyContent, "Expected different request body")
assert.Equal(t, []byte("OK"), data, "Expected different result")
assert.Equal(t, true, getTokenCalled, "Expected GetUploadToken to be called")
assert.Equal(t, true, invalidateTokenCalled, "Expected InvalidateFileTokens to be called")
})
}
func TestDownloadReportFile(t *testing.T) {
// Start a local HTTP server
getTokenCalled := false
invalidateTokenCalled := false
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/fileTokens" && req.Method == "DELETE" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(200)
rw.Write([]byte(`{"responseCode": 200}`))
invalidateTokenCalled = true
return
}
if req.URL.Path == "/fileTokens" && req.Method == "POST" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(201)
rw.Write([]byte(`{"data": {"token": "89ee873"}, "responseCode": 201}`))
getTokenCalled = true
return
}
if req.URL.Path == "/transfer/reportDownload.html" && req.URL.RawQuery == "id=10775&mat=89ee873" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(200)
rw.Write([]byte("OK"))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
data, err := sys.DownloadReportFile("/transfer/reportDownload.html", 10775)
assert.NoError(t, err, "DownloadReportFile call not successful")
assert.Equal(t, []byte("OK"), data, "Expected different result")
assert.Equal(t, true, getTokenCalled, "Expected GetUploadToken to be called")
assert.Equal(t, true, invalidateTokenCalled, "Expected InvalidateFileTokens to be called")
})
}
func TestLookupOrCreateProjectVersionDetailsForPullRequest(t *testing.T) {
// Start a local HTTP server
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projects/4711/versions" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(200)
rw.Write([]byte(`{"data": [], "count": 0, "responseCode": 200}`))
return
}
if req.URL.Path == "/projectVersions" && req.Method == "POST" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyBytes, _ := ioutil.ReadAll(req.Body)
bodyContent := string(bodyBytes)
responseContent := `{"data": `
responseContent += bodyContent
responseContent += `,"count": 1,"responseCode": 201,"links": {}}`
fmt.Println(responseContent)
rw.WriteHeader(201)
rw.Write([]byte(responseContent))
return
}
if req.URL.Path == "/projectVersions/4711/attributes" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(
`{"data": [{"_href": "https://fortify.mo.sap.corp/ssc/api/v1/projectVersions/4711/attributes/4712","attributeDefinitionId": 31,
"values": null,"guid": "gdgfdgfdgfdgfd","id": 4712,"value": "abcd"}],"count": 8,"responseCode": 200}`))
return
}
if req.URL.Path == "/projectVersions/4712/attributes" {
header := rw.Header()
header.Add("Content-type", "application/json")
bodyBytes, _ := ioutil.ReadAll(req.Body)
bodyString := string(bodyBytes)
response := `{"data": `
response += bodyString
response += `,"count": 1,"responseCode": 200}`
rw.WriteHeader(200)
rw.Write([]byte(response))
return
}
if req.URL.Path == "/projectVersions/action/copyFromPartial" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(
`{"data":[{"latestScanId":null,"serverVersion":17.2,"tracesOutOfDate":false,"attachmentsOutOfDate":false,"description":"",
"project":{"id":4711,"name":"python-test","description":"","creationDate":"2018-12-03T06:29:38.197+0000","createdBy":"someUser",
"issueTemplateId":"dasdasdasdsadasdasdasdasdas"},"sourceBasePath":null,"mode":"BASIC","masterAttrGuid":"sddasdasda","obfuscatedId":null,
"id":10172,"customTagValuesAutoApply":null,"issueTemplateId":"dasdasdasdsadasdasdasdasdas","loadProperties":null,"predictionPolicy":null,
"bugTrackerPluginId":null,"owner":"admin","_href":"https://fortify.mo.sap.corp/ssc/api/v1/projectVersions/10172",
"committed":true,"bugTrackerEnabled":false,"active":true,"snapshotOutOfDate":false,"issueTemplateModifiedTime":1578411924701,
"securityGroup":null,"creationDate":"2018-02-09T16:59:41.297+0000","refreshRequired":false,"issueTemplateName":"someTemplate",
"migrationVersion":null,"createdBy":"admin","name":"0","siteId":null,"staleIssueTemplate":false,"autoPredict":null,
"currentState":{"id":10172,"committed":true,"attentionRequired":false,"analysisResultsExist":true,"auditEnabled":true,
"lastFprUploadDate":"2018-02-09T16:59:53.497+0000","extraMessage":null,"analysisUploadEnabled":true,"batchBugSubmissionExists":false,
"hasCustomIssues":false,"metricEvaluationDate":"2018-03-10T00:02:45.553+0000","deltaPeriod":7,"issueCountDelta":0,"percentAuditedDelta":0.0,
"criticalPriorityIssueCountDelta":0,"percentCriticalPriorityIssuesAuditedDelta":0.0},"assignedIssuesCount":0,"status":null}],
"count":1,"responseCode":200,"links":{"last":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/4711/versions?start=0"},
"first":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/4711/versions?start=0"}}}`))
return
}
if req.URL.Path == "/projectVersions/10172" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(`{"data": {"active":null,"bugTrackerEnabled":null,"bugTrackerPluginId":null,"committed":true,"createdBy":null,"creationDate":null,"description":null,"issueTemplateId":null,"issueTemplateModifiedTime":null,"issueTemplateName":null,"latestScanId":null,"masterAttrGuid":null,"name":null,"owner":null,"serverVersion":null,"snapshotOutOfDate":null,"staleIssueTemplate":null}, "responseCode": 200}`))
return
}
if req.URL.Path == "/projectVersions/action/copyCurrentState" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(
`{"data":[{"latestScanId":null,"serverVersion":17.2,"tracesOutOfDate":false,"attachmentsOutOfDate":false,"description":"",
"project":{"id":4711,"name":"python-test","description":"","creationDate":"2018-12-03T06:29:38.197+0000","createdBy":"someUser",
"issueTemplateId":"dasdasdasdsadasdasdasdasdas"},"sourceBasePath":null,"mode":"BASIC","masterAttrGuid":"sddasdasda","obfuscatedId":null,
"id":10172,"customTagValuesAutoApply":null,"issueTemplateId":"dasdasdasdsadasdasdasdasdas","loadProperties":null,"predictionPolicy":null,
"bugTrackerPluginId":null,"owner":"admin","_href":"https://fortify.mo.sap.corp/ssc/api/v1/projectVersions/10172",
"committed":true,"bugTrackerEnabled":false,"active":true,"snapshotOutOfDate":false,"issueTemplateModifiedTime":1578411924701,
"securityGroup":null,"creationDate":"2018-02-09T16:59:41.297+0000","refreshRequired":false,"issueTemplateName":"someTemplate",
"migrationVersion":null,"createdBy":"admin","name":"0","siteId":null,"staleIssueTemplate":false,"autoPredict":null,
"currentState":{"id":10172,"committed":true,"attentionRequired":false,"analysisResultsExist":true,"auditEnabled":true,
"lastFprUploadDate":"2018-02-09T16:59:53.497+0000","extraMessage":null,"analysisUploadEnabled":true,"batchBugSubmissionExists":false,
"hasCustomIssues":false,"metricEvaluationDate":"2018-03-10T00:02:45.553+0000","deltaPeriod":7,"issueCountDelta":0,"percentAuditedDelta":0.0,
"criticalPriorityIssueCountDelta":0,"percentCriticalPriorityIssuesAuditedDelta":0.0},"assignedIssuesCount":0,"status":null}],
"count":1,"responseCode":200,"links":{"last":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/4711/versions?start=0"},
"first":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/4711/versions?start=0"}}}`))
return
}
if req.URL.Path == "/projectVersions/10172/authEntities" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(`{"data": [{"displayName":"some user","email":"some.one@test.com","entityName":"some_user","firstName":"some","id":589,"lastName":"user","type":"User"}],"count": 1,"responseCode": 200}`))
return
}
if req.URL.Path == "/projectVersions/10173/authEntities" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(`{"data": [{"displayName":"some user","email":"some.one@test.com","entityName":"some_user","firstName":"some","id":589,"lastName":"user","type":"User"}],"count": 1,"responseCode": 200}`))
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
int64Value := int64(65)
int32Value := int32(876)
float32Value := float32(19.12)
now := models.NewIso8601MilliDateTime()
enabled := true
disabled := false
name := "Test new PV"
owner := "someUser"
masterGUID := "dsadaoudoiud"
project := models.Project{CreatedBy: &owner, CreationDate: now, Description: name, ID: int64Value, IssueTemplateID: &name, Name: &name}
projectVersionState := models.ProjectVersionState{AnalysisResultsExist: &disabled, AnalysisUploadEnabled: &disabled,
AttentionRequired: &disabled, AuditEnabled: &enabled, BatchBugSubmissionExists: &disabled, Committed: &enabled,
CriticalPriorityIssueCountDelta: &int32Value, DeltaPeriod: &int32Value, ExtraMessage: &name, HasCustomIssues: &disabled,
ID: &int64Value, IssueCountDelta: &int32Value, LastFprUploadDate: &now, MetricEvaluationDate: &now, PercentAuditedDelta: &float32Value,
PercentCriticalPriorityIssuesAuditedDelta: &float32Value}
masterProjectVersion := models.ProjectVersion{AssignedIssuesCount: int64Value, Project: &project, Name: &name, Active: &enabled,
Committed: &enabled, AttachmentsOutOfDate: disabled, AutoPredict: disabled, BugTrackerEnabled: &disabled,
CustomTagValuesAutoApply: disabled, RefreshRequired: disabled, Owner: &owner, ServerVersion: &float32Value,
SnapshotOutOfDate: &disabled, StaleIssueTemplate: &disabled, MasterAttrGUID: &masterGUID,
LatestScanID: &int64Value, IssueTemplateName: &name, IssueTemplateModifiedTime: &int64Value,
IssueTemplateID: &name, Description: &name, CreatedBy: &owner, BugTrackerPluginID: &name, Mode: "NONE",
CurrentState: &projectVersionState, ID: int64Value, LoadProperties: "", CreationDate: &now,
MigrationVersion: float32Value, ObfuscatedID: "", PredictionPolicy: "", SecurityGroup: "",
SiteID: "", SourceBasePath: "", Status: "", TracesOutOfDate: false}
prProjectVersion, err := sys.LookupOrCreateProjectVersionDetailsForPullRequest(4711, &masterProjectVersion, "PR-815")
assert.NoError(t, err, "LookupOrCreateProjectVersionDetailsForPullRequest call not successful")
assert.Equal(t, "PR-815", *prProjectVersion.Name, "Expected different result")
assert.Equal(t, masterProjectVersion.Description, prProjectVersion.Description, "Expected different result")
assert.Equal(t, masterProjectVersion.Active, prProjectVersion.Active, "Expected different result")
assert.Equal(t, masterProjectVersion.Committed, prProjectVersion.Committed, "Expected different result")
assert.Equal(t, masterProjectVersion.Project.Name, prProjectVersion.Project.Name, "Expected different result")
assert.Equal(t, masterProjectVersion.Project.Description, prProjectVersion.Project.Description, "Expected different result")
assert.Equal(t, masterProjectVersion.Project.ID, prProjectVersion.Project.ID, "Expected different result")
assert.Equal(t, masterProjectVersion.IssueTemplateID, prProjectVersion.IssueTemplateID, "Expected different result")
})
}
func TestMergeProjectVersionStateOfPRIntoMaster(t *testing.T) {
// Start a local HTTP server
getPRProjectVersionCalled := false
invalidateTokenCalled := false
getTokenCalled := false
downloadCalled := false
uploadCalled := false
inactivateCalled := false
sys, server := spinUpServer(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/projects/4711/versions" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(`{"data":[{"latestScanId":null,"serverVersion":17.2,"tracesOutOfDate":false,"attachmentsOutOfDate":false,"description":"",
"project":{"id":4711,"name":"product.some.com","description":"","creationDate":"2018-12-03T06:29:38.197+0000","createdBy":"someUser",
"issueTemplateId":"dasdasdasdsadasdasdasdasdas"},"sourceBasePath":null,"mode":"BASIC","masterAttrGuid":"sddasdasda","obfuscatedId":null,
"id":10172,"customTagValuesAutoApply":null,"issueTemplateId":"dasdasdasdsadasdasdasdasdas","loadProperties":null,"predictionPolicy":null,
"bugTrackerPluginId":null,"owner":"admin","_href":"https://fortify.mo.sap.corp/ssc/api/v1/projectVersions/10172",
"committed":true,"bugTrackerEnabled":false,"active":true,"snapshotOutOfDate":false,"issueTemplateModifiedTime":1578411924701,
"securityGroup":null,"creationDate":"2018-02-09T16:59:41.297+0000","refreshRequired":false,"issueTemplateName":"someTemplate",
"migrationVersion":null,"createdBy":"admin","name":"PR-815","siteId":null,"staleIssueTemplate":false,"autoPredict":null,
"currentState":{"id":10172,"committed":true,"attentionRequired":false,"analysisResultsExist":true,"auditEnabled":true,
"lastFprUploadDate":"2018-02-09T16:59:53.497+0000","extraMessage":null,"analysisUploadEnabled":true,"batchBugSubmissionExists":false,
"hasCustomIssues":false,"metricEvaluationDate":"2018-03-10T00:02:45.553+0000","deltaPeriod":7,"issueCountDelta":0,"percentAuditedDelta":0.0,
"criticalPriorityIssueCountDelta":0,"percentCriticalPriorityIssuesAuditedDelta":0.0},"assignedIssuesCount":0,"status":null}],
"count":1,"responseCode":200,"links":{"last":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/4711/versions?start=0"},
"first":{"href":"https://fortify.mo.sap.corp/ssc/api/v1/projects/4711/versions?start=0"}}}`))
getPRProjectVersionCalled = true
return
}
if req.URL.Path == "/fileTokens" && req.Method == "DELETE" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(200)
rw.Write([]byte(`{"responseCode": 200}`))
invalidateTokenCalled = true
return
}
if req.URL.Path == "/fileTokens" && req.Method == "POST" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(201)
rw.Write([]byte(`{"data": {"token": "89ee873"}, "responseCode": 201}`))
getTokenCalled = true
return
}
if req.URL.Path == "/download/currentStateFprDownload.html" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(200)
rw.Write([]byte("OK"))
downloadCalled = true
return
}
if req.URL.Path == "/upload/resultFileUpload.html" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.WriteHeader(200)
rw.Write([]byte("OK"))
uploadCalled = true
return
}
if req.URL.Path == "/projectVersions/10172" {
header := rw.Header()
header.Add("Content-type", "application/json")
rw.Write([]byte(`{"data": {"active":false,"bugTrackerEnabled":null,"bugTrackerPluginId":null,"committed":true,"createdBy":null,"creationDate":null,"description":null,"issueTemplateId":null,"issueTemplateModifiedTime":null,"issueTemplateName":null,"latestScanId":null,"masterAttrGuid":null,"name":null,"owner":null,"serverVersion":null,"snapshotOutOfDate":null,"staleIssueTemplate":null}, "responseCode": 200}`))
inactivateCalled = true
return
}
})
// Close the server when test finishes
defer server.Close()
t.Run("test success", func(t *testing.T) {
err := sys.MergeProjectVersionStateOfPRIntoMaster("/download/currentStateFprDownload.html", "/upload/resultFileUpload.html", 4711, 10171, "PR-815")
assert.NoError(t, err, "MergeProjectVersionStateOfPRIntoMaster call not successful")
assert.Equal(t, true, getPRProjectVersionCalled, "Expected different value")
assert.Equal(t, true, invalidateTokenCalled, "Expected different value")
assert.Equal(t, true, getTokenCalled, "Expected different value")
assert.Equal(t, true, downloadCalled, "Expected different value")
assert.Equal(t, true, uploadCalled, "Expected different value")
assert.Equal(t, true, inactivateCalled, "Expected different value")
})
}