diff --git a/stackit/internal/services/postgresflexalpha/database/mapper.go b/stackit/internal/services/postgresflexalpha/database/mapper.go index 6e944361..560dc38d 100644 --- a/stackit/internal/services/postgresflexalpha/database/mapper.go +++ b/stackit/internal/services/postgresflexalpha/database/mapper.go @@ -21,7 +21,7 @@ func mapFields( return fmt.Errorf("id not present") } if model == nil { - return fmt.Errorf("model input is nil") + return fmt.Errorf("model given is nil") } var databaseId int64 @@ -36,6 +36,7 @@ func mapFields( model.Id = types.Int64Value(databaseId) model.Name = types.StringPointerValue(source.Name) model.Owner = types.StringPointerValue(cleanString(source.Owner)) + model.Region = types.StringValue(region) return nil } diff --git a/stackit/internal/services/postgresflexalpha/database/mapper_test.go b/stackit/internal/services/postgresflexalpha/database/mapper_test.go index f36aab99..3fc661a1 100644 --- a/stackit/internal/services/postgresflexalpha/database/mapper_test.go +++ b/stackit/internal/services/postgresflexalpha/database/mapper_test.go @@ -5,153 +5,266 @@ import ( "github.com/google/go-cmp/cmp" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/stackitcloud/stackit-sdk-go/core/utils" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/postgresflexalpha" - postgresflexalpha2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/database/datasources_gen" + datasource "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/database/datasources_gen" + resource "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/database/resources_gen" ) func TestMapFields(t *testing.T) { - type input struct { - resp *postgresflexalpha.ListDatabase - model *postgresflexalpha2.DatabaseModel + type given struct { + source *postgresflexalpha.ListDatabase + model *DataSourceModel region string } type expected struct { - model *postgresflexalpha2.DatabaseModel + model *DataSourceModel err bool } testcases := []struct { - name string - given input - want expected + name string + given given + expected expected }{ { - name: "should map fields correctly when given a valid response", - given: input{ - resp: &postgresflexalpha.ListDatabase{ - Id: ptr(int64(123)), - Name: ptr("my-db"), - Owner: ptr("\"my-owner\""), + name: "should map fields correctly", + given: given{ + source: &postgresflexalpha.ListDatabase{ + Id: utils.Ptr(int64(1)), + Name: utils.Ptr("my-db"), + Owner: utils.Ptr("\"my-owner\""), }, - model: &postgresflexalpha2.DatabaseModel{}, + model: &DataSourceModel{}, region: "eu01", }, - want: expected{ - model: &postgresflexalpha2.DatabaseModel{ - Id: types.Int64Value(123), - Name: types.StringValue("my-db"), + expected: expected{ + model: &DataSourceModel{ + DatabaseModel: datasource.DatabaseModel{ + Id: types.Int64Value(1), + Name: types.StringValue("my-db"), + Owner: types.StringValue("my-owner"), + }, Region: types.StringValue("eu01"), - Owner: types.StringValue("my-owner"), }, - err: false, }, }, { - name: "should use existing model ID if present", - given: input{ - resp: &postgresflexalpha.ListDatabase{ - Id: ptr(int64(456)), - Name: ptr("my-db"), + name: "should preserve existing model ID", + given: given{ + source: &postgresflexalpha.ListDatabase{ + Id: utils.Ptr(int64(1)), + Name: utils.Ptr("my-db"), }, - model: &postgresflexalpha2.DatabaseModel{ - Id: types.Int64Value(789), + model: &DataSourceModel{ + DatabaseModel: datasource.DatabaseModel{ + Id: types.Int64Value(1), + }, }, region: "eu01", }, - want: expected{ - model: &postgresflexalpha2.DatabaseModel{ - Id: types.Int64Value(789), - Name: types.StringValue("my-db"), + expected: expected{ + model: &DataSourceModel{ + DatabaseModel: datasource.DatabaseModel{ + Id: types.Int64Value(1), + Name: types.StringValue("my-db"), + Owner: types.StringNull(), + }, Region: types.StringValue("eu01"), - Owner: types.StringNull(), }, - err: false, }, }, { - name: "should return an error when response is nil", - given: input{ - resp: nil, - model: &postgresflexalpha2.DatabaseModel{}, - }, - want: expected{ - err: true, + name: "should fail on nil source", + given: given{ + source: nil, + model: &DataSourceModel{}, }, + expected: expected{err: true}, }, { - name: "should return an error when response ID is nil", - given: input{ - resp: &postgresflexalpha.ListDatabase{ - Id: nil, - }, - model: &postgresflexalpha2.DatabaseModel{}, - }, - want: expected{ - err: true, + name: "should fail on nil source ID", + given: given{ + source: &postgresflexalpha.ListDatabase{Id: nil}, + model: &DataSourceModel{}, }, + expected: expected{err: true}, }, { - name: "should return an error when model is nil", - given: input{ - resp: &postgresflexalpha.ListDatabase{ - Id: ptr(int64(123)), - }, - model: nil, - }, - want: expected{ - err: true, + name: "should fail on nil model", + given: given{ + source: &postgresflexalpha.ListDatabase{Id: utils.Ptr(int64(1))}, + model: nil, }, + expected: expected{err: true}, }, } for _, tc := range testcases { - t.Run(tc.name, func(t *testing.T) { - err := mapFields(tc.given.resp, tc.given.model, tc.given.region) - if (err != nil) != tc.want.err { - t.Fatalf("expected error: %v, got: %v", tc.want.err, err) - } - if err == nil { - if diff := cmp.Diff(tc.want.model, tc.given.model); diff != "" { - t.Errorf("model mismatch (-want +got):\n%s", diff) + t.Run( + tc.name, func(t *testing.T) { + err := mapFields(tc.given.source, tc.given.model, tc.given.region) + if (err != nil) != tc.expected.err { + t.Fatalf("expected error: %v, got: %v", tc.expected.err, err) } - } - }) + if err == nil { + if diff := cmp.Diff(tc.expected.model, tc.given.model); diff != "" { + t.Errorf("model mismatch (-want +got):\n%s", diff) + } + } + }, + ) + } +} + +func TestMapResourceFields(t *testing.T) { + type given struct { + source *postgresflexalpha.ListDatabase + model *ResourceModel + } + type expected struct { + model *ResourceModel + err bool + } + + testcases := []struct { + name string + given given + expected expected + }{ + { + name: "should map fields correctly", + given: given{ + source: &postgresflexalpha.ListDatabase{ + Id: utils.Ptr(int64(1)), + Name: utils.Ptr("my-db"), + Owner: utils.Ptr("\"my-owner\""), + }, + model: &ResourceModel{}, + }, + expected: expected{ + model: &ResourceModel{ + DatabaseModel: resource.DatabaseModel{ + Id: types.Int64Value(1), + Name: types.StringValue("my-db"), + Owner: types.StringValue("my-owner"), + }, + }, + }, + }, + { + name: "should fail on nil source", + given: given{ + source: nil, + model: &ResourceModel{}, + }, + expected: expected{err: true}, + }, + } + + for _, tc := range testcases { + t.Run( + tc.name, func(t *testing.T) { + err := mapResourceFields(tc.given.source, tc.given.model) + if (err != nil) != tc.expected.err { + t.Fatalf("expected error: %v, got: %v", tc.expected.err, err) + } + if err == nil { + if diff := cmp.Diff(tc.expected.model, tc.given.model); diff != "" { + t.Errorf("model mismatch (-want +got):\n%s", diff) + } + } + }, + ) + } +} + +func TestToCreatePayload(t *testing.T) { + type given struct { + model *ResourceModel + } + type expected struct { + payload *postgresflexalpha.CreateDatabaseRequestPayload + err bool + } + + testcases := []struct { + name string + given given + expected expected + }{ + { + name: "should convert model to payload", + given: given{ + model: &ResourceModel{ + DatabaseModel: resource.DatabaseModel{ + Name: types.StringValue("my-db"), + Owner: types.StringValue("my-owner"), + }, + }, + }, + expected: expected{ + payload: &postgresflexalpha.CreateDatabaseRequestPayload{ + Name: utils.Ptr("my-db"), + Owner: utils.Ptr("my-owner"), + }, + }, + }, + { + name: "should fail on nil model", + given: given{model: nil}, + expected: expected{err: true}, + }, + } + + for _, tc := range testcases { + t.Run( + tc.name, func(t *testing.T) { + actual, err := toCreatePayload(tc.given.model) + if (err != nil) != tc.expected.err { + t.Fatalf("expected error: %v, got: %v", tc.expected.err, err) + } + if err == nil { + if diff := cmp.Diff(tc.expected.payload, actual); diff != "" { + t.Errorf("payload mismatch (-want +got):\n%s", diff) + } + } + }, + ) } } func TestCleanString(t *testing.T) { testcases := []struct { - name string - given *string - want *string + name string + given *string + expected *string }{ { - name: "should remove quotes from a string", - given: ptr("\"quoted\""), - want: ptr("quoted"), + name: "should remove quotes", + given: utils.Ptr("\"quoted\""), + expected: utils.Ptr("quoted"), }, { - name: "should return nil for a nil input", - given: nil, - want: nil, + name: "should handle nil", + given: nil, + expected: nil, }, { - name: "should not change a string without quotes", - given: ptr("unquoted"), - want: ptr("unquoted"), + name: "should not change unquoted string", + given: utils.Ptr("unquoted"), + expected: utils.Ptr("unquoted"), }, } for _, tc := range testcases { - t.Run(tc.name, func(t *testing.T) { - actual := cleanString(tc.given) - if (actual == nil && tc.want != nil) || (actual != nil && tc.want == nil) || (actual != nil && *actual != *tc.want) { - t.Errorf("expected %v, got %v", tc.want, actual) - } - }) + t.Run( + tc.name, func(t *testing.T) { + actual := cleanString(tc.given) + if diff := cmp.Diff(tc.expected, actual); diff != "" { + t.Errorf("string mismatch (-want +got):\n%s", diff) + } + }, + ) } } - -func ptr[T any](v T) *T { - return &v -}