Skip to content

Commit

Permalink
Add unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
Sharon Nam authored and Sharon Nam committed Jun 28, 2023
1 parent 83aa83e commit f00857c
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 29 deletions.
61 changes: 32 additions & 29 deletions internal/service/events/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/create"
Expand Down Expand Up @@ -67,7 +66,7 @@ func ResourceRule() *schema.Resource {
ValidateFunc: validateEventPatternValue(),
AtLeastOneOf: []string{"schedule_expression", "event_pattern"},
StateFunc: func(v interface{}) string {
json, _ := jsonMarshal(v.(string))
json, _ := RuleEventPatternJSONDecoder(v.(string))
return json
},
},
Expand Down Expand Up @@ -111,30 +110,6 @@ func ResourceRule() *schema.Resource {
}
}

func jsonMarshal(jsonString interface{}) (string, error) {
var j interface{}

if jsonString == nil || jsonString.(string) == "" {
return "", nil
}

s := jsonString.(string)

err := json.Unmarshal([]byte(s), &j)
if err != nil {
return s, err
}

b, _ := json.Marshal(j)

if bytes.Contains(b, []byte("\\u003c")) || bytes.Contains(b, []byte("\\u003e")) || bytes.Contains(b, []byte("\\u0026")) {
b = bytes.Replace(b, []byte("\\u003c"), []byte("<"), -1)
b = bytes.Replace(b, []byte("\\u003e"), []byte(">"), -1)
b = bytes.Replace(b, []byte("\\u0026"), []byte("&"), -1)
}
return string(b[:]), nil
}

func resourceRuleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).EventsConn(ctx)
Expand Down Expand Up @@ -211,7 +186,7 @@ func resourceRuleRead(ctx context.Context, d *schema.ResourceData, meta interfac
d.Set("description", output.Description)
d.Set("event_bus_name", eventBusName) // Use event bus name from resource ID as API response may collapse any ARN.
if output.EventPattern != nil {
pattern, err := structure.NormalizeJsonString(aws.StringValue(output.EventPattern))
pattern, err := RuleEventPatternJSONDecoder(aws.StringValue(output.EventPattern))
if err != nil {
return sdkdiag.AppendErrorf(diags, "event pattern contains an invalid JSON: %s", err)
}
Expand Down Expand Up @@ -321,6 +296,34 @@ func FindRuleByTwoPartKey(ctx context.Context, conn *eventbridge.EventBridge, ev
return output, nil
}

// Decodes unicode translation of <,>,&
func RuleEventPatternJSONDecoder(jsonString interface{}) (string, error) {
var j interface{}

if jsonString == nil || jsonString.(string) == "" {
return "", nil
}

s := jsonString.(string)

err := json.Unmarshal([]byte(s), &j)
if err != nil {
return s, err
}

b, err := json.Marshal(j)
if err != nil {
return "", err
}

if bytes.Contains(b, []byte("\\u003c")) || bytes.Contains(b, []byte("\\u003e")) || bytes.Contains(b, []byte("\\u0026")) {
b = bytes.Replace(b, []byte("\\u003c"), []byte("<"), -1)
b = bytes.Replace(b, []byte("\\u003e"), []byte(">"), -1)
b = bytes.Replace(b, []byte("\\u0026"), []byte("&"), -1)
}
return string(b[:]), nil
}

func expandPutRuleInput(d *schema.ResourceData, name string) *eventbridge.PutRuleInput {
apiObject := &eventbridge.PutRuleInput{
Name: aws.String(name),
Expand All @@ -335,7 +338,7 @@ func expandPutRuleInput(d *schema.ResourceData, name string) *eventbridge.PutRul
}

if v, ok := d.GetOk("event_pattern"); ok {
json, _ := structure.NormalizeJsonString(v)
json, _ := RuleEventPatternJSONDecoder(v.(string))
apiObject.EventPattern = aws.String(json)
}

Expand All @@ -358,7 +361,7 @@ func expandPutRuleInput(d *schema.ResourceData, name string) *eventbridge.PutRul

func validateEventPatternValue() schema.SchemaValidateFunc {
return func(v interface{}, k string) (ws []string, errors []error) {
json, err := structure.NormalizeJsonString(v)
json, err := RuleEventPatternJSONDecoder(v.(string))
if err != nil {
errors = append(errors, fmt.Errorf("%q contains an invalid JSON: %w", k, err))

Expand Down
36 changes: 36 additions & 0 deletions internal/service/events/rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/eventbridge"
"github.com/google/go-cmp/cmp"
sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
Expand All @@ -29,6 +30,41 @@ func testAccErrorCheckSkip(t *testing.T) resource.ErrorCheckFunc {
)
}

func TestRuleEventPatternJSONDecoder(t *testing.T) {
t.Parallel()

type testCase struct {
input string
expected string
}
tests := map[string]testCase{
"lessThanGreaterThan": {
input: `{"detail": {"count": [ { "numeric": [ "\\u003e", 0, "\\u003c", 5 ] } ]}}`,
expected: `{"detail": {"count": [ { "numeric": [ ">", 0, "<", 5 ] } ]}}`,
},
"ampersand": {
input: `{"detail": {"count": [ { "numeric": [ "\\u0026", 0, "\\u0026", 5 ] } ]}}`,
expected: `{"detail": {"count": [ { "numeric": [ "&", 0, "&", 5 ] } ]}}`,
},
}

for name, test := range tests {
name, test := name, test
t.Run(name, func(t *testing.T) {
t.Parallel()

got, err := tfevents.RuleEventPatternJSONDecoder(test.input)
if err != nil {
t.Fatal(err)
}

if diff := cmp.Diff(got, test.expected); diff != "" {
t.Errorf("unexpected diff (+wanted, -got): %s", diff)
}
})
}
}

func TestAccEventsRule_basic(t *testing.T) {
ctx := acctest.Context(t)
var v1, v2, v3 eventbridge.DescribeRuleOutput
Expand Down

0 comments on commit f00857c

Please sign in to comment.