Skip to content

Commit

Permalink
Merge pull request #38323 from hashicorp/b-pinpoint-app-empty-campaig…
Browse files Browse the repository at this point in the history
…n-hook

resource/aws_pinpoint_app: Fix panic when nested objects are empty
  • Loading branch information
gdavison authored Jul 11, 2024
2 parents 32fcee4 + ec491cd commit 0660f7d
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 13 deletions.
6 changes: 3 additions & 3 deletions internal/service/pinpoint/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ func findAppSettingsByID(ctx context.Context, conn *pinpoint.Pinpoint, id string
}

func expandCampaignHook(configs []interface{}) *pinpoint.CampaignHook {
if len(configs) == 0 {
if len(configs) == 0 || configs[0] == nil {
return nil
}

Expand Down Expand Up @@ -351,7 +351,7 @@ func flattenCampaignHook(ch *pinpoint.CampaignHook) []interface{} {
}

func expandCampaignLimits(configs []interface{}) *pinpoint.CampaignLimits {
if len(configs) == 0 {
if len(configs) == 0 || configs[0] == nil {
return nil
}

Expand Down Expand Up @@ -394,7 +394,7 @@ func flattenCampaignLimits(cl *pinpoint.CampaignLimits) []interface{} {
}

func expandQuietTime(configs []interface{}) *pinpoint.QuietTime {
if len(configs) == 0 {
if len(configs) == 0 || configs[0] == nil {
return nil
}

Expand Down
204 changes: 194 additions & 10 deletions internal/service/pinpoint/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
"github.com/hashicorp/terraform-plugin-testing/statecheck"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tfpinpoint "github.com/hashicorp/terraform-provider-aws/internal/service/pinpoint"
Expand All @@ -38,13 +41,34 @@ func TestAccPinpointApp_basic(t *testing.T) {
testAccCheckAppExists(ctx, resourceName, &application),
resource.TestCheckResourceAttrSet(resourceName, names.AttrApplicationID),
resource.TestCheckResourceAttrSet(resourceName, names.AttrARN),
resource.TestCheckResourceAttr(resourceName, "campaign_hook.#", acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, "limits.#", acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, names.AttrName, rName),
resource.TestCheckResourceAttr(resourceName, names.AttrNamePrefix, ""),
resource.TestCheckResourceAttr(resourceName, "quiet_time.#", acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct0),
),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("campaign_hook"), knownvalue.ListExact([]knownvalue.Check{
knownvalue.ObjectExact(map[string]knownvalue.Check{
"lambda_function_name": knownvalue.StringExact(""),
names.AttrMode: knownvalue.StringExact(""),
"web_url": knownvalue.StringExact(""),
}),
})),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("limits"), knownvalue.ListExact([]knownvalue.Check{
knownvalue.ObjectExact(map[string]knownvalue.Check{
"daily": knownvalue.Int64Exact(0),
"maximum_duration": knownvalue.Int64Exact(0),
"messages_per_second": knownvalue.Int64Exact(0),
"total": knownvalue.Int64Exact(0),
}),
})),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("quiet_time"), knownvalue.ListExact([]knownvalue.Check{
knownvalue.ObjectExact(map[string]knownvalue.Check{
"end": knownvalue.StringExact(""),
"start": knownvalue.StringExact(""),
}),
})),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.Null()),
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTagsAll), knownvalue.MapExact(map[string]knownvalue.Check{})),
},
},
{
ResourceName: resourceName,
Expand Down Expand Up @@ -187,9 +211,53 @@ func TestAccPinpointApp_campaignHookLambda(t *testing.T) {
Config: testAccAppConfig_campaignHookLambda(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAppExists(ctx, resourceName, &application),
resource.TestCheckResourceAttr(resourceName, "campaign_hook.#", acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, "campaign_hook.0.mode", "DELIVERY"),
resource.TestCheckResourceAttrPair(resourceName, "campaign_hook.0.lambda_function_name", "aws_lambda_function.test", names.AttrARN),
),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("campaign_hook"), knownvalue.ListExact([]knownvalue.Check{
knownvalue.ObjectExact(map[string]knownvalue.Check{
"lambda_function_name": knownvalue.NotNull(), // Should be a Pair function, waiting on https://github.com/hashicorp/terraform-plugin-testing/pull/330
names.AttrMode: knownvalue.StringExact(pinpoint.ModeDelivery),
"web_url": knownvalue.StringExact(""),
}),
})),
},
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccPinpointApp_campaignHookEmpty(t *testing.T) {
ctx := acctest.Context(t)
var application pinpoint.ApplicationResponse
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_pinpoint_app.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckApp(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.PinpointServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckAppDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccAppConfig_campaignHookEmpty(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAppExists(ctx, resourceName, &application),
),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("campaign_hook"), knownvalue.ListExact([]knownvalue.Check{
knownvalue.ObjectExact(map[string]knownvalue.Check{
"lambda_function_name": knownvalue.StringExact(""),
names.AttrMode: knownvalue.StringExact(""),
"web_url": knownvalue.StringExact(""),
}),
})),
},
},
{
ResourceName: resourceName,
Expand All @@ -216,9 +284,54 @@ func TestAccPinpointApp_limits(t *testing.T) {
Config: testAccAppConfig_limits(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAppExists(ctx, resourceName, &application),
resource.TestCheckResourceAttr(resourceName, "limits.#", acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, "limits.0.total", "100"),
),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("limits"), knownvalue.ListExact([]knownvalue.Check{
knownvalue.ObjectExact(map[string]knownvalue.Check{
"daily": knownvalue.Int64Exact(3),
"maximum_duration": knownvalue.Int64Exact(600),
"messages_per_second": knownvalue.Int64Exact(50),
"total": knownvalue.Int64Exact(100),
}),
})),
},
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccPinpointApp_limitsEmpty(t *testing.T) {
ctx := acctest.Context(t)
var application pinpoint.ApplicationResponse
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_pinpoint_app.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckApp(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.PinpointServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckAppDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccAppConfig_limitsEmpty(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAppExists(ctx, resourceName, &application),
),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("limits"), knownvalue.ListExact([]knownvalue.Check{
knownvalue.ObjectExact(map[string]knownvalue.Check{
"daily": knownvalue.Int64Exact(0),
"maximum_duration": knownvalue.Int64Exact(0),
"messages_per_second": knownvalue.Int64Exact(0),
"total": knownvalue.Int64Exact(0),
}),
})),
},
},
{
ResourceName: resourceName,
Expand All @@ -245,9 +358,50 @@ func TestAccPinpointApp_quietTime(t *testing.T) {
Config: testAccAppConfig_quietTime(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAppExists(ctx, resourceName, &application),
resource.TestCheckResourceAttr(resourceName, "quiet_time.#", acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, "quiet_time.0.start", "00:00"),
),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("quiet_time"), knownvalue.ListExact([]knownvalue.Check{
knownvalue.ObjectExact(map[string]knownvalue.Check{
"end": knownvalue.StringExact("03:00"),
"start": knownvalue.StringExact("00:00"),
}),
})),
},
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccPinpointApp_quietTimeEmpty(t *testing.T) {
ctx := acctest.Context(t)
var application pinpoint.ApplicationResponse
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_pinpoint_app.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckApp(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.PinpointServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckAppDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccAppConfig_quietTimeEmpty(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAppExists(ctx, resourceName, &application),
),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("quiet_time"), knownvalue.ListExact([]knownvalue.Check{
knownvalue.ObjectExact(map[string]knownvalue.Check{
"end": knownvalue.StringExact(""),
"start": knownvalue.StringExact(""),
}),
})),
},
},
{
ResourceName: resourceName,
Expand Down Expand Up @@ -415,6 +569,16 @@ resource "aws_lambda_permission" "test" {
`, rName)
}

func testAccAppConfig_campaignHookEmpty(rName string) string {
return fmt.Sprintf(`
resource "aws_pinpoint_app" "test" {
name = %[1]q
campaign_hook {}
}
`, rName)
}

func testAccAppConfig_limits(rName string) string {
return fmt.Sprintf(`
resource "aws_pinpoint_app" "test" {
Expand All @@ -430,6 +594,16 @@ resource "aws_pinpoint_app" "test" {
`, rName)
}

func testAccAppConfig_limitsEmpty(rName string) string {
return fmt.Sprintf(`
resource "aws_pinpoint_app" "test" {
name = %[1]q
limits {}
}
`, rName)
}

func testAccAppConfig_quietTime(rName string) string {
return fmt.Sprintf(`
resource "aws_pinpoint_app" "test" {
Expand All @@ -442,3 +616,13 @@ resource "aws_pinpoint_app" "test" {
}
`, rName)
}

func testAccAppConfig_quietTimeEmpty(rName string) string {
return fmt.Sprintf(`
resource "aws_pinpoint_app" "test" {
name = %[1]q
quiet_time {}
}
`, rName)
}

0 comments on commit 0660f7d

Please sign in to comment.