feat: add tests for plan modifiers configuration and resource schema handling
This commit is contained in:
parent
c4b31d0ba8
commit
062fd98870
2 changed files with 224 additions and 0 deletions
224
stackit/internal/utils/planModifiers_test.go
Normal file
224
stackit/internal/utils/planModifiers_test.go
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
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")
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue