From be225a3132e2f80d680bad3c1cda2c36fe501dd4 Mon Sep 17 00:00:00 2001 From: Sebastian Rivera Date: Thu, 3 Mar 2022 14:45:05 -0500 Subject: [PATCH] Notification triggers are now a string enum --- errors.go | 2 + helper_test.go | 2 +- notification_configuration.go | 58 ++++++++++++++++--- ...fication_configuration_integration_test.go | 31 +++++++++- 4 files changed, 81 insertions(+), 12 deletions(-) diff --git a/errors.go b/errors.go index 791836874..f1d59ff21 100644 --- a/errors.go +++ b/errors.go @@ -143,6 +143,8 @@ var ( ErrInvalidPolicies = errors.New("must provide at least one policy") ErrInvalidVariableID = errors.New("invalid value for variable ID") + + ErrInvalidNotificationTrigger = errors.New("invalid value for notification trigger") ) // Missing values for required field/option diff --git a/helper_test.go b/helper_test.go index 6dc820c64..0b049c9ff 100644 --- a/helper_test.go +++ b/helper_test.go @@ -164,7 +164,7 @@ func createNotificationConfiguration(t *testing.T, client *Client, w *Workspace, Name: String(randomString(t)), Token: String(randomString(t)), URL: String("http://example.com"), - Triggers: []string{NotificationTriggerCreated}, + Triggers: []NotificationTriggerType{NotificationTriggerCreated}, } } diff --git a/notification_configuration.go b/notification_configuration.go index 3721c67e5..4515aac98 100644 --- a/notification_configuration.go +++ b/notification_configuration.go @@ -40,13 +40,17 @@ type notificationConfigurations struct { client *Client } +// NotificationTriggerType represents the different TFE notifications that can be sent +// as a run's progress transitions between different states +type NotificationTriggerType string + const ( - NotificationTriggerCreated string = "run:created" - NotificationTriggerPlanning string = "run:planning" - NotificationTriggerNeedsAttention string = "run:needs_attention" - NotificationTriggerApplying string = "run:applying" - NotificationTriggerCompleted string = "run:completed" - NotificationTriggerErrored string = "run:errored" + NotificationTriggerCreated NotificationTriggerType = "run:created" + NotificationTriggerPlanning NotificationTriggerType = "run:planning" + NotificationTriggerNeedsAttention NotificationTriggerType = "run:needs_attention" + NotificationTriggerApplying NotificationTriggerType = "run:applying" + NotificationTriggerCompleted NotificationTriggerType = "run:completed" + NotificationTriggerErrored NotificationTriggerType = "run:errored" ) // NotificationDestinationType represents the destination type of the @@ -126,7 +130,7 @@ type NotificationConfigurationCreateOptions struct { Token *string `jsonapi:"attr,token,omitempty"` // Optional: The list of run events that will trigger notifications. - Triggers []string `jsonapi:"attr,triggers,omitempty"` + Triggers []NotificationTriggerType `jsonapi:"attr,triggers,omitempty"` // Optional: The url of the notification configuration URL *string `jsonapi:"attr,url,omitempty"` @@ -158,7 +162,7 @@ type NotificationConfigurationUpdateOptions struct { Token *string `jsonapi:"attr,token,omitempty"` // Optional: The list of run events that will trigger notifications. - Triggers []string `jsonapi:"attr,triggers,omitempty"` + Triggers []NotificationTriggerType `jsonapi:"attr,triggers,omitempty"` // Optional: The url of the notification configuration URL *string `jsonapi:"attr,url,omitempty"` @@ -243,6 +247,10 @@ func (s *notificationConfigurations) Update(ctx context.Context, notificationCon return nil, ErrInvalidNotificationConfigID } + if err := options.valid(); err != nil { + return nil, err + } + u := fmt.Sprintf("notification-configurations/%s", url.QueryEscape(notificationConfigurationID)) req, err := s.client.newRequest("PATCH", u, &options) if err != nil { @@ -307,6 +315,10 @@ func (o NotificationConfigurationCreateOptions) valid() error { return ErrRequiredName } + if !validNotificationTriggerType(o.Triggers) { + return ErrInvalidNotificationTrigger + } + if *o.DestinationType == NotificationDestinationTypeGeneric || *o.DestinationType == NotificationDestinationTypeSlack { if o.URL == nil { return ErrRequiredURL @@ -314,3 +326,33 @@ func (o NotificationConfigurationCreateOptions) valid() error { } return nil } + +func (o NotificationConfigurationUpdateOptions) valid() error { + if o.Name != nil && !validString(o.Name) { + return ErrRequiredName + } + + if !validNotificationTriggerType(o.Triggers) { + return ErrInvalidNotificationTrigger + } + + return nil +} + +func validNotificationTriggerType(triggers []NotificationTriggerType) bool { + for _, t := range triggers { + switch t { + case NotificationTriggerApplying, + NotificationTriggerNeedsAttention, + NotificationTriggerCompleted, + NotificationTriggerCreated, + NotificationTriggerErrored, + NotificationTriggerPlanning: + continue + default: + return false + } + } + + return true +} diff --git a/notification_configuration_integration_test.go b/notification_configuration_integration_test.go index c28e7c19a..80440cb31 100644 --- a/notification_configuration_integration_test.go +++ b/notification_configuration_integration_test.go @@ -93,7 +93,7 @@ func TestNotificationConfigurationCreate(t *testing.T) { Name: String(randomString(t)), Token: String(randomString(t)), URL: String("http://example.com"), - Triggers: []string{NotificationTriggerCreated}, + Triggers: []NotificationTriggerType{NotificationTriggerCreated}, } _, err := client.NotificationConfigurations.Create(ctx, wTest.ID, options) @@ -106,7 +106,7 @@ func TestNotificationConfigurationCreate(t *testing.T) { Enabled: Bool(false), Token: String(randomString(t)), URL: String("http://example.com"), - Triggers: []string{NotificationTriggerCreated}, + Triggers: []NotificationTriggerType{NotificationTriggerCreated}, } nc, err := client.NotificationConfigurations.Create(ctx, wTest.ID, options) @@ -120,7 +120,7 @@ func TestNotificationConfigurationCreate(t *testing.T) { Enabled: Bool(false), Name: String(randomString(t)), Token: String(randomString(t)), - Triggers: []string{NotificationTriggerCreated}, + Triggers: []NotificationTriggerType{NotificationTriggerCreated}, } nc, err := client.NotificationConfigurations.Create(ctx, wTest.ID, options) @@ -134,6 +134,21 @@ func TestNotificationConfigurationCreate(t *testing.T) { assert.EqualError(t, err, ErrInvalidWorkspaceID.Error()) }) + t.Run("with an invalid notification trigger", func(t *testing.T) { + options := NotificationConfigurationCreateOptions{ + DestinationType: NotificationDestination(NotificationDestinationTypeGeneric), + Enabled: Bool(false), + Name: String(randomString(t)), + Token: String(randomString(t)), + URL: String("http://example.com"), + Triggers: []NotificationTriggerType{"the beacons of gondor are lit"}, + } + + nc, err := client.NotificationConfigurations.Create(ctx, wTest.ID, options) + assert.Nil(t, nc) + assert.EqualError(t, err, ErrInvalidNotificationTrigger.Error()) + }) + t.Run("with email users when destination type is email", func(t *testing.T) { options := NotificationConfigurationCreateOptions{ DestinationType: NotificationDestination(NotificationDestinationTypeEmail), @@ -225,6 +240,16 @@ func TestNotificationConfigurationUpdate(t *testing.T) { assert.Equal(t, nc.Name, "newName") }) + t.Run("with invalid notification trigger", func(t *testing.T) { + options := NotificationConfigurationUpdateOptions{ + Triggers: []NotificationTriggerType{"fly you fools!"}, + } + + nc, err := client.NotificationConfigurations.Update(ctx, ncTest.ID, options) + assert.Nil(t, nc) + assert.EqualError(t, err, ErrInvalidNotificationTrigger.Error()) + }) + t.Run("with email users when destination type is email", func(t *testing.T) { options := NotificationConfigurationUpdateOptions{ Enabled: Bool(true),