Skip to content

Commit

Permalink
fix: bug when flattening a field with type *string containing a valid… (
Browse files Browse the repository at this point in the history
#18)

* fix: bug when flattening a field with type *string containing a valid substructure like a JSON (e.g. the AWS policies)

* fix: lint
  • Loading branch information
notdodo authored Apr 27, 2024
1 parent cf79a34 commit 299d9d9
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 23 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/go-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@ on:
- "**.go"
- "go.mod"
- "go.sum"
- ".github/workflows/go-ci.yml"
pull_request:
paths:
- "**.go"
- "go.mod"
- "go.sum"
- ".github/workflows/go-ci.yml"

concurrency:
group: goflat-go-ci-${{ github.ref }}
cancel-in-progress: true

jobs:
sast:
uses: notdodo/github-actions/.github/workflows/go-security-scan.yml@2e84638563b65587b42ba8ab87ccdf1922c412dd
# go-sec-v0.0.0
uses: notdodo/github-actions/.github/workflows/go-security-scan.yml@go-sec-v0

build-and-test:
uses: notdodo/github-actions/.github/workflows/go-ci.yml@2e84638563b65587b42ba8ab87ccdf1922c412dd
# go-ci-v0.0.0
uses: notdodo/github-actions/.github/workflows/go-ci.yml@go-ci-v0
24 changes: 20 additions & 4 deletions goflat.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ type FlattenerConfig struct {
}

// `DefaultFlattenerConfig` returns a FlattenerConfig with default values.
func defaultConfiguration(config ...FlattenerConfig) FlattenerConfig {
func defaultConfiguration() FlattenerConfig {
return FlattenerConfig{
Prefix: "",
Separator: ".",
OmitEmpty: false,
OmitNil: false,
OmitEmpty: true,
OmitNil: true,
SortKeys: false,
KeysToLower: false,
}
Expand Down Expand Up @@ -206,7 +206,14 @@ func flattenFields(val reflect.Value, prefix string, result map[string]interface
// If the value is neither a struct nor a map, add it to the result map.
// Optionally omitting empty or nil values based on the configuration.
if !(config.OmitEmpty && isEmptyValue(val)) && !(config.OmitNil && isNilValue(val)) {
result[prefix[:len(prefix)-1]] = val.Interface()
prefix = prefix[:len(prefix)-1]
// If `val` is a valid JSON likely this was *string; flat it
if js := isJSON(val.String()); js != nil {
flatMap, _ := FlatJSONToMap(val.String(), config)
flatten(prefix, flatMap, result, config)
} else {
result[prefix] = val.Interface()
}
}
}
}
Expand Down Expand Up @@ -260,3 +267,12 @@ func isNilValue(field reflect.Value) bool {
// Check if the field is a pointer and is nil.
return field.Kind() == reflect.Ptr && field.IsNil()
}

// `jsJSON` checks if a string it's a valid JSON string.
func isJSON(str string) json.RawMessage {
var js json.RawMessage
if err := json.Unmarshal([]byte(str), &js); err != nil {
return nil
}
return js
}
51 changes: 36 additions & 15 deletions goflat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ type User struct {
}

type Member struct {
User *User
Role string
Active bool
User *User
Role string
Active bool
SubField *string
}

type Group struct {
Expand Down Expand Up @@ -94,8 +95,24 @@ func TestIsEmptyValue(t *testing.T) {
}

func TestFlattenStructWithArrayOfPointersInGroup(t *testing.T) {
s := `[{
"PolicyName": "policy-s3-operator",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::personal-s3-bucket/*"
]
}
]
}]`

members := []*Member{
{User: &User{Username: "john_doe", Email: "john@example.com"}, Role: "Admin", Active: true},
{User: &User{Username: "john_doe", Email: "john@example.com"}, Role: "Admin", Active: true, SubField: &s},
{User: &User{Username: "jane_doe", Email: "jane@example.com"}, Role: "User", Active: false},
}
group := Group{Name: "Admins", Members: members}
Expand All @@ -108,20 +125,24 @@ func TestFlattenStructWithArrayOfPointersInGroup(t *testing.T) {
})

expectedMap := map[string]interface{}{
"Name": "Admins",
"Members.0.User.Username": "john_doe",
"Members.0.User.Email": "john@example.com",
"Members.0.Role": "Admin",
"Members.0.Active": true,
"Members.1.User.Username": "jane_doe",
"Members.1.User.Email": "jane@example.com",
"Members.1.Role": "User",
"Members.1.Active": false,
"Name": "Admins",
"Members.0.User.Username": "john_doe",
"Members.0.User.Email": "john@example.com",
"Members.0.Role": "Admin",
"Members.0.Active": true,
"Members.1.User.Username": "jane_doe",
"Members.1.User.Email": "jane@example.com",
"Members.1.Role": "User",
"Members.1.Active": false,
"Members.0.SubField.0.PolicyName": "policy-s3-operator",
"Members.0.SubField.0.Statement.0.Effect": "Allow",
"Members.0.SubField.0.Statement.0.Action.0": "s3:PutObject",
"Members.0.SubField.0.Statement.0.Action.1": "s3:GetObject",
"Members.0.SubField.0.Statement.0.Resource.0": "arn:aws:s3:::personal-s3-bucket/*",
}

if !reflect.DeepEqual(flattenedMap, expectedMap) {
fmt.Println(flattenedMap)
fmt.Println(expectedMap)
fmt.Println(diff.Diff(flattenedMap, expectedMap))
t.Errorf("Flattened result does not match the expected map. Got: %+v, Expected: %+v", flattenedMap, expectedMap)
}
}
Expand Down

0 comments on commit 299d9d9

Please sign in to comment.