Skip to content

Commit

Permalink
test: create cases for omitempty and stripepmtyentries
Browse files Browse the repository at this point in the history
  • Loading branch information
ddlees committed Dec 11, 2023
1 parent 7700807 commit 765eb05
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 2 deletions.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/spf13/cobra v1.3.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.10.1
github.com/stretchr/testify v1.7.0
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a
go.uber.org/mock v0.2.0
golang.org/x/net v0.17.0
Expand All @@ -20,12 +21,14 @@ require (

require (
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
Expand All @@ -34,4 +37,5 @@ require (
golang.org/x/text v0.13.0 // indirect
gopkg.in/ini.v1 v1.66.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
3 changes: 1 addition & 2 deletions models/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ func StripEmptyEntries(data map[string]any) {
for _, item := range slice {
if mapValue, ok := item.(map[string]any); ok {
StripEmptyEntries(mapValue)
} else {
data[key] = append(data[key].([]any), item)
}
data[key] = append(data[key].([]any), item)
}
} else {
data[key] = value
Expand Down
207 changes: 207 additions & 0 deletions models/utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
package models_test

import (
"encoding/json"
"fmt"
"testing"

"github.com/bloodhoundad/azurehound/v2/models"
"github.com/stretchr/testify/require"
)

type Foo struct {
Bar string
}

func TestStripEmptyEntries(t *testing.T) {
t.Run("should omit empty basic types", func(t *testing.T) {
var pointer *Foo

data := map[string]any{
"array": [0]any{},
"map": map[string]any{},
"slice": []any{},
"string": "",
"bool": false,
"float32": float32(0),
"float64": float64(0),
"int": int(0),
"int8": int8(0),
"int16": int16(0),
"int32": int32(0),
"int64": int64(0),
"uint": uint(0),
"uint8": uint8(0),
"uint16": uint16(0),
"uint32": uint32(0),
"uint64": uint64(0),
"pointer": pointer,
"nil": nil,
}

require.NotEmpty(t, data)
models.StripEmptyEntries(data)
require.Empty(t, data)
})

t.Run("should not omit non-empty basic types", func(t *testing.T) {
data := map[string]any{
"array": [1]any{1},
"map": map[any]any{"foo": "bar"},
"slice": []any{1},
"string": "foo",
"bool": true,
"float32": float32(1),
"float64": float64(1),
"int": int(1),
"int8": int8(1),
"int16": int16(1),
"int32": int32(1),
"int64": int64(1),
"uint": uint(1),
"uint8": uint8(1),
"uint16": uint16(1),
"uint32": uint32(1),
"uint64": uint64(1),
"pointer": &Foo{},
}

require.NotEmpty(t, data)
numKeys := len(data)
models.StripEmptyEntries(data)
require.NotEmpty(t, data)
require.Equal(t, numKeys, len(data))
})

t.Run("should not omit empty struct types", func(t *testing.T) {
data := map[string]any{
"struct": Foo{Bar: "baz"},
}

require.NotEmpty(t, data)
numKeys := len(data)
models.StripEmptyEntries(data)
require.NotEmpty(t, data)
require.Equal(t, numKeys, len(data))
require.NotEmpty(t, data["struct"])
require.Equal(t, data["struct"].(Foo).Bar, "baz")
})

t.Run("should recursively strip non-empty, nested map[string]any entries", func(t *testing.T) {
data := map[string]any{
"empty": map[string]any{},
"nonempty": map[string]any{
"emptyprop": 0,
"nonemptyprop": 1,
},
}

models.StripEmptyEntries(data)
require.Nil(t, data["empty"])
require.NotNil(t, data["nonempty"])
require.IsType(t, map[string]any{}, data["nonempty"])
nested := data["nonempty"].(map[string]any)
require.Equal(t, 1, len(nested))
require.Nil(t, nested["emptyprop"])
require.Equal(t, 1, nested["nonemptyprop"])
})

t.Run("should strip non-empty slice entries of type map[string]any", func(t *testing.T) {
data := map[string]any{
"empty": []any{},
"nonempty": []any{
map[string]any{
"emptyprop": 0,
"nonemptyprop": 1,
},
},
}

fmt.Println(data["nonempty"])
models.StripEmptyEntries(data)
require.Nil(t, data["empty"])
require.NotNil(t, data["nonempty"])
require.IsType(t, []any{}, data["nonempty"])
slice := data["nonempty"].([]any)
fmt.Println(slice)
require.IsType(t, map[string]any{}, slice[0])
entry := slice[0].(map[string]any)
require.Nil(t, entry["emptyprop"])
require.Equal(t, 1, entry["nonemptyprop"])
})
}

func TestOmitEmpty(t *testing.T) {
t.Run("should omit empty basic types", func(t *testing.T) {
data := json.RawMessage(`{
"string": "",
"number": 0,
"object": {},
"array": [],
"boolean": false,
"null": null
}`)

filtered, err := models.OmitEmpty(data)
require.Nil(t, err)
require.Equal(t, `{}`, string(filtered))
})

t.Run("should not omit non-empty basic types", func(t *testing.T) {
data := json.RawMessage(`{
"string": "foo",
"number": 1,
"object": { "bar": "" },
"array": [1],
"boolean": true
}`)

filtered, err := models.OmitEmpty(data)
require.Nil(t, err)
require.Equal(t, `{"array":[1],"boolean":true,"number":1,"object":{},"string":"foo"}`, string(filtered))
})

t.Run("should not omit empty struct/object types, just their empty properties", func(t *testing.T) {
data := json.RawMessage(`{
"object": { "bar": "" }
}`)

filtered, err := models.OmitEmpty(data)
require.Nil(t, err)
require.Equal(t, `{"object":{}}`, string(filtered))
})

t.Run("should recursively strip non-empty, nested object entries", func(t *testing.T) {
data := json.RawMessage(`{
"empty": {},
"nonempty": {
"emptyprop": 0,
"nonemptyprop": 1
}
}`)

filtered, err := models.OmitEmpty(data)
require.Nil(t, err)
require.Equal(t, `{"nonempty":{"nonemptyprop":1}}`, string(filtered))
})

t.Run("should strip non-empty array entries of type object", func(t *testing.T) {
data := json.RawMessage(`{
"empty": [],
"nonempty": [{
"emptyprop": 0,
"nonemptyprop": 1
}]
}`)

filtered, err := models.OmitEmpty(data)
require.Nil(t, err)
require.Equal(t, `{"nonempty":[{"nonemptyprop":1}]}`, string(filtered))
})

t.Run("should return an error", func(t *testing.T) {
invalidJson := json.RawMessage(`{]}`)
_, err := models.OmitEmpty(invalidJson)
require.Error(t, err)
})
}

0 comments on commit 765eb05

Please sign in to comment.