diff --git a/checks/files_to_ignore_test.go b/checks/files_to_ignore_test.go index c4932f2..9daa430 100644 --- a/checks/files_to_ignore_test.go +++ b/checks/files_to_ignore_test.go @@ -26,6 +26,21 @@ func TestFilesToIgnore(t *testing.T) { assert.Empty(t, testReport.Issues) }) + t.Run("Ignore PDB and .gitignore as Special Cases", func(t *testing.T) { + t.Parallel() + testReport := report.Report{ + UploadedFiles: []report.UploadedFile{ + {Id: 111111, Name: ".gitignore", MD5: "hash1", IsIgnored: false, IsThirdParty: false}, + {Id: 222222, Name: "test.pdb", MD5: "hash2", IsIgnored: false, IsThirdParty: false}, + }, + Issues: []report.Issue{}, + } + + ignoreJunkFiles(&testReport) + assert.Empty(t, testReport.Issues) + assert.True(t, testReport.UploadedFiles[1].IsIgnored) + }) + t.Run("1 file to Ignore", func(t *testing.T) { t.Parallel() testReport := report.Report{ diff --git a/checks/minified_javascript.go b/checks/minified_javascript.go index 76e526e..cb1080e 100644 --- a/checks/minified_javascript.go +++ b/checks/minified_javascript.go @@ -2,9 +2,10 @@ package checks import ( "fmt" + "strings" + "github.com/antfie/scan_health/v2/report" "github.com/antfie/scan_health/v2/utils" - "strings" ) // Test cases diff --git a/checks/minified_javascript_test.go b/checks/minified_javascript_test.go new file mode 100644 index 0000000..875628d --- /dev/null +++ b/checks/minified_javascript_test.go @@ -0,0 +1,117 @@ +package checks + +import ( + "testing" + + "github.com/antfie/scan_health/v2/report" + "github.com/stretchr/testify/assert" +) + +func TestMinifiedJavaScript(t *testing.T) { + + t.Run("No Issues", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "Test", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 111111, Name: "file1.js", MD5: "hash1", IsIgnored: false, IsThirdParty: false}, + {Id: 222222, Name: "file2.js", MD5: "hash2", IsIgnored: false, IsThirdParty: false}, + }, + } + + minifiedJavaScript(&mockReport) + + assert.Equal(t, len(mockReport.Issues), 0) + }) + + t.Run("No JS Minified Issues", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "Test", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {Issues: []string{"No PDB files found"}}, + }}, + }, + } + + minifiedJavaScript(&mockReport) + + assert.Equal(t, len(mockReport.Issues), 0) + }) + + t.Run("Testing for JS Minified Warning", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "JS files within Test", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {Issues: []string{"because we think it is minified"}}, + }}, + {Name: "JS files within Test2", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {Issues: []string{"because we think it is minified"}}, + }}, + }, + } + + minifiedJavaScript(&mockReport) + + if !assert.Equal(t, len(mockReport.Issues), 1) { + t.FailNow() + } + + assert.Contains(t, mockReport.Issues[0].Description, "2 minified") + assert.Equal(t, mockReport.Issues[0].Severity, report.IssueSeverityMedium) + assert.Equal(t, len(mockReport.Recommendations), 2) + }) + + t.Run("Testing for /dist/ JS Files", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "JS files within Test", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {Issues: []string{"Random issue in /dist/blah.js"}}, + }}, + }, + } + + minifiedJavaScript(&mockReport) + + assert.Equal(t, len(mockReport.Issues), 1) + assert.Equal(t, mockReport.Issues[0].Severity, report.IssueSeverityMedium) + assert.Equal(t, len(mockReport.Recommendations), 2) + }) + + t.Run("Testing for minification by name", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + UploadedFiles: []report.UploadedFile{ + {Id: 111111, Name: "file1.min.js", MD5: "hash1", IsIgnored: false, IsThirdParty: false}, + {Id: 222222, Name: "file2.js", MD5: "hash2", IsIgnored: false, IsThirdParty: false}, + {Id: 222222, Name: "file3.min.js", MD5: "hash3", IsIgnored: false, IsThirdParty: false}, + }, + } + + minifiedJavaScript(&mockReport) + if !assert.Equal(t, len(mockReport.Issues), 1) { + t.FailNow() + } + + assert.Contains(t, mockReport.Issues[0].Description, "2 minified") + assert.Equal(t, mockReport.Issues[0].Severity, report.IssueSeverityMedium) + + assert.Equal(t, len(mockReport.Recommendations), 2) + }) + +} diff --git a/checks/missing_debug_symbols_test.go b/checks/missing_debug_symbols_test.go new file mode 100644 index 0000000..a6f5689 --- /dev/null +++ b/checks/missing_debug_symbols_test.go @@ -0,0 +1,114 @@ +package checks + +import ( + "testing" + + "github.com/antfie/scan_health/v2/report" + "github.com/stretchr/testify/assert" +) + +func TestMissingDebugSymbols(t *testing.T) { + + t.Run("No Executables/DLLs", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "file3.jar", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 333333, Name: "file3.jar", MD5: "hash2", IsIgnored: false, IsThirdParty: false}, + }, + } + + missingDebugSymbols(&mockReport) + + assert.Equal(t, len(mockReport.Issues), 0) + }) + + t.Run("Executables/DLLs but no issues", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "file3.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + }}, + {Name: "file4.exe", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 111111, Name: "file3.dll", MD5: "hash1", IsIgnored: false, IsThirdParty: false}, + {Id: 222222, Name: "file4.exe", MD5: "hash2", IsIgnored: false, IsThirdParty: false}, + }, + } + + missingDebugSymbols(&mockReport) + + assert.Equal(t, len(mockReport.Issues), 0) + }) + + t.Run("Java with missing debug", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "file3.jar", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {Issues: []string{"No supporting files or PDB files"}}, + }}, + {Name: "file4.war", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {Issues: []string{"No supporting files or PDB files"}}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 111111, Name: "file3.exe", MD5: "hash1", IsIgnored: false, IsThirdParty: false}, + {Id: 222222, Name: "file4.dll", MD5: "hash2", IsIgnored: false, IsThirdParty: false}, + {Id: 111111, Name: "file3.jar", MD5: "hash1", IsIgnored: false, IsThirdParty: false}, + {Id: 222222, Name: "file4.war", MD5: "hash2", IsIgnored: false, IsThirdParty: false}, + }, + Issues: []report.Issue{}, + } + + missingDebugSymbols(&mockReport) + + assert.Equal(t, len(mockReport.Issues), 0) + assert.Equal(t, len(mockReport.Recommendations), 0) + }) + + t.Run("Executables + DLLs with missing debug", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "file3.exe", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {Issues: []string{"No supporting files or PDB files"}}, + }}, + {Name: "file4.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {Issues: []string{"No supporting files or PDB files"}}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 111111, Name: "file3.exe", MD5: "hash1", IsIgnored: false, IsThirdParty: false}, + {Id: 222222, Name: "file4.dll", MD5: "hash2", IsIgnored: false, IsThirdParty: false}, + }, + } + + missingDebugSymbols(&mockReport) + + if !assert.Equal(t, len(mockReport.Issues), 1) { + assert.Contains(t, mockReport.Issues[0].Description, "2 modules") + } + + assert.Equal(t, len(mockReport.Recommendations), 1) + }) +} diff --git a/checks/testing_artefacts_test.go b/checks/testing_artefacts_test.go new file mode 100644 index 0000000..778a746 --- /dev/null +++ b/checks/testing_artefacts_test.go @@ -0,0 +1,142 @@ +package checks + +import ( + "testing" + + "github.com/antfie/scan_health/v2/report" + "github.com/stretchr/testify/assert" +) + +func TestTestingArtefacst(t *testing.T) { + + t.Run("No Testing Artefacts", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "file3.jar", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 333333, Name: "file3.jar", MD5: "hash2", IsIgnored: false}, + }, + } + + testingArtefacts(&mockReport) + + assert.Equal(t, len(mockReport.Issues), 0) + }) + + t.Run("Testing File uploaded", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "file3.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 111111, Name: "Antlr3.Runtime.dll", MD5: "hash1", IsIgnored: false}, + {Id: 222222, Name: "file3.unittests.dll", MD5: "hash2", IsIgnored: false}, + {Id: 222222, Name: "file15.unittest.dll", MD5: "hash2", IsIgnored: false}, + }, + } + + testingArtefacts(&mockReport) + + if !assert.Equal(t, len(mockReport.Issues), 1) { + t.FailNow() + } + + assert.Contains(t, mockReport.Issues[0].Description, "2 testing artefacts") + assert.Equal(t, len(mockReport.Recommendations), 1) + + }) + + t.Run("Testing Module found, not selected", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "moq.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + }}, + {Name: "standalone.unittests.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 111111, Name: "upload.zip", MD5: "hash1", IsIgnored: false}, + }, + } + + testingArtefacts(&mockReport) + + assert.Equal(t, len(mockReport.Issues), 0) + }) + + t.Run("Testing Module found, selected", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "moq.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {IsSelected: true}, + }}, + {Name: "standalone.unittests.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {IsSelected: true}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 111111, Name: "upload.zip", MD5: "hash1", IsIgnored: false}, + }, + } + + testingArtefacts(&mockReport) + + if !assert.Equal(t, len(mockReport.Issues), 1) { + t.FailNow() + } + + assert.Contains(t, mockReport.Issues[0].Description, "2 testing artefacts") + assert.Equal(t, len(mockReport.Recommendations), 2) + }) + + t.Run("Module dependant on testing artefacts", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "MyApp.exe", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {IsSelected: true}, + {Issues: []string{"something including test/dependency.dll"}}, + }}, + {Name: "AnotherApp.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {IsSelected: true}, + {Issues: []string{"something including test/userDependency.dll"}}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 111111, Name: "upload.zip", MD5: "hash1", IsIgnored: false}, + }, + } + + testingArtefacts(&mockReport) + + if !assert.Equal(t, len(mockReport.Issues), 1) { + t.FailNow() + } + + assert.Contains(t, mockReport.Issues[0].Description, "2 modules") + assert.Equal(t, len(mockReport.Recommendations), 1) + }) +} diff --git a/checks/third_party_test.go b/checks/third_party_test.go new file mode 100644 index 0000000..bc3d4f9 --- /dev/null +++ b/checks/third_party_test.go @@ -0,0 +1,95 @@ +package checks + +import ( + "testing" + + "github.com/antfie/scan_health/v2/report" + "github.com/stretchr/testify/assert" +) + +func TestThirdParty(t *testing.T) { + + t.Run("No Third Party", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "file3.jar", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 333333, Name: "file3.jar", MD5: "hash2", IsIgnored: false, IsThirdParty: false}, + }, + } + + thirdParty(&mockReport) + + assert.Equal(t, len(mockReport.Issues), 0) + }) + + t.Run("Third Party uploaded, not selected", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "file3.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + }}, + {Name: "Antlr3.Runtime.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {IsSelected: false}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 111111, Name: "Antlr3.Runtime.dll", MD5: "hash1", IsIgnored: false, IsThirdParty: false}, + {Id: 222222, Name: "file4.exe", MD5: "hash2", IsIgnored: false, IsThirdParty: false}, + }, + } + + thirdParty(&mockReport) + + assert.Equal(t, len(mockReport.Issues), 0) + }) + + t.Run("Third Party uploaded, selected", func(t *testing.T) { + t.Parallel() + mockReport := report.Report{ + Modules: []report.Module{ + {Name: "file3.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + }}, + {Name: "Antlr3.Runtime.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {IsSelected: true}, + }}, + {Name: "DevExpress.Components.dll", + Instances: []report.ModuleInstance{ + {IsDependency: false}, + {IsSelected: true}, + }}, + }, + UploadedFiles: []report.UploadedFile{ + {Id: 111111, Name: "Antlr3.Runtime.dll", MD5: "hash1", IsIgnored: false, IsThirdParty: false}, + {Id: 222222, Name: "file4.exe", MD5: "hash2", IsIgnored: false, IsThirdParty: false}, + {Id: 333333, Name: "DevExpress.Components.dll", MD5: "hash2", IsIgnored: false, IsThirdParty: false}, + }, + } + + thirdParty(&mockReport) + + if !assert.Equal(t, len(mockReport.Issues), 1) { + t.FailNow() + } + + assert.Contains(t, mockReport.Issues[0].Description, "2 third-party components") + + assert.Equal(t, report.IssueSeverityMedium, mockReport.Issues[0].Severity) + assert.Equal(t, len(mockReport.Recommendations), 1) + assert.True(t, mockReport.UploadedFiles[0].IsThirdParty) + assert.True(t, mockReport.UploadedFiles[2].IsThirdParty) + }) +}