Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Enhancements

* Adds `DeliveryResponses` parsing in `NotificationConfiguration`, by @jpadrianoGo [#1190](https://github.com/hashicorp/go-tfe/pull/1190)
* Adds `Logs` method to `QueryRuns`, which is EXPERIMENTAL, SUBJECT TO CHANGE, and may not be available to all users by @brandonc [#1186](https://github.com/hashicorp/go-tfe/pull/1186)
* Adds `Source` field to `Workspace` by @jpadrianoGo [#1124](https://github.com/hashicorp/go-tfe/pull/1124)
* Adds `IconUrl`, `InstallationType`, and `InstallationURL` to githubAppInstallation, by @jpadrianoGo [#1191](https://github.com/hashicorp/go-tfe/pull/1143)
Expand Down
50 changes: 40 additions & 10 deletions notification_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package tfe

import (
"context"
"encoding/json"
"fmt"
"net/url"
"time"
Expand Down Expand Up @@ -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"`
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -276,6 +280,8 @@ func (s *notificationConfigurations) Create(ctx context.Context, subscribableID

backfillDeprecatedSubscribable(nc)

parseDeliveryResponses(nc)

return nc, nil
}

Expand All @@ -299,6 +305,8 @@ func (s *notificationConfigurations) Read(ctx context.Context, notificationConfi

backfillDeprecatedSubscribable(nc)

parseDeliveryResponses(nc)

return nc, nil
}

Expand Down Expand Up @@ -326,6 +334,8 @@ func (s *notificationConfigurations) Update(ctx context.Context, notificationCon

backfillDeprecatedSubscribable(nc)

parseDeliveryResponses(nc)

return nc, nil
}

Expand Down Expand Up @@ -364,6 +374,8 @@ func (s *notificationConfigurations) Verify(ctx context.Context, notificationCon
return nil, err
}

parseDeliveryResponses(nc)

return nc, nil
}

Expand Down Expand Up @@ -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)
}
}
107 changes: 107 additions & 0 deletions notification_configuration_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package tfe
import (
"context"
"fmt"
"os"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -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)
Expand Down
Loading