224 lines
5.6 KiB
Go
224 lines
5.6 KiB
Go
package utils
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
|
"github.com/stackitcloud/stackit-sdk-go/core/utils"
|
|
)
|
|
|
|
func TestReadModifiersConfig(t *testing.T) {
|
|
testcases := []struct {
|
|
name string
|
|
content []byte
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "valid yaml",
|
|
content: []byte(`
|
|
fields:
|
|
- name: 'id'
|
|
modifiers:
|
|
- 'UseStateForUnknown'
|
|
`),
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "invalid yaml",
|
|
content: []byte(`invalid: yaml: :`),
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(
|
|
tc.name, func(t *testing.T) {
|
|
_, err := ReadModifiersConfig(tc.content)
|
|
if (err != nil) != tc.wantErr {
|
|
t.Errorf("ReadModifiersConfig() error = %v, wantErr %v", err, tc.wantErr)
|
|
}
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestAddPlanModifiersToResourceSchema(t *testing.T) {
|
|
testcases := []struct {
|
|
name string
|
|
fields *Fields
|
|
sch *schema.Schema
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "full coverage - all types and nested structures",
|
|
fields: &Fields{
|
|
Fields: []*Field{
|
|
{
|
|
Name: "string_attr",
|
|
Modifiers: []*string{utils.Ptr("RequiresReplace"), utils.Ptr("UseStateForUnknown")},
|
|
},
|
|
{Name: "bool_attr", Modifiers: []*string{utils.Ptr("RequiresReplace")}},
|
|
{Name: "int_attr", Modifiers: []*string{utils.Ptr("UseStateForUnknown")}},
|
|
{Name: "list_attr", Modifiers: []*string{utils.Ptr("RequiresReplace")}},
|
|
{Name: "Nested.sub_string", Modifiers: []*string{utils.Ptr("RequiresReplace")}},
|
|
},
|
|
},
|
|
sch: &schema.Schema{
|
|
Attributes: map[string]schema.Attribute{
|
|
"StringAttr": schema.StringAttribute{},
|
|
"BoolAttr": schema.BoolAttribute{},
|
|
"IntAttr": schema.Int64Attribute{},
|
|
"ListAttr": schema.ListAttribute{},
|
|
"Nested": schema.SingleNestedAttribute{
|
|
Attributes: map[string]schema.Attribute{
|
|
"SubString": schema.StringAttribute{},
|
|
},
|
|
},
|
|
"Unsupported": schema.MapAttribute{ElementType: types.StringType}, // Triggers default/warn case
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "validation error - invalid modifier",
|
|
fields: &Fields{
|
|
Fields: []*Field{
|
|
{Name: "id", Modifiers: []*string{utils.Ptr("InvalidModifier")}},
|
|
},
|
|
},
|
|
sch: &schema.Schema{
|
|
Attributes: map[string]schema.Attribute{"id": schema.StringAttribute{}},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "validation error - empty modifier",
|
|
fields: &Fields{
|
|
Fields: []*Field{
|
|
{Name: "id", Modifiers: []*string{utils.Ptr("")}},
|
|
},
|
|
},
|
|
sch: &schema.Schema{},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "nil fields - should return nil",
|
|
fields: nil,
|
|
sch: &schema.Schema{},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(
|
|
tc.name, func(t *testing.T) {
|
|
err := AddPlanModifiersToResourceSchema(tc.fields, tc.sch)
|
|
|
|
if (err != nil) != tc.wantErr {
|
|
t.Fatalf("AddPlanModifiersToResourceSchema() error = %v, wantErr %v", err, tc.wantErr)
|
|
}
|
|
|
|
if !tc.wantErr && tc.name == "full coverage - all types and nested structures" {
|
|
// Check StringAttr
|
|
if sAttr, ok := tc.sch.Attributes["StringAttr"].(schema.StringAttribute); ok {
|
|
if len(sAttr.PlanModifiers) != 2 {
|
|
t.Errorf("StringAttr: expected 2 modifiers, got %d", len(sAttr.PlanModifiers))
|
|
}
|
|
}
|
|
|
|
// Check Nested Sub-Attribute
|
|
if nested, ok := tc.sch.Attributes["Nested"].(schema.SingleNestedAttribute); ok {
|
|
if subAttr, ok := nested.Attributes["SubString"].(schema.StringAttribute); ok {
|
|
if len(subAttr.PlanModifiers) != 1 {
|
|
// Dies schlug vorher fehl, weil der Prefix "Nested" statt "nested" war
|
|
t.Errorf("Nested SubString: expected 1 modifier, got %d", len(subAttr.PlanModifiers))
|
|
}
|
|
} else {
|
|
t.Error("SubString attribute not found in Nested")
|
|
}
|
|
} else {
|
|
t.Error("Nested attribute not found")
|
|
}
|
|
}
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestFieldListToMap(t *testing.T) {
|
|
testcases := []struct {
|
|
name string
|
|
fields *Fields
|
|
want map[string][]*string
|
|
}{
|
|
{
|
|
name: "convert list to map",
|
|
fields: &Fields{
|
|
Fields: []*Field{
|
|
{Name: "test", Modifiers: []*string{utils.Ptr("mod")}},
|
|
},
|
|
},
|
|
want: map[string][]*string{
|
|
"test": {utils.Ptr("mod")},
|
|
},
|
|
},
|
|
{
|
|
name: "nil fields",
|
|
fields: nil,
|
|
want: map[string][]*string{},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(
|
|
tc.name, func(t *testing.T) {
|
|
got := fieldListToMap(tc.fields)
|
|
if diff := cmp.Diff(tc.want, got); diff != "" {
|
|
t.Errorf("fieldListToMap() mismatch (-want +got):\n%s", diff)
|
|
}
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestHandleTypeMismatches(t *testing.T) {
|
|
modifiers := []*string{utils.Ptr("RequiresReplace")}
|
|
|
|
t.Run(
|
|
"bool type mismatch", func(t *testing.T) {
|
|
_, err := handleBoolPlanModifiers(schema.StringAttribute{}, modifiers)
|
|
if err == nil {
|
|
t.Error("expected error for type mismatch in handleBoolPlanModifiers")
|
|
}
|
|
},
|
|
)
|
|
|
|
t.Run(
|
|
"string type mismatch", func(t *testing.T) {
|
|
_, err := handleStringPlanModifiers(schema.BoolAttribute{}, modifiers)
|
|
if err == nil {
|
|
t.Error("expected error for type mismatch in handleStringPlanModifiers")
|
|
}
|
|
},
|
|
)
|
|
|
|
t.Run(
|
|
"int64 type mismatch", func(t *testing.T) {
|
|
_, err := handleInt64PlanModifiers(schema.StringAttribute{}, modifiers)
|
|
if err == nil {
|
|
t.Error("expected error for type mismatch in handleInt64PlanModifiers")
|
|
}
|
|
},
|
|
)
|
|
|
|
t.Run(
|
|
"list type mismatch", func(t *testing.T) {
|
|
_, err := handleListPlanModifiers(schema.StringAttribute{}, modifiers)
|
|
if err == nil {
|
|
t.Error("expected error for type mismatch in handleListPlanModifiers")
|
|
}
|
|
},
|
|
)
|
|
}
|