Skip to content

Commit 84513be

Browse files
author
Cristina Sánchez Sánchez
committed
WIP- Created resource
1 parent f166785 commit 84513be

File tree

7 files changed

+602
-0
lines changed

7 files changed

+602
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package clouduserprojectassignment_test
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/acc"
8+
)
9+
10+
func TestMain(m *testing.M) {
11+
cleanup := acc.SetupSharedResources()
12+
exitCode := m.Run()
13+
cleanup()
14+
os.Exit(exitCode)
15+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package clouduserprojectassignment
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-framework/diag"
7+
"github.com/hashicorp/terraform-plugin-framework/types"
8+
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
9+
"go.mongodb.org/atlas-sdk/v20250312005/admin"
10+
)
11+
12+
// TODO: `ctx` parameter and `diags` return value can be removed if tf schema has no complex data types (e.g., schema.ListAttribute, schema.SetAttribute)
13+
func NewTFModel(ctx context.Context, projectID string, apiResp *admin.GroupUserResponse) (*TFModel, diag.Diagnostics) {
14+
diags := diag.Diagnostics{}
15+
16+
if apiResp == nil {
17+
return nil, diags
18+
}
19+
20+
roles := conversion.TFSetValueOrNull(ctx, &apiResp.Roles, types.StringType)
21+
22+
return &TFModel{
23+
Country: types.StringPointerValue(apiResp.Country),
24+
CreatedAt: types.StringPointerValue(conversion.TimePtrToStringPtr(apiResp.CreatedAt)),
25+
FirstName: types.StringPointerValue(apiResp.FirstName),
26+
ProjectId: types.StringValue(projectID),
27+
UserId: types.StringValue(apiResp.GetId()),
28+
InvitationCreatedAt: types.StringPointerValue(conversion.TimePtrToStringPtr(apiResp.InvitationCreatedAt)),
29+
InvitationExpiresAt: types.StringPointerValue(conversion.TimePtrToStringPtr(apiResp.InvitationExpiresAt)),
30+
InviterUsername: types.StringPointerValue(apiResp.InviterUsername),
31+
LastAuth: types.StringPointerValue(conversion.TimePtrToStringPtr(apiResp.LastAuth)),
32+
LastName: types.StringPointerValue(apiResp.LastName),
33+
MobileNumber: types.StringPointerValue(apiResp.MobileNumber),
34+
OrgMembershipStatus: types.StringValue(apiResp.GetOrgMembershipStatus()),
35+
Roles: roles,
36+
Username: types.StringValue(apiResp.GetUsername()),
37+
}, diags
38+
}
39+
40+
41+
func NewProjectUserReq(ctx context.Context, plan *TFModel) (*admin.GroupUserRequest, diag.Diagnostics) {
42+
var roleNames []string
43+
if !plan.Roles.IsNull() && !plan.Roles.IsUnknown() {
44+
roleNames = conversion.TypesSetToString(ctx, plan.Roles)
45+
}
46+
47+
48+
addProjectUserReq := admin.GroupUserRequest{
49+
Username: plan.Username.ValueString(),
50+
Roles: roleNames,
51+
}
52+
return &addProjectUserReq, nil
53+
}
54+
55+
func NewAtlasUpdateReq(ctx context.Context, plan *TFModel, state *TFModel) (addRequests []*admin.AddOrRemoveGroupRole, removeRequests []*admin.AddOrRemoveGroupRole, diags diag.Diagnostics) {
56+
diags = diag.Diagnostics{}
57+
var currentRoles, desiredRoles []string
58+
if !state.Roles.IsNull() && !state.Roles.IsUnknown() {
59+
currentRoles = conversion.TypesSetToString(ctx, state.Roles)
60+
}
61+
if !plan.Roles.IsNull() && !plan.Roles.IsUnknown() {
62+
desiredRoles = conversion.TypesSetToString(ctx, plan.Roles)
63+
}
64+
65+
rolesToAdd, rolesToRemove := diffRoles(currentRoles, desiredRoles)
66+
67+
addRequests = make([]*admin.AddOrRemoveGroupRole, 0, len(rolesToAdd))
68+
for _, role := range rolesToAdd {
69+
addRequests = append(addRequests, &admin.AddOrRemoveGroupRole{
70+
GroupRole: role,
71+
})
72+
}
73+
74+
removeRequests = make([]*admin.AddOrRemoveGroupRole, 0, len(rolesToRemove))
75+
for _, role := range rolesToRemove {
76+
removeRequests = append(removeRequests, &admin.AddOrRemoveGroupRole{
77+
GroupRole: role,
78+
})
79+
}
80+
81+
return addRequests, removeRequests, nil
82+
}
83+
84+
func diffRoles(oldRoles, newRoles []string) (toAdd, toRemove []string) {
85+
86+
oldRolesMap := make(map[string]bool, len(oldRoles))
87+
newRolesMap := make(map[string]bool, len(newRoles))
88+
89+
for _, role := range oldRoles {
90+
oldRolesMap[role] = true
91+
}
92+
93+
for _, role := range newRoles {
94+
newRolesMap[role] = true
95+
if !oldRolesMap[role] {
96+
toAdd = append(toAdd, role)
97+
}
98+
}
99+
100+
for _, role := range oldRoles {
101+
if !newRolesMap[role] {
102+
toRemove = append(toRemove, role)
103+
}
104+
}
105+
106+
return toAdd, toRemove
107+
}
108+
109+
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package clouduserprojectassignment_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/mongodb/terraform-provider-mongodbatlas/internal/service/clouduserprojectassignment"
9+
// "go.mongodb.org/atlas-sdk/v20231115003/admin" use latest version
10+
)
11+
12+
type sdkToTFModelTestCase struct {
13+
SDKResp *admin.CloudUserProjectAssignment
14+
expectedTFModel *clouduserprojectassignment.TFModel
15+
}
16+
17+
func TestCloudUserProjectAssignmentSDKToTFModel(t *testing.T) {
18+
testCases := map[string]sdkToTFModelTestCase{ // TODO: consider adding test cases to contemplate all possible API responses
19+
"Complete SDK response": {
20+
SDKResp: &admin.CloudUserProjectAssignment{
21+
},
22+
expectedTFModel: &clouduserprojectassignment.TFModel{
23+
},
24+
},
25+
}
26+
27+
for testName, tc := range testCases {
28+
t.Run(testName, func(t *testing.T) {
29+
resultModel, diags := clouduserprojectassignment.NewTFModel(context.Background(), tc.SDKResp)
30+
if diags.HasError() {
31+
t.Errorf("unexpected errors found: %s", diags.Errors()[0].Summary())
32+
}
33+
assert.Equal(t, tc.expectedTFModel, resultModel, "created terraform model did not match expected output")
34+
})
35+
}
36+
}
37+
38+
39+
type tfToSDKModelTestCase struct {
40+
tfModel *clouduserprojectassignment.TFModel
41+
expectedSDKReq *admin.CloudUserProjectAssignment
42+
}
43+
44+
func TestCloudUserProjectAssignmentTFModelToSDK(t *testing.T) {
45+
testCases := map[string]tfToSDKModelTestCase{
46+
"Complete TF state": {
47+
tfModel: &clouduserprojectassignment.TFModel{
48+
},
49+
expectedSDKReq: &admin.CloudUserProjectAssignment{
50+
},
51+
},
52+
}
53+
54+
for testName, tc := range testCases {
55+
t.Run(testName, func(t *testing.T) {
56+
apiReqResult, diags := clouduserprojectassignment.NewAtlasReq(context.Background(), tc.tfModel)
57+
if diags.HasError() {
58+
t.Errorf("unexpected errors found: %s", diags.Errors()[0].Summary())
59+
}
60+
assert.Equal(t, tc.expectedSDKReq, apiReqResult, "created sdk model did not match expected output")
61+
})
62+
}
63+
}
64+
65+

0 commit comments

Comments
 (0)