Skip to content

Commit d7fa170

Browse files
Added Unit Tests
1 parent 2b90300 commit d7fa170

File tree

2 files changed

+159
-23
lines changed

2 files changed

+159
-23
lines changed

lib/reporting/report_test.go

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package reporting
22

33
import (
4+
"bytes"
45
"encoding/json"
56
"os"
67
"path/filepath"
@@ -12,6 +13,7 @@ import (
1213
"github.com/checkmarx/2ms/lib/config"
1314
"github.com/checkmarx/2ms/lib/secrets"
1415
"github.com/stretchr/testify/assert"
16+
"gopkg.in/yaml.v3"
1517
)
1618

1719
// test input results
@@ -334,3 +336,142 @@ func SortResults(results1, results2 []Results) {
334336
return results2[i].Message.Text < results2[j].Message.Text
335337
})
336338
}
339+
340+
func TestGetOutputYAML(t *testing.T) {
341+
testCases := []struct {
342+
name string
343+
report Report
344+
}{
345+
{
346+
name: "Single real secret in hardcodedPassword.go",
347+
report: Report{
348+
TotalItemsScanned: 1,
349+
TotalSecretsFound: 1,
350+
Results: map[string][]*secrets.Secret{
351+
"c6490d749fd4670fde969011d99ea5c4c4b1c0d7": {
352+
{
353+
ID: "c6490d749fd4670fde969011d99ea5c4c4b1c0d7",
354+
Source: "..\\2ms\\engine\\rules\\hardcodedPassword.go",
355+
RuleID: "generic-api-key",
356+
StartLine: 45,
357+
EndLine: 45,
358+
LineContent: "value",
359+
StartColumn: 8,
360+
EndColumn: 64,
361+
Value: "value",
362+
ValidationStatus: "",
363+
CvssScore: 8.2,
364+
RuleDescription: "Detected a Generic API Key, potentially exposing access to various services and sensitive operations.",
365+
},
366+
},
367+
},
368+
},
369+
},
370+
{
371+
name: "Multiple real JWT secrets in jwt.txt",
372+
report: Report{
373+
TotalItemsScanned: 2,
374+
TotalSecretsFound: 2,
375+
Results: map[string][]*secrets.Secret{
376+
"12fd8706491196cbfbdddd2fdcd650ed842dd963": {
377+
{
378+
ID: "12fd8706491196cbfbdddd2fdcd650ed842dd963",
379+
Source: "..\\2ms\\pkg\\testData\\secrets\\jwt.txt",
380+
RuleID: "jwt",
381+
StartLine: 1,
382+
EndLine: 1,
383+
LineContent: "line content",
384+
StartColumn: 129,
385+
EndColumn: 232,
386+
Value: "value",
387+
ValidationStatus: "",
388+
CvssScore: 8.2,
389+
RuleDescription: "Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.",
390+
ExtraDetails: map[string]interface{}{
391+
"secretDetails": map[string]string{
392+
"name": "mockName2",
393+
"sub": "mockSub2",
394+
},
395+
},
396+
},
397+
{
398+
ID: "12fd8706491196cbfbdddd2fdcd650ed842dd963",
399+
Source: "..\\2ms\\pkg\\testData\\secrets\\jwt.txt",
400+
RuleID: "jwt",
401+
StartLine: 2,
402+
EndLine: 2,
403+
LineContent: "line Content",
404+
StartColumn: 64,
405+
EndColumn: 166,
406+
Value: "value",
407+
ValidationStatus: "",
408+
CvssScore: 8.2,
409+
RuleDescription: "Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.",
410+
ExtraDetails: map[string]interface{}{
411+
"secretDetails": map[string]string{
412+
"name": "mockName2",
413+
"sub": "mockSub2",
414+
},
415+
},
416+
},
417+
},
418+
},
419+
},
420+
},
421+
}
422+
423+
for _, tc := range testCases {
424+
t.Run(tc.name, func(t *testing.T) {
425+
output, err := tc.report.GetOutput("yaml", &config.Config{Name: "report", Version: "1"})
426+
assert.NoError(t, err)
427+
428+
var report Report
429+
err = yaml.Unmarshal([]byte(output), &report)
430+
assert.NoError(t, err)
431+
432+
assert.Equal(t, tc.report.TotalItemsScanned, report.TotalItemsScanned)
433+
assert.Equal(t, tc.report.TotalSecretsFound, report.TotalSecretsFound)
434+
435+
for key, expectedSecretsList := range tc.report.Results {
436+
actualSecretsList, exists := report.Results[key]
437+
if !exists {
438+
t.Errorf("Key %s not found in actual report results", key)
439+
continue
440+
}
441+
442+
for i, expectedSecret := range expectedSecretsList {
443+
actualSecret := actualSecretsList[i]
444+
445+
assert.Equal(t, expectedSecret.ID, actualSecret.ID, "Mismatch in ID for key %s at index %d", key, i)
446+
assert.Equal(t, expectedSecret.Source, actualSecret.Source, "Mismatch in Source for key %s at index %d", key, i)
447+
assert.Equal(t, expectedSecret.RuleID, actualSecret.RuleID, "Mismatch in RuleID for key %s at index %d", key, i)
448+
assert.Equal(t, expectedSecret.StartLine, actualSecret.StartLine, "Mismatch in StartLine for key %s at index %d", key, i)
449+
assert.Equal(t, expectedSecret.EndLine, actualSecret.EndLine, "Mismatch in EndLine for key %s at index %d", key, i)
450+
assert.Equal(t, expectedSecret.LineContent, actualSecret.LineContent, "Mismatch in LineContent for key %s at index %d", key, i)
451+
assert.Equal(t, expectedSecret.StartColumn, actualSecret.StartColumn, "Mismatch in StartColumn for key %s at index %d", key, i)
452+
assert.Equal(t, expectedSecret.EndColumn, actualSecret.EndColumn, "Mismatch in EndColumn for key %s at index %d", key, i)
453+
assert.Equal(t, expectedSecret.Value, actualSecret.Value, "Mismatch in Value for key %s at index %d", key, i)
454+
assert.Equal(t, expectedSecret.ValidationStatus, actualSecret.ValidationStatus, "Mismatch in ValidationStatus for key %s at index %d", key, i)
455+
assert.Equal(t, expectedSecret.RuleDescription, actualSecret.RuleDescription, "Mismatch in RuleDescription for key %s at index %d", key, i)
456+
assert.Equal(t, expectedSecret.CvssScore, actualSecret.CvssScore, "Mismatch in CvssScore for key %s at index %d", key, i)
457+
458+
expectedYAML, err := yaml.Marshal(expectedSecret.ExtraDetails)
459+
if err != nil {
460+
t.Errorf("Error serializing %s at index %d: %v", key, i, err)
461+
continue
462+
}
463+
464+
actualYAML, err := yaml.Marshal(actualSecret.ExtraDetails)
465+
if err != nil {
466+
t.Errorf("Error %s at index %d: %v", key, i, err)
467+
continue
468+
}
469+
470+
if !bytes.Equal(expectedYAML, actualYAML) {
471+
t.Errorf("Mismatch in ExtraDetails for key %s at index %d:\nExpected:\n%s\nGot:\n%s", key, i, expectedYAML, actualYAML)
472+
}
473+
}
474+
}
475+
})
476+
}
477+
}

lib/reporting/yaml.go

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ package reporting
22

33
import (
44
"fmt"
5-
"sort"
65
"strings"
76

8-
"github.com/checkmarx/2ms/lib/secrets"
7+
"gopkg.in/yaml.v3"
98
)
109

1110
func writeYaml(report *Report) (string, error) {
@@ -15,39 +14,35 @@ func writeYaml(report *Report) (string, error) {
1514
builder.WriteString(fmt.Sprintf("totalsecretsfound: %d\n", report.TotalSecretsFound))
1615
builder.WriteString("results:\n")
1716

18-
groupedByID := make(map[string][]*secrets.Secret)
19-
for _, secretList := range report.Results {
20-
for _, s := range secretList {
21-
groupedByID[s.ID] = append(groupedByID[s.ID], s)
17+
for _, secretsList := range report.Results {
18+
if len(secretsList) > 0 {
19+
builder.WriteString(fmt.Sprintf(" %s:\n", secretsList[0].ID))
2220
}
23-
}
24-
25-
ids := make([]string, 0, len(groupedByID))
26-
for id := range groupedByID {
27-
ids = append(ids, id)
28-
}
29-
sort.Strings(ids)
30-
31-
for _, id := range ids {
32-
builder.WriteString(fmt.Sprintf(" %s:\n", id))
33-
for _, s := range groupedByID[id] {
21+
for _, s := range secretsList {
3422
builder.WriteString(" - id: " + s.ID + "\n")
3523
builder.WriteString(" source: " + s.Source + "\n")
3624
builder.WriteString(" ruleid: " + s.RuleID + "\n")
3725
builder.WriteString(fmt.Sprintf(" startline: %d\n", s.StartLine))
3826
builder.WriteString(fmt.Sprintf(" endline: %d\n", s.EndLine))
39-
4027
builder.WriteString(fmt.Sprintf(" linecontent: %q\n", s.LineContent))
4128
builder.WriteString(fmt.Sprintf(" startcolumn: %d\n", s.StartColumn))
4229
builder.WriteString(fmt.Sprintf(" endcolumn: %d\n", s.EndColumn))
4330
builder.WriteString(" value: " + s.Value + "\n")
44-
4531
builder.WriteString(fmt.Sprintf(" validationstatus: %q\n", fmt.Sprintf("%v", s.ValidationStatus)))
4632
builder.WriteString(" ruledescription: " + s.RuleDescription + "\n")
47-
if len(s.ExtraDetails) == 0 {
48-
builder.WriteString(" extradetails: {}\n")
49-
} else {
50-
builder.WriteString(fmt.Sprintf(" extradetails: %v\n", s.ExtraDetails))
33+
if len(s.ExtraDetails) > 0 {
34+
builder.WriteString(" extradetails:\n")
35+
marshaled, err := yaml.Marshal(s.ExtraDetails)
36+
if err != nil {
37+
builder.WriteString(fmt.Sprintf(" error: %v\n", err))
38+
} else {
39+
lines := strings.Split(string(marshaled), "\n")
40+
for _, line := range lines {
41+
if line != "" {
42+
builder.WriteString(" " + line + "\n")
43+
}
44+
}
45+
}
5146
}
5247
builder.WriteString(fmt.Sprintf(" cvssscore: %.1f\n", s.CvssScore))
5348
}

0 commit comments

Comments
 (0)