diff --git a/stackit/internal/services/postgresflexalpha/database/mapper.go b/stackit/internal/services/postgresflexalpha/database/mapper.go new file mode 100644 index 00000000..4a9043d1 --- /dev/null +++ b/stackit/internal/services/postgresflexalpha/database/mapper.go @@ -0,0 +1,47 @@ +package postgresflexalpha + +import ( + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/types" + "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" +) + +// mapFields maps fields from a ListDatabase API response to a DatabaseModel for the data source. +func mapFields(resp *postgresflexalpha.ListDatabase, model *postgresflexalpha2.DatabaseModel, region string) error { + if resp == nil { + return fmt.Errorf("response is nil") + } + if resp.Id == nil || *resp.Id == 0 { + return fmt.Errorf("id not present") + } + if model == nil { + return fmt.Errorf("model input is nil") + } + + var databaseId int64 + if model.Id.ValueInt64() != 0 { + databaseId = model.Id.ValueInt64() + } else if resp.Id != nil { + databaseId = *resp.Id + } else { + return fmt.Errorf("database id not present") + } + + model.Id = types.Int64Value(databaseId) + model.Name = types.StringPointerValue(resp.Name) + model.Region = types.StringValue(region) + model.Owner = types.StringPointerValue(cleanString(resp.Owner)) + return nil +} + +// cleanString removes leading and trailing quotes from a string pointer. +func cleanString(s *string) *string { + if s == nil { + return nil + } + res := strings.Trim(*s, "\"") + return &res +} diff --git a/stackit/internal/services/postgresflexalpha/database/mapper_test.go b/stackit/internal/services/postgresflexalpha/database/mapper_test.go new file mode 100644 index 00000000..f36aab99 --- /dev/null +++ b/stackit/internal/services/postgresflexalpha/database/mapper_test.go @@ -0,0 +1,157 @@ +package postgresflexalpha + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/types" + "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" +) + +func TestMapFields(t *testing.T) { + type input struct { + resp *postgresflexalpha.ListDatabase + model *postgresflexalpha2.DatabaseModel + region string + } + type expected struct { + model *postgresflexalpha2.DatabaseModel + err bool + } + + testcases := []struct { + name string + given input + want 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\""), + }, + model: &postgresflexalpha2.DatabaseModel{}, + region: "eu01", + }, + want: expected{ + model: &postgresflexalpha2.DatabaseModel{ + Id: types.Int64Value(123), + Name: types.StringValue("my-db"), + 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"), + }, + model: &postgresflexalpha2.DatabaseModel{ + Id: types.Int64Value(789), + }, + region: "eu01", + }, + want: expected{ + model: &postgresflexalpha2.DatabaseModel{ + Id: types.Int64Value(789), + Name: types.StringValue("my-db"), + 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 return an error when response ID is nil", + given: input{ + resp: &postgresflexalpha.ListDatabase{ + Id: nil, + }, + model: &postgresflexalpha2.DatabaseModel{}, + }, + want: 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, + }, + }, + } + + 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) + } + } + }) + } +} + +func TestCleanString(t *testing.T) { + testcases := []struct { + name string + given *string + want *string + }{ + { + name: "should remove quotes from a string", + given: ptr("\"quoted\""), + want: ptr("quoted"), + }, + { + name: "should return nil for a nil input", + given: nil, + want: nil, + }, + { + name: "should not change a string without quotes", + given: ptr("unquoted"), + want: 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) + } + }) + } +} + +func ptr[T any](v T) *T { + return &v +}