Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 10 additions & 6 deletions internal/resources/payments_connectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/formancehq/formance-sdk-go/v3/pkg/models/operations"
"github.com/formancehq/formance-sdk-go/v3/pkg/models/shared"
"github.com/formancehq/go-libs/v3/logging"
"github.com/formancehq/terraform-provider-stack/internal"
"github.com/formancehq/terraform-provider-stack/internal/server/sdk"
"github.com/hashicorp/terraform-plugin-framework/attr"
Expand Down Expand Up @@ -55,19 +56,21 @@ type PaymentsConnectorsModel struct {
Config types.Dynamic `tfsdk:"config"`
}

func (m PaymentsConnectorsModel) CreateConfig() (operations.V3InstallConnectorRequest, error) {
func (m PaymentsConnectorsModel) installConfig(ctx context.Context) (operations.V3InstallConnectorRequest, error) {
var snakeAS map[string]interface{}
if err := json.Unmarshal([]byte(m.Config.String()), &snakeAS); err != nil {
return operations.V3InstallConnectorRequest{}, fmt.Errorf("failed to unmarshal config: %w", err)
}

if err := json.Unmarshal([]byte(m.Credentials.String()), &snakeAS); err != nil {
return operations.V3InstallConnectorRequest{}, fmt.Errorf("failed to unmarshal credentials: %w", err)
logging.FromContext(ctx).Error(err)
return operations.V3InstallConnectorRequest{}, fmt.Errorf("failed to unmarshal credentials")
}

data, err := json.Marshal(snakeAS)
if err != nil {
return operations.V3InstallConnectorRequest{}, fmt.Errorf("failed to marshal connector config: %w", err)
logging.FromContext(ctx).Error(err)
return operations.V3InstallConnectorRequest{}, fmt.Errorf("failed to marshal connector config")
}

provider := ""
Expand All @@ -83,7 +86,8 @@ func (m PaymentsConnectorsModel) CreateConfig() (operations.V3InstallConnectorRe
}

if err := config.V3InstallConnectorRequest.UnmarshalJSON(data); err != nil {
return config, err
logging.FromContext(ctx).Error(err)
return config, fmt.Errorf("failed to unmarshal config in V3InstallConnectorRequest")
}

return config, nil
Expand Down Expand Up @@ -215,7 +219,7 @@ func (s *PaymentsConnectors) Create(ctx context.Context, req resource.CreateRequ
return
}

config, err := plan.CreateConfig()
config, err := plan.installConfig(ctx)
if err != nil {
res.Diagnostics.AddError(
"Invalid Connector Configuration",
Expand Down Expand Up @@ -318,7 +322,7 @@ func (s *PaymentsConnectors) Update(ctx context.Context, req resource.UpdateRequ
}

sdkPayments := s.store.Payments()
config, err := plan.CreateConfig()
config, err := plan.installConfig(ctx)
if err != nil {
res.Diagnostics.AddError(
"Invalid Connector Configuration",
Expand Down
49 changes: 33 additions & 16 deletions internal/resources/payments_connectors_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package resources_test
package resources

import (
"fmt"
"testing"

"github.com/formancehq/formance-sdk-go/v3/pkg/models/operations"
"github.com/formancehq/formance-sdk-go/v3/pkg/models/shared"
"github.com/formancehq/go-libs/v3/logging"
"github.com/formancehq/go-libs/v3/pointer"
"github.com/formancehq/terraform-provider-stack/internal/resources"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand All @@ -18,17 +19,17 @@ func TestPaymentsCreateConfigFromModel(t *testing.T) {
t.Parallel()

type testCase struct {
plan resources.PaymentsConnectorsModel
plan PaymentsConnectorsModel
expectedConnector operations.V3InstallConnectorRequest
}

for _, tc := range []testCase{
{
plan: resources.PaymentsConnectorsModel{
Credentials: types.DynamicValue(resources.NewDynamicObjectValue(map[string]attr.Value{
plan: PaymentsConnectorsModel{
Credentials: types.DynamicValue(NewDynamicObjectValue(map[string]attr.Value{
"apiKey": types.DynamicValue(types.StringValue("my-api-key")),
}).Value()),
Config: types.DynamicValue(resources.NewDynamicObjectValue(map[string]attr.Value{
Config: types.DynamicValue(NewDynamicObjectValue(map[string]attr.Value{
"endpoint": types.DynamicValue(types.StringValue("https://api.example.com")),
"name": types.DynamicValue(types.StringValue("Example Connector")),
"pageSize": types.DynamicValue(types.Int64Value(100)),
Expand All @@ -52,13 +53,13 @@ func TestPaymentsCreateConfigFromModel(t *testing.T) {
},
},
{
plan: resources.PaymentsConnectorsModel{
Credentials: types.DynamicValue(resources.NewDynamicObjectValue(
plan: PaymentsConnectorsModel{
Credentials: types.DynamicValue(NewDynamicObjectValue(
map[string]attr.Value{
"apiKey": types.DynamicValue(types.StringValue("api-key-value")),
"webhookPassword": types.DynamicValue(types.StringValue("webhook-password")),
}).Value()),
Config: types.DynamicValue(resources.NewDynamicObjectValue(
Config: types.DynamicValue(NewDynamicObjectValue(
map[string]attr.Value{
"name": types.DynamicValue(types.StringValue("Example Connector")),
"pageSize": types.DynamicValue(types.Int64Value(50)),
Expand Down Expand Up @@ -90,7 +91,7 @@ func TestPaymentsCreateConfigFromModel(t *testing.T) {
},
} {
t.Run(fmt.Sprintf("%s %s", t.Name(), "1"), func(t *testing.T) {
req, err := tc.plan.CreateConfig()
req, err := tc.plan.installConfig(logging.TestingContext())
if err != nil {
t.Fatalf("failed to create config: %v", err)
}
Expand All @@ -101,6 +102,22 @@ func TestPaymentsCreateConfigFromModel(t *testing.T) {
}
}

func TestPaymentsCreateConfigFromModel_Error(t *testing.T) {
t.Parallel()

plan := PaymentsConnectorsModel{
Credentials: types.DynamicValue(NewDynamicObjectValue(map[string]attr.Value{
"apiKey": types.DynamicValue(types.StringValue("my-api-key")),
}).Value()),
Config: types.DynamicValue(types.StringNull()),
}

_, err := plan.installConfig(logging.TestingContext())
require.Error(t, err)
require.Contains(t, err.Error(), "failed to unmarshal config")
require.NotContains(t, err.Error(), "my-api-key")
}

func TestExtractKeys(t *testing.T) {
t.Parallel()
type testCase struct {
Expand All @@ -120,7 +137,7 @@ func TestExtractKeys(t *testing.T) {
t.Run(t.Name(), func(t *testing.T) {
t.Parallel()

keys := resources.ExtractKeys(tc.m)
keys := ExtractKeys(tc.m)

require.ElementsMatch(t, tc.expectedKeys, keys)
})
Expand Down Expand Up @@ -151,7 +168,7 @@ func TestSanitizeUnknownKeys(t *testing.T) {
} {
t.Run(t.Name(), func(t *testing.T) {
t.Parallel()
d := resources.SanitizeUnknownKeys(tc.m, tc.allowedKeys)
d := SanitizeUnknownKeys(tc.m, tc.allowedKeys)
require.Equal(t, tc.expectedMap, d)

})
Expand All @@ -163,7 +180,7 @@ func TestPaymentsStateFromRequest(t *testing.T) {

type testCase struct {
request *shared.V3GetConnectorConfigResponse
fromState resources.PaymentsConnectorsModel
fromState PaymentsConnectorsModel
}

for _, tc := range []testCase{
Expand All @@ -183,13 +200,13 @@ func TestPaymentsStateFromRequest(t *testing.T) {
},
},
},
fromState: resources.PaymentsConnectorsModel{
fromState: PaymentsConnectorsModel{
ID: types.StringValue("somevalue"),
Credentials: types.DynamicValue(resources.NewDynamicObjectValue(map[string]attr.Value{
Credentials: types.DynamicValue(NewDynamicObjectValue(map[string]attr.Value{
"apiKey": types.StringValue("api-key-value"),
"webhookPassword": types.StringValue("webhook-password"),
}).Value()),
Config: types.DynamicValue(resources.NewDynamicObjectValue(map[string]attr.Value{
Config: types.DynamicValue(NewDynamicObjectValue(map[string]attr.Value{
"name": types.StringValue("Example Connector"),
"pageSize": types.Int64Value(50),
"pollingPeriod": types.StringValue("2m"),
Expand Down