From a513c27dce125efc54efc1486aaaa25ff9fe71ed Mon Sep 17 00:00:00 2001 From: sulemaanhamza Date: Thu, 23 Nov 2023 11:01:13 +0500 Subject: [PATCH 1/2] Possible bug fix to prevent index out of range error in case of malformed policies + test case for edge cases Signed-off-by: sulemaanhamza --- core/core/list.go | 14 +++++++++++++- core/core/list_test.go | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/core/core/list.go b/core/core/list.go index d00a2376..7a65d1ef 100644 --- a/core/core/list.go +++ b/core/core/list.go @@ -159,8 +159,20 @@ func generateControlRows(policies []string) [][]string { rows := [][]string{} for _, control := range policies { + idAndControlAndFrameworks := strings.Split(control, "|") - id, control, framework := idAndControlAndFrameworks[0], idAndControlAndFrameworks[1], idAndControlAndFrameworks[2] + + var id, control, framework string + + if len(idAndControlAndFrameworks) == 0 { + continue + } else if len(idAndControlAndFrameworks) == 1 { + id = idAndControlAndFrameworks[0] + } else if len(idAndControlAndFrameworks) == 2 { + id, control = idAndControlAndFrameworks[0], idAndControlAndFrameworks[1] + } else if len(idAndControlAndFrameworks) > 2 { + id, control, framework = idAndControlAndFrameworks[0], idAndControlAndFrameworks[1], idAndControlAndFrameworks[2] + } docs := cautils.GetControlLink(id) diff --git a/core/core/list_test.go b/core/core/list_test.go index d309eb63..0839a691 100644 --- a/core/core/list_test.go +++ b/core/core/list_test.go @@ -201,6 +201,27 @@ func TestGenerateControlRowsWithAllFields(t *testing.T) { assert.Equal(t, want, got) } +// Handles policies with no '|' characters in the string +func TestGenerateControlRowsHandlesPoliciesWithEmptyStringOrNoPipesOrOnePipeMissing(t *testing.T) { + policies := []string{ + "", + "1", + "2|Control 2", + "3", + } + + expectedRows := [][]string{ + {"", "", "https://hub.armosec.io/docs/", ""}, + {"1", "", "https://hub.armosec.io/docs/1", ""}, + {"2", "Control 2", "https://hub.armosec.io/docs/2", ""}, + {"3", "", "https://hub.armosec.io/docs/3", ""}, + } + + rows := generateControlRows(policies) + + assert.Equal(t, expectedRows, rows) +} + // The function generates a table with the correct headers and rows based on the input policies. func TestGenerateTableWithCorrectHeadersAndRows(t *testing.T) { // Arrange From bc2fc83599cab6db74c1013be2581d5e5c1e00c2 Mon Sep 17 00:00:00 2001 From: sulemaanhamza Date: Thu, 23 Nov 2023 13:15:31 +0500 Subject: [PATCH 2/2] Enhanced policies list to cover multiple edge-cases + Added new test-case with table-like structure to test pretty print of rows Signed-off-by: sulemaanhamza --- core/core/list.go | 9 +++--- core/core/list_test.go | 64 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/core/core/list.go b/core/core/list.go index 7a65d1ef..9818e7a2 100644 --- a/core/core/list.go +++ b/core/core/list.go @@ -164,13 +164,14 @@ func generateControlRows(policies []string) [][]string { var id, control, framework string - if len(idAndControlAndFrameworks) == 0 { + switch len(idAndControlAndFrameworks) { + case 0: continue - } else if len(idAndControlAndFrameworks) == 1 { + case 1: id = idAndControlAndFrameworks[0] - } else if len(idAndControlAndFrameworks) == 2 { + case 2: id, control = idAndControlAndFrameworks[0], idAndControlAndFrameworks[1] - } else if len(idAndControlAndFrameworks) > 2 { + default: id, control, framework = idAndControlAndFrameworks[0], idAndControlAndFrameworks[1], idAndControlAndFrameworks[2] } diff --git a/core/core/list_test.go b/core/core/list_test.go index 0839a691..81ead3c3 100644 --- a/core/core/list_test.go +++ b/core/core/list_test.go @@ -206,15 +206,21 @@ func TestGenerateControlRowsHandlesPoliciesWithEmptyStringOrNoPipesOrOnePipeMiss policies := []string{ "", "1", - "2|Control 2", - "3", + "2|Control 2|Framework 2", + "3|Control 3|Framework 3|Extra 3", + "4||Framework 4", + "|", + "5|Control 5||Extra 5", } expectedRows := [][]string{ {"", "", "https://hub.armosec.io/docs/", ""}, {"1", "", "https://hub.armosec.io/docs/1", ""}, - {"2", "Control 2", "https://hub.armosec.io/docs/2", ""}, - {"3", "", "https://hub.armosec.io/docs/3", ""}, + {"2", "Control 2", "https://hub.armosec.io/docs/2", "Framework\n2"}, + {"3", "Control 3", "https://hub.armosec.io/docs/3", "Framework\n3"}, + {"4", "", "https://hub.armosec.io/docs/4", "Framework\n4"}, + {"", "", "https://hub.armosec.io/docs/", ""}, + {"5", "Control 5", "https://hub.armosec.io/docs/5", ""}, } rows := generateControlRows(policies) @@ -261,6 +267,56 @@ func TestGenerateTableWithCorrectHeadersAndRows(t *testing.T) { assert.Equal(t, want, string(got)) } +func TestGenerateTableWithMalformedPoliciesAndPrettyPrintHeadersAndRows(t *testing.T) { + // Arrange + ctx := context.Background() + policies := []string{ + "", + "1", + "2|Control 2|Framework 2", + "3|Control 3|Framework 3|Extra 3", + "4||Framework 4", + "|", + "5|Control 5||Extra 5", + } + + // Redirect stdout to a buffer + rescueStdout := os.Stdout + r, w, _ := os.Pipe() + os.Stdout = w + + prettyPrintControls(ctx, policies) + + w.Close() + got, _ := io.ReadAll(r) + + os.Stdout = rescueStdout + + want := `┌────────────┬──────────────┬───────────────────────────────┬────────────┐ +│ Control ID │ Control name │ Docs │ Frameworks │ +├────────────┼──────────────┼───────────────────────────────┼────────────┤ +│ │ │ https://hub.armosec.io/docs/ │ │ +├────────────┼──────────────┼───────────────────────────────┼────────────┤ +│ 1 │ │ https://hub.armosec.io/docs/1 │ │ +├────────────┼──────────────┼───────────────────────────────┼────────────┤ +│ 2 │ Control 2 │ https://hub.armosec.io/docs/2 │ Framework │ +│ │ │ │ 2 │ +├────────────┼──────────────┼───────────────────────────────┼────────────┤ +│ 3 │ Control 3 │ https://hub.armosec.io/docs/3 │ Framework │ +│ │ │ │ 3 │ +├────────────┼──────────────┼───────────────────────────────┼────────────┤ +│ 4 │ │ https://hub.armosec.io/docs/4 │ Framework │ +│ │ │ │ 4 │ +├────────────┼──────────────┼───────────────────────────────┼────────────┤ +│ │ │ https://hub.armosec.io/docs/ │ │ +├────────────┼──────────────┼───────────────────────────────┼────────────┤ +│ 5 │ Control 5 │ https://hub.armosec.io/docs/5 │ │ +└────────────┴──────────────┴───────────────────────────────┴────────────┘ +` + + assert.Equal(t, want, string(got)) +} + // Returns a non-empty list of supported actions when 'ListSupportActions' is called. func TestListSupportActionsNotEmpty(t *testing.T) { actions := ListSupportActions()