From d5e41386ea2317c1865d092092b9216513e8e95c Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Wed, 10 Jul 2024 14:18:18 -0700 Subject: [PATCH 1/5] Uses `ConfigStateChecks` for `campaign_hook` --- internal/service/pinpoint/app_test.go | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/internal/service/pinpoint/app_test.go b/internal/service/pinpoint/app_test.go index 6540916a673..57953a00677 100644 --- a/internal/service/pinpoint/app_test.go +++ b/internal/service/pinpoint/app_test.go @@ -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" @@ -38,13 +41,21 @@ 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(""), + }), + })), + }, }, { ResourceName: resourceName, @@ -187,9 +198,17 @@ 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, From a9368d975f5e7517dc7530cec86e62556f164768 Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Wed, 10 Jul 2024 14:24:07 -0700 Subject: [PATCH 2/5] Uses `ConfigStateChecks` for `limits` --- internal/service/pinpoint/app_test.go | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/internal/service/pinpoint/app_test.go b/internal/service/pinpoint/app_test.go index 57953a00677..fa2871cc5e9 100644 --- a/internal/service/pinpoint/app_test.go +++ b/internal/service/pinpoint/app_test.go @@ -41,7 +41,6 @@ func TestAccPinpointApp_basic(t *testing.T) { testAccCheckAppExists(ctx, resourceName, &application), resource.TestCheckResourceAttrSet(resourceName, names.AttrApplicationID), resource.TestCheckResourceAttrSet(resourceName, names.AttrARN), - resource.TestCheckResourceAttr(resourceName, "limits.#", acctest.Ct1), resource.TestCheckResourceAttr(resourceName, names.AttrName, rName), resource.TestCheckResourceAttr(resourceName, names.AttrNamePrefix, ""), resource.TestCheckResourceAttr(resourceName, "quiet_time.#", acctest.Ct1), @@ -55,6 +54,14 @@ func TestAccPinpointApp_basic(t *testing.T) { "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), + }), + })), }, }, { @@ -235,9 +242,17 @@ 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, From 341b3fee0c8dde2c83d3b33e1a7eb0fcf798babb Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Wed, 10 Jul 2024 14:34:58 -0700 Subject: [PATCH 3/5] Uses `ConfigStateChecks` for `quiet_time` --- internal/service/pinpoint/app_test.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/internal/service/pinpoint/app_test.go b/internal/service/pinpoint/app_test.go index fa2871cc5e9..b52a9255033 100644 --- a/internal/service/pinpoint/app_test.go +++ b/internal/service/pinpoint/app_test.go @@ -43,7 +43,6 @@ func TestAccPinpointApp_basic(t *testing.T) { resource.TestCheckResourceAttrSet(resourceName, names.AttrARN), 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{ @@ -62,6 +61,12 @@ func TestAccPinpointApp_basic(t *testing.T) { "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(""), + }), + })), }, }, { @@ -279,9 +284,15 @@ 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, From 78ced039f6c5aaa3323561551d670d3dd2db9701 Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Wed, 10 Jul 2024 14:35:32 -0700 Subject: [PATCH 4/5] Uses `ConfigStateChecks` for tags --- internal/service/pinpoint/app_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/service/pinpoint/app_test.go b/internal/service/pinpoint/app_test.go index b52a9255033..cee73ea6b9e 100644 --- a/internal/service/pinpoint/app_test.go +++ b/internal/service/pinpoint/app_test.go @@ -43,7 +43,6 @@ func TestAccPinpointApp_basic(t *testing.T) { resource.TestCheckResourceAttrSet(resourceName, names.AttrARN), resource.TestCheckResourceAttr(resourceName, names.AttrName, rName), resource.TestCheckResourceAttr(resourceName, names.AttrNamePrefix, ""), - resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct0), ), ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("campaign_hook"), knownvalue.ListExact([]knownvalue.Check{ @@ -67,6 +66,8 @@ func TestAccPinpointApp_basic(t *testing.T) { "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{})), }, }, { From ec491cd7e56a9a2fbd931bef9033c1ba8d0bbbaf Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Wed, 10 Jul 2024 14:50:14 -0700 Subject: [PATCH 5/5] Fixes panic --- internal/service/pinpoint/app.go | 6 +- internal/service/pinpoint/app_test.go | 138 ++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 3 deletions(-) diff --git a/internal/service/pinpoint/app.go b/internal/service/pinpoint/app.go index 944572ad808..b354a97cdd3 100644 --- a/internal/service/pinpoint/app.go +++ b/internal/service/pinpoint/app.go @@ -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 } @@ -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 } @@ -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 } diff --git a/internal/service/pinpoint/app_test.go b/internal/service/pinpoint/app_test.go index cee73ea6b9e..0077b962b4e 100644 --- a/internal/service/pinpoint/app_test.go +++ b/internal/service/pinpoint/app_test.go @@ -232,6 +232,42 @@ func TestAccPinpointApp_campaignHookLambda(t *testing.T) { }) } +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, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccPinpointApp_limits(t *testing.T) { ctx := acctest.Context(t) var application pinpoint.ApplicationResponse @@ -269,6 +305,43 @@ func TestAccPinpointApp_limits(t *testing.T) { }) } +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, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccPinpointApp_quietTime(t *testing.T) { ctx := acctest.Context(t) var application pinpoint.ApplicationResponse @@ -304,6 +377,41 @@ func TestAccPinpointApp_quietTime(t *testing.T) { }) } +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, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccPreCheckApp(ctx context.Context, t *testing.T) { t.Helper() acctest.PreCheckPinpointApp(ctx, t) @@ -461,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" { @@ -476,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" { @@ -488,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) +}