Skip to content

Commit

Permalink
test: add unit test to database_user resource (#1738)
Browse files Browse the repository at this point in the history
* move model methods to model file

* public struct

* initial tests

* add rest of model tests

* move model methods and add tests

* move last model methods

* typo

* use asser
  • Loading branch information
oarbusi authored Dec 13, 2023
1 parent 42f0f37 commit 5526472
Show file tree
Hide file tree
Showing 5 changed files with 583 additions and 249 deletions.
35 changes: 6 additions & 29 deletions internal/service/databaseuser/data_source_database_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@ package databaseuser

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/config"
"go.mongodb.org/atlas-sdk/v20231115002/admin"
)

type databaseUserDS struct {
Expand All @@ -24,7 +21,7 @@ func DataSource() datasource.DataSource {
}
}

type tfDatabaseUserDSModel struct {
type TfDatabaseUserDSModel struct {
ID types.String `tfsdk:"id"`
ProjectID types.String `tfsdk:"project_id"`
AuthDatabaseName types.String `tfsdk:"auth_database_name"`
Expand All @@ -34,9 +31,9 @@ type tfDatabaseUserDSModel struct {
OIDCAuthType types.String `tfsdk:"oidc_auth_type"`
LDAPAuthType types.String `tfsdk:"ldap_auth_type"`
AWSIAMType types.String `tfsdk:"aws_iam_type"`
Roles []tfRoleModel `tfsdk:"roles"`
Labels []tfLabelModel `tfsdk:"labels"`
Scopes []tfScopeModel `tfsdk:"scopes"`
Roles []TfRoleModel `tfsdk:"roles"`
Labels []TfLabelModel `tfsdk:"labels"`
Scopes []TfScopeModel `tfsdk:"scopes"`
}

var _ datasource.DataSource = &databaseUserDS{}
Expand Down Expand Up @@ -120,7 +117,7 @@ func (d *databaseUserDS) Schema(ctx context.Context, req datasource.SchemaReques
}

func (d *databaseUserDS) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var databaseDSUserModel *tfDatabaseUserDSModel
var databaseDSUserModel *TfDatabaseUserDSModel
var err error
resp.Diagnostics.Append(req.Config.Get(ctx, &databaseDSUserModel)...)
if resp.Diagnostics.HasError() {
Expand All @@ -138,7 +135,7 @@ func (d *databaseUserDS) Read(ctx context.Context, req datasource.ReadRequest, r
return
}

dbUserModel, diagnostic := newTFDatabaseDSUserModel(ctx, dbUser)
dbUserModel, diagnostic := NewTFDatabaseDSUserModel(ctx, dbUser)
resp.Diagnostics.Append(diagnostic...)
if resp.Diagnostics.HasError() {
return
Expand All @@ -149,23 +146,3 @@ func (d *databaseUserDS) Read(ctx context.Context, req datasource.ReadRequest, r
return
}
}

func newTFDatabaseDSUserModel(ctx context.Context, dbUser *admin.CloudDatabaseUser) (*tfDatabaseUserDSModel, diag.Diagnostics) {
id := fmt.Sprintf("%s-%s-%s", dbUser.GroupId, dbUser.Username, dbUser.DatabaseName)
databaseUserModel := &tfDatabaseUserDSModel{
ID: types.StringValue(id),
ProjectID: types.StringValue(dbUser.GroupId),
AuthDatabaseName: types.StringValue(dbUser.DatabaseName),
Username: types.StringValue(dbUser.Username),
Password: types.StringValue(dbUser.GetPassword()),
X509Type: types.StringValue(dbUser.GetX509Type()),
OIDCAuthType: types.StringValue(dbUser.GetOidcAuthType()),
LDAPAuthType: types.StringValue(dbUser.GetLdapAuthType()),
AWSIAMType: types.StringValue(dbUser.GetAwsIAMType()),
Roles: newTFRolesModel(dbUser.Roles),
Labels: newTFLabelsModel(dbUser.Labels),
Scopes: newTFScopesModel(dbUser.Scopes),
}

return databaseUserModel, nil
}
28 changes: 4 additions & 24 deletions internal/service/databaseuser/data_source_database_users.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ import (

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/config"
"go.mongodb.org/atlas-sdk/v20231115002/admin"
)

const (
Expand All @@ -31,10 +28,10 @@ func PluralDataSource() datasource.DataSource {
var _ datasource.DataSource = &DatabaseUsersDS{}
var _ datasource.DataSourceWithConfigure = &DatabaseUsersDS{}

type tfDatabaseUsersDSModel struct {
type TfDatabaseUsersDSModel struct {
ID types.String `tfsdk:"id"`
ProjectID types.String `tfsdk:"project_id"`
Results []*tfDatabaseUserDSModel `tfsdk:"results"`
Results []*TfDatabaseUserDSModel `tfsdk:"results"`
}

func (d *DatabaseUsersDS) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
Expand Down Expand Up @@ -129,7 +126,7 @@ func (d *DatabaseUsersDS) Schema(ctx context.Context, req datasource.SchemaReque
}

func (d *DatabaseUsersDS) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var databaseUsersModel *tfDatabaseUsersDSModel
var databaseUsersModel *TfDatabaseUsersDSModel
var err error
resp.Diagnostics.Append(req.Config.Get(ctx, &databaseUsersModel)...)
if resp.Diagnostics.HasError() {
Expand All @@ -144,7 +141,7 @@ func (d *DatabaseUsersDS) Read(ctx context.Context, req datasource.ReadRequest,
return
}

dbUserModel, diagnostic := newTFDatabaseUsersMode(ctx, projectID, dbUser.GetResults())
dbUserModel, diagnostic := NewTFDatabaseUsersModel(ctx, projectID, dbUser.GetResults())
resp.Diagnostics.Append(diagnostic...)
if resp.Diagnostics.HasError() {
return
Expand All @@ -155,20 +152,3 @@ func (d *DatabaseUsersDS) Read(ctx context.Context, req datasource.ReadRequest,
return
}
}

func newTFDatabaseUsersMode(ctx context.Context, projectID string, dbUsers []admin.CloudDatabaseUser) (*tfDatabaseUsersDSModel, diag.Diagnostics) {
results := make([]*tfDatabaseUserDSModel, len(dbUsers))
for i := range dbUsers {
dbUserModel, d := newTFDatabaseDSUserModel(ctx, &dbUsers[i])
if d.HasError() {
return nil, d
}
results[i] = dbUserModel
}

return &tfDatabaseUsersDSModel{
ProjectID: types.StringValue(projectID),
Results: results,
ID: types.StringValue(id.UniqueId()),
}, nil
}
229 changes: 229 additions & 0 deletions internal/service/databaseuser/model_database_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
package databaseuser

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
"go.mongodb.org/atlas-sdk/v20231115002/admin"
)

func NewMongoDBDatabaseUser(ctx context.Context, dbUserModel *TfDatabaseUserModel) (*admin.CloudDatabaseUser, diag.Diagnostics) {
var rolesModel []*TfRoleModel
var labelsModel []*TfLabelModel
var scopesModel []*TfScopeModel

diags := dbUserModel.Roles.ElementsAs(ctx, &rolesModel, false)
if diags.HasError() {
return nil, diags
}

diags = dbUserModel.Labels.ElementsAs(ctx, &labelsModel, false)
if diags.HasError() {
return nil, diags
}

diags = dbUserModel.Scopes.ElementsAs(ctx, &scopesModel, false)
if diags.HasError() {
return nil, diags
}

return &admin.CloudDatabaseUser{
GroupId: dbUserModel.ProjectID.ValueString(),
Username: dbUserModel.Username.ValueString(),
Password: dbUserModel.Password.ValueStringPointer(),
X509Type: dbUserModel.X509Type.ValueStringPointer(),
AwsIAMType: dbUserModel.AWSIAMType.ValueStringPointer(),
OidcAuthType: dbUserModel.OIDCAuthType.ValueStringPointer(),
LdapAuthType: dbUserModel.LDAPAuthType.ValueStringPointer(),
DatabaseName: dbUserModel.AuthDatabaseName.ValueString(),
Roles: NewMongoDBAtlasRoles(rolesModel),
Labels: NewMongoDBAtlasLabels(labelsModel),
Scopes: NewMongoDBAtlasScopes(scopesModel),
}, nil
}

func NewTfDatabaseUserModel(ctx context.Context, model *TfDatabaseUserModel, dbUser *admin.CloudDatabaseUser) (*TfDatabaseUserModel, diag.Diagnostics) {
rolesSet, diagnostic := types.SetValueFrom(ctx, RoleObjectType, NewTFRolesModel(dbUser.Roles))
if diagnostic.HasError() {
return nil, diagnostic
}

labelsSet, diagnostic := types.SetValueFrom(ctx, LabelObjectType, NewTFLabelsModel(dbUser.Labels))
if diagnostic.HasError() {
return nil, diagnostic
}

scopesSet, diagnostic := types.SetValueFrom(ctx, ScopeObjectType, NewTFScopesModel(dbUser.Scopes))
if diagnostic.HasError() {
return nil, diagnostic
}

// ID is encoded to preserve format defined in previous versions.
encodedID := conversion.EncodeStateID(map[string]string{
"project_id": dbUser.GroupId,
"username": dbUser.Username,
"auth_database_name": dbUser.DatabaseName,
})
databaseUserModel := &TfDatabaseUserModel{
ID: types.StringValue(encodedID),
ProjectID: types.StringValue(dbUser.GroupId),
AuthDatabaseName: types.StringValue(dbUser.DatabaseName),
Username: types.StringValue(dbUser.Username),
X509Type: types.StringValue(dbUser.GetX509Type()),
OIDCAuthType: types.StringValue(dbUser.GetOidcAuthType()),
LDAPAuthType: types.StringValue(dbUser.GetLdapAuthType()),
AWSIAMType: types.StringValue(dbUser.GetAwsIAMType()),
Roles: rolesSet,
Labels: labelsSet,
Scopes: scopesSet,
}

if model != nil && model.Password.ValueString() != "" {
// The Password is not retuned from the endpoint so we use the one provided in the model
databaseUserModel.Password = model.Password
}

return databaseUserModel, nil
}

func NewTFDatabaseDSUserModel(ctx context.Context, dbUser *admin.CloudDatabaseUser) (*TfDatabaseUserDSModel, diag.Diagnostics) {
databaseID := fmt.Sprintf("%s-%s-%s", dbUser.GroupId, dbUser.Username, dbUser.DatabaseName)
databaseUserModel := &TfDatabaseUserDSModel{
ID: types.StringValue(databaseID),
ProjectID: types.StringValue(dbUser.GroupId),
AuthDatabaseName: types.StringValue(dbUser.DatabaseName),
Username: types.StringValue(dbUser.Username),
Password: types.StringValue(dbUser.GetPassword()),
X509Type: types.StringValue(dbUser.GetX509Type()),
OIDCAuthType: types.StringValue(dbUser.GetOidcAuthType()),
LDAPAuthType: types.StringValue(dbUser.GetLdapAuthType()),
AWSIAMType: types.StringValue(dbUser.GetAwsIAMType()),
Roles: NewTFRolesModel(dbUser.Roles),
Labels: NewTFLabelsModel(dbUser.Labels),
Scopes: NewTFScopesModel(dbUser.Scopes),
}

return databaseUserModel, nil
}

func NewTFDatabaseUsersModel(ctx context.Context, projectID string, dbUsers []admin.CloudDatabaseUser) (*TfDatabaseUsersDSModel, diag.Diagnostics) {
results := make([]*TfDatabaseUserDSModel, len(dbUsers))
for i := range dbUsers {
dbUserModel, d := NewTFDatabaseDSUserModel(ctx, &dbUsers[i])
if d.HasError() {
return nil, d
}
results[i] = dbUserModel
}

return &TfDatabaseUsersDSModel{
ProjectID: types.StringValue(projectID),
Results: results,
ID: types.StringValue(id.UniqueId()),
}, nil
}

func NewTFScopesModel(scopes []admin.UserScope) []TfScopeModel {
if len(scopes) == 0 {
return nil
}

out := make([]TfScopeModel, len(scopes))
for i, v := range scopes {
out[i] = TfScopeModel{
Name: types.StringValue(v.Name),
Type: types.StringValue(v.Type),
}
}

return out
}

func NewMongoDBAtlasLabels(labels []*TfLabelModel) []admin.ComponentLabel {
if len(labels) == 0 {
return []admin.ComponentLabel{}
}

out := make([]admin.ComponentLabel, len(labels))
for i, v := range labels {
out[i] = admin.ComponentLabel{
Key: v.Key.ValueStringPointer(),
Value: v.Value.ValueStringPointer(),
}
}

return out
}

func NewTFLabelsModel(labels []admin.ComponentLabel) []TfLabelModel {
if len(labels) == 0 {
return nil
}

out := make([]TfLabelModel, len(labels))
for i, v := range labels {
out[i] = TfLabelModel{
Key: types.StringValue(v.GetKey()),
Value: types.StringValue(v.GetValue()),
}
}

return out
}

func NewMongoDBAtlasScopes(scopes []*TfScopeModel) []admin.UserScope {
if len(scopes) == 0 {
return []admin.UserScope{}
}

out := make([]admin.UserScope, len(scopes))
for i, v := range scopes {
out[i] = admin.UserScope{
Name: v.Name.ValueString(),
Type: v.Type.ValueString(),
}
}

return out
}

func NewTFRolesModel(roles []admin.DatabaseUserRole) []TfRoleModel {
if len(roles) == 0 {
return nil
}

out := make([]TfRoleModel, len(roles))
for i, v := range roles {
out[i] = TfRoleModel{
RoleName: types.StringValue(v.RoleName),
DatabaseName: types.StringValue(v.DatabaseName),
}

if v.GetCollectionName() != "" {
out[i].CollectionName = types.StringValue(v.GetCollectionName())
}
}

return out
}

func NewMongoDBAtlasRoles(roles []*TfRoleModel) []admin.DatabaseUserRole {
if len(roles) == 0 {
return []admin.DatabaseUserRole{}
}

out := make([]admin.DatabaseUserRole, len(roles))
for i, v := range roles {
out[i] = admin.DatabaseUserRole{
RoleName: v.RoleName.ValueString(),
DatabaseName: v.DatabaseName.ValueString(),
CollectionName: v.CollectionName.ValueStringPointer(),
}
}

return out
}
Loading

0 comments on commit 5526472

Please sign in to comment.