2020-10-20 09:49:26 +02:00
|
|
|
package whitesource
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2021-02-03 15:52:48 +02:00
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
|
|
|
|
2020-10-20 09:49:26 +02:00
|
|
|
"github.com/SAP/jenkins-library/pkg/mock"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestExecuteScanNPM(t *testing.T) {
|
|
|
|
config := ScanOptions{
|
|
|
|
ScanType: "npm",
|
|
|
|
OrgToken: "org-token",
|
|
|
|
UserToken: "user-token",
|
|
|
|
ProductName: "mock-product",
|
|
|
|
ProjectName: "mock-project",
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
t.Run("happy path NPM", func(t *testing.T) {
|
|
|
|
// init
|
|
|
|
utilsMock := NewScanUtilsMock()
|
|
|
|
utilsMock.AddFile("package.json", []byte(`{"name":"my-module-name"}`))
|
|
|
|
scan := newTestScan(&config)
|
|
|
|
// test
|
|
|
|
err := scan.ExecuteNpmScan(&config, utilsMock)
|
|
|
|
// assert
|
|
|
|
require.NoError(t, err)
|
|
|
|
expectedCalls := []mock.ExecCall{
|
|
|
|
{
|
|
|
|
Exec: "npm",
|
|
|
|
Params: []string{
|
|
|
|
"ls",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Exec: "npx",
|
|
|
|
Params: []string{
|
|
|
|
"whitesource",
|
|
|
|
"run",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
assert.Equal(t, expectedCalls, utilsMock.Calls)
|
|
|
|
assert.True(t, utilsMock.HasWrittenFile(whiteSourceConfig))
|
|
|
|
assert.True(t, utilsMock.HasRemovedFile(whiteSourceConfig))
|
|
|
|
})
|
2020-11-26 12:45:53 +02:00
|
|
|
t.Run("happy path with excluded modules", func(t *testing.T) {
|
|
|
|
// init
|
|
|
|
utilsMock := NewScanUtilsMock()
|
|
|
|
utilsMock.AddFile("package.json", []byte(`{"name":"my-module-name"}`))
|
|
|
|
utilsMock.AddFile("sub/package.json", []byte(`{"name":"my-sub-module-name"}`))
|
|
|
|
utilsMock.AddFile("deep/sub/package.json", []byte(`{"name":"my-deep-sub-module-name"}`))
|
|
|
|
|
|
|
|
config := ScanOptions{
|
|
|
|
ScanType: "npm",
|
|
|
|
OrgToken: "org-token",
|
|
|
|
UserToken: "user-token",
|
|
|
|
ProductName: "mock-product",
|
|
|
|
ProjectName: "mock-project",
|
|
|
|
BuildDescriptorExcludeList: []string{"unrelated/pom.xml", "sub/package.json", "deep/sub/package.json"},
|
|
|
|
}
|
|
|
|
|
|
|
|
scan := newTestScan(&config)
|
|
|
|
// test
|
|
|
|
err := scan.ExecuteNpmScan(&config, utilsMock)
|
|
|
|
// assert
|
|
|
|
require.NoError(t, err)
|
|
|
|
expectedCalls := []mock.ExecCall{
|
|
|
|
{
|
|
|
|
Exec: "npm",
|
|
|
|
Params: []string{
|
|
|
|
"ls",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Exec: "npx",
|
|
|
|
Params: []string{
|
|
|
|
"whitesource",
|
|
|
|
"run",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
assert.Equal(t, expectedCalls, utilsMock.Calls)
|
|
|
|
assert.True(t, utilsMock.HasWrittenFile(whiteSourceConfig))
|
|
|
|
assert.True(t, utilsMock.HasRemovedFile(whiteSourceConfig))
|
|
|
|
assert.False(t, utilsMock.HasWrittenFile(filepath.Join("sub", whiteSourceConfig)))
|
|
|
|
assert.False(t, utilsMock.HasWrittenFile(filepath.Join("deep", "sub", whiteSourceConfig)))
|
|
|
|
})
|
2020-10-20 09:49:26 +02:00
|
|
|
t.Run("no NPM modules", func(t *testing.T) {
|
|
|
|
// init
|
|
|
|
utilsMock := NewScanUtilsMock()
|
|
|
|
scan := newTestScan(&config)
|
|
|
|
// test
|
|
|
|
err := scan.ExecuteNpmScan(&config, utilsMock)
|
|
|
|
// assert
|
|
|
|
assert.EqualError(t, err, "found no NPM modules to scan. Configured excludes: []")
|
|
|
|
assert.Len(t, utilsMock.Calls, 0)
|
|
|
|
assert.False(t, utilsMock.HasWrittenFile(whiteSourceConfig))
|
|
|
|
})
|
|
|
|
t.Run("package.json needs name", func(t *testing.T) {
|
|
|
|
// init
|
|
|
|
utilsMock := NewScanUtilsMock()
|
|
|
|
utilsMock.AddFile("package.json", []byte(`{"key":"value"}`))
|
|
|
|
scan := newTestScan(&config)
|
|
|
|
// test
|
|
|
|
err := scan.ExecuteNpmScan(&config, utilsMock)
|
|
|
|
// assert
|
|
|
|
assert.EqualError(t, err, "failed to scan NPM module 'package.json': the file 'package.json' must configure a name")
|
|
|
|
})
|
|
|
|
t.Run("npm ls fails", func(t *testing.T) {
|
|
|
|
// init
|
|
|
|
utilsMock := NewScanUtilsMock()
|
|
|
|
utilsMock.AddFile("package.json", []byte(`{"name":"my-module-name"}`))
|
|
|
|
utilsMock.AddFile(filepath.Join("app", "package.json"), []byte(`{"name":"my-app-module-name"}`))
|
|
|
|
utilsMock.AddFile("package-lock.json", []byte("dummy"))
|
|
|
|
|
|
|
|
utilsMock.ShouldFailOnCommand = make(map[string]error)
|
|
|
|
utilsMock.ShouldFailOnCommand["npm ls"] = fmt.Errorf("mock failure")
|
|
|
|
scan := newTestScan(&config)
|
|
|
|
// test
|
|
|
|
err := scan.ExecuteNpmScan(&config, utilsMock)
|
|
|
|
// assert
|
|
|
|
assert.NoError(t, err)
|
|
|
|
expectedNpmInstalls := []NpmInstall{
|
2020-11-10 10:09:51 +02:00
|
|
|
{CurrentDir: "app", PackageJSON: []string{"package.json"}},
|
|
|
|
{CurrentDir: "", PackageJSON: []string{"package.json"}},
|
2020-10-20 09:49:26 +02:00
|
|
|
}
|
|
|
|
assert.Equal(t, expectedNpmInstalls, utilsMock.NpmInstalledModules)
|
|
|
|
assert.True(t, utilsMock.HasRemovedFile("package-lock.json"))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestWriteWhitesourceConfigJSON(t *testing.T) {
|
|
|
|
config := &ScanOptions{
|
2021-02-03 15:52:48 +02:00
|
|
|
OrgToken: "org-token",
|
|
|
|
UserToken: "user-token",
|
|
|
|
ProductName: "mock-product",
|
|
|
|
ProductVersion: "product-version",
|
|
|
|
ProjectName: "mock-project",
|
|
|
|
ProductToken: "mock-product-token",
|
2020-10-20 09:49:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
expected := make(map[string]interface{})
|
|
|
|
expected["apiKey"] = "org-token"
|
|
|
|
expected["userKey"] = "user-token"
|
|
|
|
expected["checkPolicies"] = true
|
2020-11-26 12:45:53 +02:00
|
|
|
expected["forceUpdate"] = true
|
2020-10-20 09:49:26 +02:00
|
|
|
expected["productName"] = "mock-product"
|
|
|
|
expected["projectName"] = "mock-project"
|
|
|
|
expected["productToken"] = "mock-product-token"
|
|
|
|
expected["productVer"] = "product-version"
|
|
|
|
expected["devDep"] = true
|
|
|
|
expected["ignoreNpmLsErrors"] = true
|
|
|
|
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
t.Run("write config from scratch", func(t *testing.T) {
|
|
|
|
// init
|
|
|
|
utils := NewScanUtilsMock()
|
|
|
|
scan := newTestScan(config)
|
|
|
|
// test
|
|
|
|
err := scan.writeWhitesourceConfigJSON(config, utils, true, true)
|
|
|
|
// assert
|
|
|
|
if assert.NoError(t, err) && assert.True(t, utils.HasWrittenFile(whiteSourceConfig)) {
|
|
|
|
contents, _ := utils.FileRead(whiteSourceConfig)
|
|
|
|
actual := make(map[string]interface{})
|
|
|
|
_ = json.Unmarshal(contents, &actual)
|
|
|
|
assert.Equal(t, expected, actual)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("extend and merge config", func(t *testing.T) {
|
|
|
|
// init
|
|
|
|
initial := make(map[string]interface{})
|
|
|
|
initial["checkPolicies"] = false
|
|
|
|
initial["productName"] = "mock-product"
|
|
|
|
initial["productVer"] = "41"
|
|
|
|
initial["unknown"] = "preserved"
|
|
|
|
encoded, _ := json.Marshal(initial)
|
|
|
|
|
|
|
|
utils := NewScanUtilsMock()
|
|
|
|
utils.AddFile(whiteSourceConfig, encoded)
|
|
|
|
|
|
|
|
scan := newTestScan(config)
|
|
|
|
|
|
|
|
// test
|
|
|
|
err := scan.writeWhitesourceConfigJSON(config, utils, true, true)
|
|
|
|
// assert
|
|
|
|
if assert.NoError(t, err) && assert.True(t, utils.HasWrittenFile(whiteSourceConfig)) {
|
|
|
|
contents, _ := utils.FileRead(whiteSourceConfig)
|
|
|
|
actual := make(map[string]interface{})
|
|
|
|
_ = json.Unmarshal(contents, &actual)
|
|
|
|
|
|
|
|
mergedExpected := expected
|
|
|
|
mergedExpected["unknown"] = "preserved"
|
|
|
|
|
|
|
|
assert.Equal(t, mergedExpected, actual)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("extend and merge config, omit productToken", func(t *testing.T) {
|
|
|
|
// init
|
|
|
|
initial := make(map[string]interface{})
|
|
|
|
initial["checkPolicies"] = false
|
|
|
|
initial["productName"] = "mock-product"
|
|
|
|
initial["productVer"] = "41"
|
|
|
|
initial["unknown"] = "preserved"
|
|
|
|
initial["projectToken"] = "mock-project-token"
|
|
|
|
encoded, _ := json.Marshal(initial)
|
|
|
|
|
|
|
|
utils := NewScanUtilsMock()
|
|
|
|
utils.AddFile(whiteSourceConfig, encoded)
|
|
|
|
|
|
|
|
scan := newTestScan(config)
|
|
|
|
|
|
|
|
// test
|
|
|
|
err := scan.writeWhitesourceConfigJSON(config, utils, true, true)
|
|
|
|
// assert
|
|
|
|
if assert.NoError(t, err) && assert.True(t, utils.HasWrittenFile(whiteSourceConfig)) {
|
|
|
|
contents, _ := utils.FileRead(whiteSourceConfig)
|
|
|
|
actual := make(map[string]interface{})
|
|
|
|
_ = json.Unmarshal(contents, &actual)
|
|
|
|
|
|
|
|
mergedExpected := expected
|
|
|
|
mergedExpected["unknown"] = "preserved"
|
|
|
|
mergedExpected["projectToken"] = "mock-project-token"
|
|
|
|
delete(mergedExpected, "productToken")
|
|
|
|
|
|
|
|
assert.Equal(t, mergedExpected, actual)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|