diff --git a/CHANGELOG.md b/CHANGELOG.md index 7454afeec..5b345784b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Unreleased +## Enhancements + +* Adds `DeliveryResponses` parsing in `NotificationConfiguration`, by @jpadrianoGo [#1129](https://github.com/hashicorp/go-tfe/pull/1129) + # v1.85.0 ## Bug Fixes diff --git a/notification_configuration.go b/notification_configuration.go index ad6c8dfae..85f1fb46b 100644 --- a/notification_configuration.go +++ b/notification_configuration.go @@ -5,6 +5,7 @@ package tfe import ( "context" + "encoding/json" "fmt" "net/url" "time" @@ -91,16 +92,17 @@ type NotificationConfigurationSubscribableChoice struct { // NotificationConfiguration represents a Notification Configuration. type NotificationConfiguration struct { - ID string `jsonapi:"primary,notification-configurations"` - CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"` - DeliveryResponses []*DeliveryResponse `jsonapi:"attr,delivery-responses"` - DestinationType NotificationDestinationType `jsonapi:"attr,destination-type"` - Enabled bool `jsonapi:"attr,enabled"` - Name string `jsonapi:"attr,name"` - Token string `jsonapi:"attr,token"` - Triggers []string `jsonapi:"attr,triggers"` - UpdatedAt time.Time `jsonapi:"attr,updated-at,iso8601"` - URL string `jsonapi:"attr,url"` + ID string `jsonapi:"primary,notification-configurations"` + CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"` + DeliveryResponsesRaw []interface{} `jsonapi:"attr,delivery-responses"` + DeliveryResponses []*DeliveryResponse `json:"-"` + DestinationType NotificationDestinationType `jsonapi:"attr,destination-type"` + Enabled bool `jsonapi:"attr,enabled"` + Name string `jsonapi:"attr,name"` + Token string `jsonapi:"attr,token"` + Triggers []string `jsonapi:"attr,triggers"` + UpdatedAt time.Time `jsonapi:"attr,updated-at,iso8601"` + URL string `jsonapi:"attr,url"` // EmailAddresses is only available for TFE users. It is not available in HCP Terraform. EmailAddresses []string `jsonapi:"attr,email-addresses"` @@ -241,6 +243,8 @@ func (s *notificationConfigurations) List(ctx context.Context, subscribableID st for i := range ncl.Items { backfillDeprecatedSubscribable(ncl.Items[i]) + + parseDeliveryResponses(ncl.Items[i]) } return ncl, nil @@ -276,6 +280,8 @@ func (s *notificationConfigurations) Create(ctx context.Context, subscribableID backfillDeprecatedSubscribable(nc) + parseDeliveryResponses(nc) + return nc, nil } @@ -299,6 +305,8 @@ func (s *notificationConfigurations) Read(ctx context.Context, notificationConfi backfillDeprecatedSubscribable(nc) + parseDeliveryResponses(nc) + return nc, nil } @@ -326,6 +334,8 @@ func (s *notificationConfigurations) Update(ctx context.Context, notificationCon backfillDeprecatedSubscribable(nc) + parseDeliveryResponses(nc) + return nc, nil } @@ -364,6 +374,8 @@ func (s *notificationConfigurations) Verify(ctx context.Context, notificationCon return nil, err } + parseDeliveryResponses(nc) + return nc, nil } @@ -447,3 +459,21 @@ func validNotificationTriggerType(triggers []NotificationTriggerType) bool { return true } + +func parseDeliveryResponses(nc *NotificationConfiguration) { + for _, raw := range nc.DeliveryResponsesRaw { + data, ok := raw.(map[string]interface{}) + if !ok { + continue + } + byteData, err := json.Marshal(data) + if err != nil { + continue + } + deliveryResponse := &DeliveryResponse{} + if err := json.Unmarshal(byteData, deliveryResponse); err != nil { + continue + } + nc.DeliveryResponses = append(nc.DeliveryResponses, deliveryResponse) + } +} diff --git a/notification_configuration_integration_test.go b/notification_configuration_integration_test.go index d81ede21d..4f286c7d4 100644 --- a/notification_configuration_integration_test.go +++ b/notification_configuration_integration_test.go @@ -6,6 +6,7 @@ package tfe import ( "context" "fmt" + "os" "testing" "github.com/stretchr/testify/assert" @@ -514,6 +515,112 @@ func TestNotificationConfigurationRead_forTeams(t *testing.T) { }) } +func TestNotificationConfigurationReadDeliveryResponses(t *testing.T) { + client := testClient(t) + ctx := context.Background() + + runTaskURL := os.Getenv("TFC_RUN_TASK_URL") + if runTaskURL == "" { + t.Skip("Cannot create a notification configuration with an empty URL. You must set TFC_RUN_TASK_URL for run task related tests.") + } + + options := &NotificationConfigurationCreateOptions{ + DestinationType: NotificationDestination(NotificationDestinationTypeGeneric), + Enabled: Bool(true), + Name: String(randomString(t)), + Token: String(randomString(t)), + URL: String(runTaskURL), + Triggers: []NotificationTriggerType{NotificationTriggerCreated}, + } + + t.Run("with notification configuration create", func(t *testing.T) { + ncTest, ncTestCleanup := createNotificationConfiguration(t, client, nil, options) + defer ncTestCleanup() + + assert.Equal(t, 1, len(ncTest.DeliveryResponses)) + assert.NotNil(t, ncTest.DeliveryResponses[0]) + assert.NotEmpty(t, ncTest.DeliveryResponses[0].Code) + }) + + t.Run("with notification configuration list", func(t *testing.T) { + wTest, wTestCleanup := createWorkspace(t, client, nil) + defer wTestCleanup() + + ncTest1, ncTestCleanup1 := createNotificationConfiguration(t, client, wTest, options) + defer ncTestCleanup1() + ncTest2, ncTestCleanup2 := createNotificationConfiguration(t, client, wTest, options) + defer ncTestCleanup2() + + ncl, err := client.NotificationConfigurations.List( + ctx, + wTest.ID, + nil, + ) + require.NoError(t, err) + assert.Contains(t, ncl.Items, ncTest1) + assert.Contains(t, ncl.Items, ncTest2) + + assert.NotNil(t, ncl.Items[0].DeliveryResponses) + assert.NotEmpty(t, ncl.Items[0].DeliveryResponses) + assert.NotNil(t, ncl.Items[1].DeliveryResponses) + assert.NotEmpty(t, ncl.Items[1].DeliveryResponses) + }) + + t.Run("with notification configuration read", func(t *testing.T) { + ncTest, ncTestCleanup := createNotificationConfiguration(t, client, nil, options) + defer ncTestCleanup() + + nc, err := client.NotificationConfigurations.Read(ctx, ncTest.ID) + require.NoError(t, err) + assert.Equal(t, ncTest.ID, nc.ID) + assert.Equal(t, 1, len(nc.DeliveryResponses)) + assert.NotNil(t, nc.DeliveryResponses[0]) + assert.NotEmpty(t, nc.DeliveryResponses[0].Code) + }) + + t.Run("with notification configuration update", func(t *testing.T) { + ncTest, ncTestCleanup := createNotificationConfiguration(t, client, nil, options) + defer ncTestCleanup() + + optionsUpdate := NotificationConfigurationUpdateOptions{ + Enabled: Bool(true), + Name: String("newName"), + } + + nc, err := client.NotificationConfigurations.Update(ctx, ncTest.ID, optionsUpdate) + require.NoError(t, err) + + assert.Equal(t, nc.Name, "newName") + assert.Equal(t, ncTest.ID, nc.ID) + assert.Equal(t, 1, len(nc.DeliveryResponses)) + assert.NotNil(t, nc.DeliveryResponses[0]) + assert.NotEmpty(t, nc.DeliveryResponses[0].Code) + }) + + t.Run("with notification configuration verify", func(t *testing.T) { + ncTest, ncTestCleanup := createNotificationConfiguration(t, client, nil, options) + defer ncTestCleanup() + + ncVerifyTest, err := client.NotificationConfigurations.Verify(ctx, ncTest.ID) + require.NoError(t, err) + + assert.Equal(t, ncTest.ID, ncVerifyTest.ID) + assert.Equal(t, 1, len(ncVerifyTest.DeliveryResponses)) + assert.NotNil(t, ncVerifyTest.DeliveryResponses[0]) + assert.NotEmpty(t, ncVerifyTest.DeliveryResponses[0].Code) + }) + + t.Run("with notification configuration disabled", func(t *testing.T) { + ncTest, ncTestCleanup := createNotificationConfiguration(t, client, nil, nil) + defer ncTestCleanup() + + nc, err := client.NotificationConfigurations.Read(ctx, ncTest.ID) + require.NoError(t, err) + assert.Equal(t, ncTest.ID, nc.ID) + assert.Equal(t, 0, len(nc.DeliveryResponses)) + }) +} + func TestNotificationConfigurationUpdate_forTeams(t *testing.T) { skipUnlessBeta(t) client := testClient(t)