chore(projectmanager): remove members attribute (#737)
relates to STACKITTPR-165
This commit is contained in:
parent
a8809a4979
commit
297a8a6f88
7 changed files with 145 additions and 713 deletions
|
|
@ -2,15 +2,13 @@ package project
|
|||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/utils"
|
||||
"github.com/stackitcloud/stackit-sdk-go/services/authorization"
|
||||
"github.com/stackitcloud/stackit-sdk-go/services/resourcemanager"
|
||||
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion"
|
||||
)
|
||||
|
|
@ -38,7 +36,6 @@ func TestMapProjectFields(t *testing.T) {
|
|||
ProjectId: types.StringValue("pid"),
|
||||
ContainerParentId: types.StringNull(),
|
||||
Name: types.StringNull(),
|
||||
Members: types.ListNull(types.ObjectType{AttrTypes: memberTypes}),
|
||||
},
|
||||
nil,
|
||||
true,
|
||||
|
|
@ -65,7 +62,6 @@ func TestMapProjectFields(t *testing.T) {
|
|||
ProjectId: types.StringValue("pid"),
|
||||
ContainerParentId: types.StringValue("parent_cid"),
|
||||
Name: types.StringValue("name"),
|
||||
Members: types.ListNull(types.ObjectType{AttrTypes: memberTypes}),
|
||||
},
|
||||
&map[string]string{
|
||||
"label1": "ref1",
|
||||
|
|
@ -95,7 +91,6 @@ func TestMapProjectFields(t *testing.T) {
|
|||
ProjectId: types.StringValue("pid"),
|
||||
ContainerParentId: types.StringValue(testUUID),
|
||||
Name: types.StringValue("name"),
|
||||
Members: types.ListNull(types.ObjectType{AttrTypes: memberTypes}),
|
||||
},
|
||||
&map[string]string{
|
||||
"label1": "ref1",
|
||||
|
|
@ -138,7 +133,6 @@ func TestMapProjectFields(t *testing.T) {
|
|||
model := &Model{
|
||||
ContainerId: tt.expected.ContainerId,
|
||||
ContainerParentId: containerParentId,
|
||||
Members: types.ListNull(types.ObjectType{AttrTypes: memberTypes}),
|
||||
}
|
||||
|
||||
err := mapProjectFields(context.Background(), tt.projectResp, model, nil)
|
||||
|
|
@ -158,195 +152,22 @@ func TestMapProjectFields(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestMapMembersFields(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
configMembers basetypes.ListValue
|
||||
membersResp *[]authorization.Member
|
||||
expected Model
|
||||
expectedLabels *map[string]string
|
||||
isValid bool
|
||||
}{
|
||||
{
|
||||
"default_ok",
|
||||
types.ListNull(types.ObjectType{AttrTypes: memberTypes}),
|
||||
&[]authorization.Member{
|
||||
{
|
||||
Subject: utils.Ptr("owner_email"),
|
||||
Role: utils.Ptr("owner"),
|
||||
},
|
||||
{
|
||||
Subject: utils.Ptr("reader_email"),
|
||||
Role: utils.Ptr("reader"),
|
||||
},
|
||||
},
|
||||
Model{
|
||||
Id: types.StringNull(),
|
||||
ProjectId: types.StringNull(),
|
||||
ContainerId: types.StringNull(),
|
||||
ContainerParentId: types.StringNull(),
|
||||
Name: types.StringNull(),
|
||||
Labels: types.MapNull(types.StringType),
|
||||
Members: types.ListValueMust(types.ObjectType{AttrTypes: memberTypes}, []attr.Value{
|
||||
types.ObjectValueMust(
|
||||
memberTypes,
|
||||
map[string]attr.Value{
|
||||
"subject": types.StringValue("owner_email"),
|
||||
"role": types.StringValue("owner"),
|
||||
},
|
||||
),
|
||||
types.ObjectValueMust(
|
||||
memberTypes,
|
||||
map[string]attr.Value{
|
||||
"subject": types.StringValue("reader_email"),
|
||||
"role": types.StringValue("reader"),
|
||||
},
|
||||
),
|
||||
}),
|
||||
},
|
||||
nil,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"default_ok (preserve model order)",
|
||||
types.ListValueMust(types.ObjectType{AttrTypes: memberTypes}, []attr.Value{
|
||||
types.ObjectValueMust(
|
||||
memberTypes,
|
||||
map[string]attr.Value{
|
||||
"subject": types.StringValue("reader_email"),
|
||||
"role": types.StringValue("reader"),
|
||||
},
|
||||
),
|
||||
types.ObjectValueMust(
|
||||
memberTypes,
|
||||
map[string]attr.Value{
|
||||
"subject": types.StringValue("owner_email"),
|
||||
"role": types.StringValue("owner"),
|
||||
},
|
||||
),
|
||||
}),
|
||||
&[]authorization.Member{
|
||||
{
|
||||
Subject: utils.Ptr("owner_email"),
|
||||
Role: utils.Ptr("owner"),
|
||||
},
|
||||
{
|
||||
Subject: utils.Ptr("reader_email"),
|
||||
Role: utils.Ptr("reader"),
|
||||
},
|
||||
},
|
||||
Model{
|
||||
Id: types.StringNull(),
|
||||
ProjectId: types.StringNull(),
|
||||
ContainerId: types.StringNull(),
|
||||
ContainerParentId: types.StringNull(),
|
||||
Name: types.StringNull(),
|
||||
Labels: types.MapNull(types.StringType),
|
||||
Members: types.ListValueMust(types.ObjectType{AttrTypes: memberTypes}, []attr.Value{
|
||||
types.ObjectValueMust(
|
||||
memberTypes,
|
||||
map[string]attr.Value{
|
||||
"subject": types.StringValue("reader_email"),
|
||||
"role": types.StringValue("reader"),
|
||||
},
|
||||
),
|
||||
types.ObjectValueMust(
|
||||
memberTypes,
|
||||
map[string]attr.Value{
|
||||
"subject": types.StringValue("owner_email"),
|
||||
"role": types.StringValue("owner"),
|
||||
},
|
||||
),
|
||||
}),
|
||||
},
|
||||
nil,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"empty members",
|
||||
types.ListNull(types.ObjectType{AttrTypes: memberTypes}),
|
||||
&[]authorization.Member{},
|
||||
Model{
|
||||
Id: types.StringNull(),
|
||||
ProjectId: types.StringNull(),
|
||||
ContainerId: types.StringNull(),
|
||||
ContainerParentId: types.StringNull(),
|
||||
Name: types.StringNull(),
|
||||
Labels: types.MapNull(types.StringType),
|
||||
Members: types.ListValueMust(types.ObjectType{AttrTypes: memberTypes}, []attr.Value{}),
|
||||
},
|
||||
nil,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"nil members",
|
||||
types.ListNull(types.ObjectType{AttrTypes: memberTypes}),
|
||||
nil,
|
||||
Model{
|
||||
Id: types.StringNull(),
|
||||
ProjectId: types.StringNull(),
|
||||
ContainerId: types.StringNull(),
|
||||
ContainerParentId: types.StringNull(),
|
||||
Name: types.StringNull(),
|
||||
Members: types.ListNull(types.ObjectType{AttrTypes: memberTypes}),
|
||||
Labels: types.MapNull(types.StringType),
|
||||
},
|
||||
nil,
|
||||
true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.description, func(t *testing.T) {
|
||||
state := &Model{
|
||||
Id: types.StringNull(),
|
||||
ProjectId: types.StringNull(),
|
||||
ContainerId: types.StringNull(),
|
||||
ContainerParentId: types.StringNull(),
|
||||
Name: types.StringNull(),
|
||||
Labels: types.MapNull(types.StringType),
|
||||
}
|
||||
if !tt.configMembers.IsNull() {
|
||||
state.Members = tt.configMembers
|
||||
}
|
||||
err := mapMembersFields(context.Background(), tt.membersResp, state)
|
||||
if !tt.isValid && err == nil {
|
||||
t.Fatalf("Should have failed")
|
||||
}
|
||||
if tt.isValid && err != nil {
|
||||
t.Fatalf("Should not have failed: %v", err)
|
||||
}
|
||||
if tt.isValid {
|
||||
diff := cmp.Diff(state, &tt.expected)
|
||||
if diff != "" {
|
||||
t.Fatalf("Data does not match: %s", diff)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestToCreatePayload(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
input *Model
|
||||
input *ResourceModel
|
||||
inputLabels *map[string]string
|
||||
expected *resourcemanager.CreateProjectPayload
|
||||
isValid bool
|
||||
}{
|
||||
{
|
||||
"mapping_with_conversions_single_member",
|
||||
&Model{
|
||||
ContainerParentId: types.StringValue("pid"),
|
||||
Name: types.StringValue("name"),
|
||||
Members: types.ListValueMust(types.ObjectType{AttrTypes: memberTypes}, []attr.Value{
|
||||
types.ObjectValueMust(
|
||||
memberTypes,
|
||||
map[string]attr.Value{
|
||||
"subject": types.StringValue("owner_email"),
|
||||
"role": types.StringValue("owner"),
|
||||
},
|
||||
),
|
||||
}),
|
||||
"mapping_with_conversions",
|
||||
&ResourceModel{
|
||||
Model: Model{
|
||||
ContainerParentId: types.StringValue("pid"),
|
||||
Name: types.StringValue("name"),
|
||||
},
|
||||
OwnerEmail: types.StringValue("john.doe@stackit.cloud"),
|
||||
},
|
||||
&map[string]string{
|
||||
"label1": "1",
|
||||
|
|
@ -360,7 +181,7 @@ func TestToCreatePayload(t *testing.T) {
|
|||
},
|
||||
Members: &[]resourcemanager.Member{
|
||||
{
|
||||
Subject: utils.Ptr("owner_email"),
|
||||
Subject: utils.Ptr("john.doe@stackit.cloud"),
|
||||
Role: utils.Ptr("owner"),
|
||||
},
|
||||
},
|
||||
|
|
@ -369,119 +190,12 @@ func TestToCreatePayload(t *testing.T) {
|
|||
true,
|
||||
},
|
||||
{
|
||||
"mapping_with_conversions_ok_multiple_members",
|
||||
&Model{
|
||||
ContainerParentId: types.StringValue("pid"),
|
||||
Name: types.StringValue("name"),
|
||||
Members: types.ListValueMust(types.ObjectType{AttrTypes: memberTypes}, []attr.Value{
|
||||
types.ObjectValueMust(
|
||||
memberTypes,
|
||||
map[string]attr.Value{
|
||||
"subject": types.StringValue("owner_email"),
|
||||
"role": types.StringValue("owner"),
|
||||
},
|
||||
),
|
||||
types.ObjectValueMust(
|
||||
memberTypes,
|
||||
map[string]attr.Value{
|
||||
"subject": types.StringValue("reader_email"),
|
||||
"role": types.StringValue("reader"),
|
||||
},
|
||||
),
|
||||
}),
|
||||
},
|
||||
&map[string]string{
|
||||
"label1": "1",
|
||||
"label2": "2",
|
||||
},
|
||||
&resourcemanager.CreateProjectPayload{
|
||||
ContainerParentId: utils.Ptr("pid"),
|
||||
Labels: &map[string]string{
|
||||
"label1": "1",
|
||||
"label2": "2",
|
||||
"no owner_email fails",
|
||||
&ResourceModel{
|
||||
Model: Model{
|
||||
ContainerParentId: types.StringValue("pid"),
|
||||
Name: types.StringValue("name"),
|
||||
},
|
||||
Members: &[]resourcemanager.Member{
|
||||
{
|
||||
Subject: utils.Ptr("owner_email"),
|
||||
Role: utils.Ptr("owner"),
|
||||
},
|
||||
{
|
||||
Subject: utils.Ptr("reader_email"),
|
||||
Role: utils.Ptr("reader"),
|
||||
},
|
||||
},
|
||||
Name: utils.Ptr("name"),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"new members field takes precedence over deprecated owner_email field",
|
||||
&Model{
|
||||
ContainerParentId: types.StringValue("pid"),
|
||||
Name: types.StringValue("name"),
|
||||
OwnerEmail: types.StringValue("some_email_deprecated"),
|
||||
Members: types.ListValueMust(types.ObjectType{AttrTypes: memberTypes}, []attr.Value{
|
||||
types.ObjectValueMust(
|
||||
memberTypes,
|
||||
map[string]attr.Value{
|
||||
"subject": types.StringValue("owner_email"),
|
||||
"role": types.StringValue("owner"),
|
||||
},
|
||||
),
|
||||
}),
|
||||
},
|
||||
&map[string]string{
|
||||
"label1": "1",
|
||||
"label2": "2",
|
||||
},
|
||||
&resourcemanager.CreateProjectPayload{
|
||||
ContainerParentId: utils.Ptr("pid"),
|
||||
Labels: &map[string]string{
|
||||
"label1": "1",
|
||||
"label2": "2",
|
||||
},
|
||||
Members: &[]resourcemanager.Member{
|
||||
{
|
||||
Subject: utils.Ptr("owner_email"),
|
||||
Role: utils.Ptr("owner"),
|
||||
},
|
||||
},
|
||||
Name: utils.Ptr("name"),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"deprecated owner_email field still works",
|
||||
&Model{
|
||||
ContainerParentId: types.StringValue("pid"),
|
||||
Name: types.StringValue("name"),
|
||||
OwnerEmail: types.StringValue("some_email_deprecated"),
|
||||
},
|
||||
&map[string]string{
|
||||
"label1": "1",
|
||||
"label2": "2",
|
||||
},
|
||||
&resourcemanager.CreateProjectPayload{
|
||||
ContainerParentId: utils.Ptr("pid"),
|
||||
Labels: &map[string]string{
|
||||
"label1": "1",
|
||||
"label2": "2",
|
||||
},
|
||||
Members: &[]resourcemanager.Member{
|
||||
{
|
||||
Subject: utils.Ptr("some_email_deprecated"),
|
||||
Role: utils.Ptr("owner"),
|
||||
},
|
||||
},
|
||||
Name: utils.Ptr("name"),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"no members or owner_email fails",
|
||||
&Model{
|
||||
ContainerParentId: types.StringValue("pid"),
|
||||
Name: types.StringValue("name"),
|
||||
},
|
||||
&map[string]string{},
|
||||
nil,
|
||||
|
|
@ -508,7 +222,7 @@ func TestToCreatePayload(t *testing.T) {
|
|||
tt.input.Labels = convertedLabels
|
||||
}
|
||||
}
|
||||
output, err := toCreatePayload(context.Background(), tt.input)
|
||||
output, err := toCreatePayload(tt.input)
|
||||
if !tt.isValid && err == nil {
|
||||
t.Fatalf("Should have failed")
|
||||
}
|
||||
|
|
@ -528,14 +242,14 @@ func TestToCreatePayload(t *testing.T) {
|
|||
func TestToUpdatePayload(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
input *Model
|
||||
input *ResourceModel
|
||||
inputLabels *map[string]string
|
||||
expected *resourcemanager.PartialUpdateProjectPayload
|
||||
isValid bool
|
||||
}{
|
||||
{
|
||||
"default_ok",
|
||||
&Model{},
|
||||
&ResourceModel{},
|
||||
nil,
|
||||
&resourcemanager.PartialUpdateProjectPayload{
|
||||
ContainerParentId: nil,
|
||||
|
|
@ -546,10 +260,12 @@ func TestToUpdatePayload(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"mapping_with_conversions_ok",
|
||||
&Model{
|
||||
ContainerParentId: types.StringValue("pid"),
|
||||
Name: types.StringValue("name"),
|
||||
OwnerEmail: types.StringValue("owner_email"),
|
||||
&ResourceModel{
|
||||
Model: Model{
|
||||
ContainerParentId: types.StringValue("pid"),
|
||||
Name: types.StringValue("name"),
|
||||
},
|
||||
OwnerEmail: types.StringValue("owner_email"),
|
||||
},
|
||||
&map[string]string{
|
||||
"label1": "1",
|
||||
|
|
@ -602,3 +318,57 @@ func TestToUpdatePayload(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestToMembersPayload(t *testing.T) {
|
||||
type args struct {
|
||||
model *ResourceModel
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *[]resourcemanager.Member
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "missing model",
|
||||
args: args{},
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "empty model",
|
||||
args: args{
|
||||
model: &ResourceModel{},
|
||||
},
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "ok",
|
||||
args: args{
|
||||
model: &ResourceModel{
|
||||
OwnerEmail: types.StringValue("john.doe@stackit.cloud"),
|
||||
},
|
||||
},
|
||||
want: &[]resourcemanager.Member{
|
||||
{
|
||||
Subject: utils.Ptr("john.doe@stackit.cloud"),
|
||||
Role: utils.Ptr("owner"),
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := toMembersPayload(tt.args.model)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("toMembersPayload() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("toMembersPayload() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue