From f7874893022e4746bef5ccab7ca3360a3623b312 Mon Sep 17 00:00:00 2001 From: Thomas De Meyer Date: Fri, 16 Aug 2024 13:29:44 +0200 Subject: [PATCH] feat: fixed tests, added additional validations --- .gitignore | 7 +- .../resources/associate_role/resource_test.go | 8 +- .../resources/business_unit_company/model.go | 4 + .../business_unit_company/resource.go | 17 +- .../business_unit_company/resource_test.go | 152 +++++++------ .../resources/business_unit_division/model.go | 4 + .../business_unit_division/resource.go | 42 ++-- .../business_unit_division/resource_test.go | 206 ++++++++++++------ internal/resources/project/upgrade_v1.go | 9 + internal/resources/project/upgrade_v1_test.go | 1 + 10 files changed, 292 insertions(+), 158 deletions(-) diff --git a/.gitignore b/.gitignore index 9504672a..4e2fd302 100644 --- a/.gitignore +++ b/.gitignore @@ -4,17 +4,18 @@ terraform-provider-commercetools_* /dist/* coverage.txt -// Terraform files +# Terraform files .terraform/ terraform.* crash.log -// Local files +# Local files /local/* !/local/*.example -// Go modules +# Go modules vendor/ /.idea +/.env diff --git a/internal/resources/associate_role/resource_test.go b/internal/resources/associate_role/resource_test.go index b1af64eb..2015c30f 100644 --- a/internal/resources/associate_role/resource_test.go +++ b/internal/resources/associate_role/resource_test.go @@ -27,7 +27,7 @@ func TestAssociateRoleResource_Create(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(rn, "name", name), resource.TestCheckResourceAttr(rn, "key", key), - resource.TestCheckResourceAttr(rn, "permissions.#", "7"), + resource.TestCheckResourceAttr(rn, "permissions.#", "6"), ), }, { @@ -35,8 +35,8 @@ func TestAssociateRoleResource_Create(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(rn, "name", "Sales Manager - DACH"), resource.TestCheckResourceAttr(rn, "key", key), - resource.TestCheckResourceAttr(rn, "permissions.#", "8"), - resource.TestCheckResourceAttr(rn, "permissions.7", "AddChildUnits"), + resource.TestCheckResourceAttr(rn, "permissions.#", "7"), + resource.TestCheckResourceAttr(rn, "permissions.6", "AddChildUnits"), resource.TestCheckResourceAttr(rn, "buyer_assignable", "true"), ), }, @@ -55,7 +55,6 @@ func testAssociateRoleConfig(identifier, name, key string) string { buyer_assignable = false name = "{{ .name }}" permissions = [ - "AddChildUnits", "UpdateBusinessUnitDetails", "UpdateAssociates", "CreateMyCarts", @@ -78,7 +77,6 @@ func testAssociateRoleConfigUpdate(identifier, name, key string, buyerAssign boo buyer_assignable = {{ .buyer_assignable }} name = "{{ .name }}" permissions = [ - "AddChildUnits", "UpdateBusinessUnitDetails", "UpdateAssociates", "CreateMyCarts", diff --git a/internal/resources/business_unit_company/model.go b/internal/resources/business_unit_company/model.go index 6927d481..3f41784e 100644 --- a/internal/resources/business_unit_company/model.go +++ b/internal/resources/business_unit_company/model.go @@ -121,6 +121,10 @@ func (c *Company) updateActions(plan Company) (platform.BusinessUnitUpdate, erro Actions: []platform.BusinessUnitUpdateAction{}, } + if !c.Key.Equal(plan.Key) { + return result, fmt.Errorf("key is immutable. Delete this resource instead if a change is intended") + } + if !c.Name.Equal(plan.Name) { result.Actions = append(result.Actions, platform.BusinessUnitChangeNameAction{ Name: plan.Name.ValueString(), diff --git a/internal/resources/business_unit_company/resource.go b/internal/resources/business_unit_company/resource.go index 4a725037..a1351f1b 100644 --- a/internal/resources/business_unit_company/resource.go +++ b/internal/resources/business_unit_company/resource.go @@ -36,20 +36,21 @@ func NewCompanyResource() resource.Resource { // Schema implements resource.Resource. func (b *companyResource) Schema(_ context.Context, req resource.SchemaRequest, res *resource.SchemaResponse) { res.Schema = schema.Schema{ - MarkdownDescription: "Business Unit type to represent the top level of a business. Contains specific fields and values that differentiate a Company from the generic BusinessUnit.\n\n" + + MarkdownDescription: "Business Unit type to represent the top level of a business. Contains specific fields and values that differentiate a company from the generic business unit.\n\n" + "See also the [Business Unit API Documentation](https://docs.commercetools.com/api/projects/business-units", Attributes: map[string]schema.Attribute{ "id": schema.StringAttribute{ - MarkdownDescription: "Unique identifier of the Company.", + MarkdownDescription: "Unique identifier of the company.", Computed: true, }, "version": schema.Int64Attribute{ - MarkdownDescription: "The current version of the Company.", + MarkdownDescription: "The current version of the company.", Computed: true, }, "key": schema.StringAttribute{ - MarkdownDescription: "User-defined unique identifier for the Company.", - Required: true, + MarkdownDescription: "User-defined unique key for the company. Must be unique within the project. " + + "Updating this value is not supported.", + Required: true, Validators: []validator.String{ stringvalidator.LengthBetween(2, 256), stringvalidator.RegexMatches( @@ -59,7 +60,7 @@ func (b *companyResource) Schema(_ context.Context, req resource.SchemaRequest, }, }, "status": schema.StringAttribute{ - MarkdownDescription: "The status of the Company.", + MarkdownDescription: "The status of the company.", Optional: true, Computed: true, Default: stringdefault.StaticString(string(platform.BusinessUnitStatusActive)), @@ -71,11 +72,11 @@ func (b *companyResource) Schema(_ context.Context, req resource.SchemaRequest, }, }, "name": schema.StringAttribute{ - MarkdownDescription: "The name of the Company.", + MarkdownDescription: "The name of the company.", Required: true, }, "contact_email": schema.StringAttribute{ - MarkdownDescription: "The email address of the Company.", + MarkdownDescription: "The email address of the company.", Optional: true, }, "shipping_address_keys": schema.SetAttribute{ diff --git a/internal/resources/business_unit_company/resource_test.go b/internal/resources/business_unit_company/resource_test.go index a8273a1b..1a5a3956 100644 --- a/internal/resources/business_unit_company/resource_test.go +++ b/internal/resources/business_unit_company/resource_test.go @@ -2,7 +2,9 @@ package business_unit_company_test import ( "context" + "github.com/labd/commercetools-go-sdk/platform" "github.com/labd/terraform-provider-commercetools/internal/resources/business_unit_company" + "regexp" "testing" fwresource "github.com/hashicorp/terraform-plugin-framework/resource" @@ -44,26 +46,35 @@ func TestBusinessUnitResource(t *testing.T) { CheckDestroy: testBusinessUnitDestroy, Steps: []resource.TestStep{ { - Config: businessUnitTFResourceDef("", "", ""), + Config: businessUnitTFResourceDef(), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(r, "key", "acme-company"), resource.TestCheckResourceAttr(r, "name", "Acme Company Business Unit"), - resource.TestCheckResourceAttr(r, "status", "Active"), - resource.TestCheckResourceAttr(r, "stores.#", "2"), - resource.TestCheckResourceAttr(r, "stores.0.key", "acme-usa"), - resource.TestCheckResourceAttr(r, "stores.1.key", "acme-germany"), - resource.TestCheckResourceAttr(r, "addresses.#", "1"), + resource.TestCheckResourceAttr(r, "status", string(platform.BusinessUnitConfigurationStatusActive)), + resource.TestCheckResourceAttr(r, "contact_email", "acme@example.com"), + resource.TestCheckResourceAttr(r, "address.#", "1"), ), }, { - Config: businessUnitTFResourceDef("Acme Business Unit - Updated", "Inactive", ""), + Config: businessUnitTFResourceDef(withBusinessUnitCompanyKey("acme-company-updated")), + ExpectError: regexp.MustCompile(`key is immutable`), + }, + { + Config: businessUnitTFResourceDef(withBusinessUnitCompanyName("Acme Business Unit - Updated")), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(r, "key", "acme-company"), - resource.TestCheckResourceAttr(r, "status", "Inactive"), - resource.TestCheckResourceAttr(r, "stores.#", "2"), - resource.TestCheckResourceAttr(r, "stores.0.key", "acme-usa"), - resource.TestCheckResourceAttr(r, "stores.1.key", "acme-germany"), - resource.TestCheckResourceAttr(r, "addresses.#", "1"), + resource.TestCheckResourceAttr(r, "name", "Acme Business Unit - Updated"), + ), + }, + { + Config: businessUnitTFResourceDef(withBusinessUnitCompanyStatus(platform.BusinessUnitConfigurationStatusInactive)), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(r, "status", string(platform.BusinessUnitConfigurationStatusInactive)), + ), + }, + { + Config: businessUnitTFResourceDef(withBusinessUnitCompanyContactEmail("acme-updated@example.com")), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(r, "contact_email", "acme-updated@example.com"), ), }, }, @@ -74,59 +85,76 @@ func testBusinessUnitDestroy(_ *terraform.State) error { return nil } -func businessUnitTFResourceDef(name, status, email string) string { - if status == "" { - status = "Active" +type option func(map[string]interface{}) + +func withBusinessUnitCompanyKey(key string) option { + return func(data map[string]interface{}) { + data["key"] = key + } +} + +func withBusinessUnitCompanyName(name string) option { + return func(data map[string]interface{}) { + data["name"] = name + } +} + +func withBusinessUnitCompanyStatus(status platform.BusinessUnitConfigurationStatus) option { + return func(data map[string]interface{}) { + data["status"] = status } +} - if email == "" { - email = "acme@example.com" +func withBusinessUnitCompanyContactEmail(email string) option { + return func(data map[string]interface{}) { + data["contact_email"] = email } +} - if name == "" { - name = "Acme Company Business Unit" +func businessUnitTFResourceDef(options ...option) string { + data := map[string]interface{}{ + "key": "acme-company", + "status": platform.BusinessUnitConfigurationStatusActive, + "contact_email": "acme@example.com", + "name": "Acme Company Business Unit", } - return utils.HCLTemplate(`resource "commercetools_business_unit_company" "acme_company" { - key = "acme-company" - name = {{ .name }} - status = {{ .status }} - contact_email = {{ .email}} - - store { - key = "acme-usa" - } - - store { - key = "acme-germany" - } - - address { - key = "acme-business-unit-address" - title = "Acme Business Unit Address" - salutation = "Mr." - first_name = "John" - last_name = "Doe" - street_name = "Main Street" - street_number = "1" - additional_street_info = "Additional Street Info" - postal_code = "12345" - city = "Berlin" - region = "Berlin" - country = "DE" - company = "Acme" - department = "IT" - building = "Building" - apartment = "Apartment" - po_box = "P.O. Box" - phone = "123456789" - mobile = "987654321" - } - default_shipping_address_id = "acme-business-unit-address" - default_billing_address_id = "acme-business-unit-address" -}`, map[string]any{ - "name": name, - "status": status, - "email": email, - }) + for _, option := range options { + option(data) + } + + return utils.HCLTemplate(` + resource "commercetools_business_unit_company" "acme_company" { + key = "{{ .key }}" + name = "{{ .name }}" + status = "{{ .status }}" + contact_email = "{{ .contact_email }}" + + address { + key = "acme-business-unit-address" + title = "Acme Business Unit Address" + salutation = "Mr." + first_name = "John" + last_name = "Doe" + street_name = "Main Street" + street_number = "1" + additional_street_info = "Additional Street Info" + postal_code = "12345" + city = "Berlin" + region = "Berlin" + country = "DE" + company = "Acme" + department = "IT" + building = "Building" + apartment = "Apartment" + po_box = "P.O. Box" + phone = "123456789" + mobile = "987654321" + } + shipping_address_keys = ["acme-business-unit-address"] + billing_address_keys = ["acme-business-unit-address"] + default_shipping_address_key = "acme-business-unit-address" + default_billing_address_key = "acme-business-unit-address" + } + `, data) } diff --git a/internal/resources/business_unit_division/model.go b/internal/resources/business_unit_division/model.go index d402fce3..f70062a5 100644 --- a/internal/resources/business_unit_division/model.go +++ b/internal/resources/business_unit_division/model.go @@ -129,6 +129,10 @@ func (d *Division) updateActions(plan Division) (platform.BusinessUnitUpdate, er Actions: []platform.BusinessUnitUpdateAction{}, } + if !d.Key.Equal(plan.Key) { + return result, fmt.Errorf("key is immutable. Delete this resource instead if a change is intended") + } + if !d.Name.Equal(plan.Name) { result.Actions = append(result.Actions, platform.BusinessUnitChangeNameAction{ Name: plan.Name.ValueString(), diff --git a/internal/resources/business_unit_division/resource.go b/internal/resources/business_unit_division/resource.go index 50e2a5d6..0a0174e3 100644 --- a/internal/resources/business_unit_division/resource.go +++ b/internal/resources/business_unit_division/resource.go @@ -3,6 +3,7 @@ package business_unit_division import ( "context" "errors" + "github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/labd/terraform-provider-commercetools/internal/sharedtypes" "regexp" @@ -39,20 +40,21 @@ func NewDivisionResource() resource.Resource { // Schema implements resource.Resource. func (b *divisionResource) Schema(_ context.Context, req resource.SchemaRequest, res *resource.SchemaResponse) { res.Schema = schema.Schema{ - MarkdownDescription: "Business Unit type to represent the top level of a business. Contains specific fields and values that differentiate a Division from the generic BusinessUnit.\n\n" + - "See also the [Business Unit API Documentation](https://docs.commercetools.com/api/projects/business-units", + MarkdownDescription: "business unit type to represent the top level of a business. Contains specific fields and values that differentiate a Division from the generic BusinessUnit.\n\n" + + "See also the [business unit API Documentation](https://docs.commercetools.com/api/projects/business-units", Attributes: map[string]schema.Attribute{ "id": schema.StringAttribute{ - MarkdownDescription: "Unique identifier of the Division.", + MarkdownDescription: "Unique identifier of the division.", Computed: true, }, "version": schema.Int64Attribute{ - MarkdownDescription: "The current version of the Division.", + MarkdownDescription: "The current version of the division.", Computed: true, }, "key": schema.StringAttribute{ - MarkdownDescription: "User-defined unique identifier for the Division.", - Required: true, + MarkdownDescription: "User-defined unique key for the division. Must be unique within the project. " + + "Updating this value is not supported.", + Required: true, Validators: []validator.String{ stringvalidator.LengthBetween(2, 256), stringvalidator.RegexMatches( @@ -62,7 +64,7 @@ func (b *divisionResource) Schema(_ context.Context, req resource.SchemaRequest, }, }, "status": schema.StringAttribute{ - MarkdownDescription: "Indicates whether the Business Unit can be edited and used in [Orders](https://docs.commercetools.com/api/projects/orders). Defaults to `Active`.", + MarkdownDescription: "Indicates whether the business unit can be edited and used in [Orders](https://docs.commercetools.com/api/projects/orders). Defaults to `Active`.", Optional: true, Computed: true, Default: stringdefault.StaticString(string(platform.BusinessUnitStatusActive)), @@ -74,7 +76,7 @@ func (b *divisionResource) Schema(_ context.Context, req resource.SchemaRequest, }, }, "store_mode": schema.StringAttribute{ - MarkdownDescription: "Defines whether the Stores of the Business Unit are set directly on the Business Unit or are inherited from a parent. Defaults to `FromParent`", + MarkdownDescription: "Defines whether the Stores of the business unit are set directly on the business unit or are inherited from a parent. Defaults to `FromParent`", Optional: true, Computed: true, Default: stringdefault.StaticString(string(platform.BusinessUnitStoreModeFromParent)), @@ -86,15 +88,15 @@ func (b *divisionResource) Schema(_ context.Context, req resource.SchemaRequest, }, }, "name": schema.StringAttribute{ - MarkdownDescription: "The name of the Division.", + MarkdownDescription: "The name of the division.", Required: true, }, "contact_email": schema.StringAttribute{ - MarkdownDescription: "The email address of the Division.", + MarkdownDescription: "The email address of the division.", Optional: true, }, "associate_mode": schema.StringAttribute{ - MarkdownDescription: "Determines whether the Business Unit can inherit Associates from a parent. Defaults to `ExplicitAndFromParent`.", + MarkdownDescription: "Determines whether the business unit can inherit Associates from a parent. Defaults to `ExplicitAndFromParent`.", Optional: true, Computed: true, Default: stringdefault.StaticString(string(platform.BusinessUnitAssociateModeExplicitAndFromParent)), @@ -106,7 +108,7 @@ func (b *divisionResource) Schema(_ context.Context, req resource.SchemaRequest, }, }, "approval_rule_mode": schema.StringAttribute{ - MarkdownDescription: "Determines whether the Business Unit can inherit Approval Rules from a parent. Defaults to `ExplicitAndFromParent`.", + MarkdownDescription: "Determines whether the business unit can inherit Approval Rules from a parent. Defaults to `ExplicitAndFromParent`.", Optional: true, Computed: true, Default: stringdefault.StaticString(string(platform.BusinessUnitApprovalRuleModeExplicitAndFromParent)), @@ -118,7 +120,7 @@ func (b *divisionResource) Schema(_ context.Context, req resource.SchemaRequest, }, }, "shipping_address_keys": schema.ListAttribute{ - MarkdownDescription: "List of the shipping addresses used by the Division.", + MarkdownDescription: "List of the shipping addresses used by the division.", Optional: true, ElementType: types.StringType, PlanModifiers: []planmodifier.List{ @@ -130,7 +132,7 @@ func (b *divisionResource) Schema(_ context.Context, req resource.SchemaRequest, Optional: true, }, "billing_address_keys": schema.ListAttribute{ - MarkdownDescription: "List of the billing addresses used by the Division.", + MarkdownDescription: "List of the billing addresses used by the division.", Optional: true, ElementType: types.StringType, PlanModifiers: []planmodifier.List{ @@ -146,14 +148,20 @@ func (b *divisionResource) Schema(_ context.Context, req resource.SchemaRequest, "store": sharedtypes.StoreKeyReferenceBlockSchema, "address": sharedtypes.AddressBlockSchema, "parent_unit": schema.SingleNestedBlock{ - MarkdownDescription: "Reference to a parent Business Unit by its key.", + MarkdownDescription: "Reference to a parent business unit by its key or id. One of either is required.", + Validators: []validator.Object{ + objectvalidator.AtLeastOneOf( + path.MatchRelative().AtName("key"), + path.MatchRelative().AtName("id"), + ), + }, Attributes: map[string]schema.Attribute{ "id": schema.StringAttribute{ - MarkdownDescription: "User-defined unique identifier of the Business Unit", + MarkdownDescription: "User-defined unique identifier of the business unit", Optional: true, }, "key": schema.StringAttribute{ - MarkdownDescription: "User-defined unique key of the Business Unit", + MarkdownDescription: "User-defined unique key of the business unit", Optional: true, }, }, diff --git a/internal/resources/business_unit_division/resource_test.go b/internal/resources/business_unit_division/resource_test.go index 907a871a..cb2ee6ac 100644 --- a/internal/resources/business_unit_division/resource_test.go +++ b/internal/resources/business_unit_division/resource_test.go @@ -2,7 +2,9 @@ package business_unit_division_test import ( "context" + "github.com/labd/commercetools-go-sdk/platform" "github.com/labd/terraform-provider-commercetools/internal/resources/business_unit_division" + "regexp" "testing" fwresource "github.com/hashicorp/terraform-plugin-framework/resource" @@ -41,92 +43,170 @@ func TestBusinessUnitResource_Division(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.TestAccPreCheck(t) }, ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - CheckDestroy: testBusinessUnitDestroy, + CheckDestroy: testBusinessUnitDivisionDestroy, Steps: []resource.TestStep{ { - Config: businessUnitTFResourceDef("", "", ""), + Config: businessUnitDivisionTFResourceDef(), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(r, "key", "acme-division"), resource.TestCheckResourceAttr(r, "name", "Acme Company Business Unit"), + resource.TestCheckResourceAttr(r, "contact_email", "acme@example.com"), resource.TestCheckResourceAttr(r, "status", "Active"), - resource.TestCheckResourceAttr(r, "stores.#", "2"), - resource.TestCheckResourceAttr(r, "stores.0.key", "acme-usa"), - resource.TestCheckResourceAttr(r, "stores.1.key", "acme-germany"), - resource.TestCheckResourceAttr(r, "addresses.#", "1"), + resource.TestCheckResourceAttr(r, "address.#", "1"), ), }, { - Config: businessUnitTFResourceDef("Acme Business Unit - Updated", "Inactive", ""), + Config: businessUnitDivisionTFResourceDef(withBusinessDivisionKey("acme-division-updated")), + ExpectError: regexp.MustCompile(`key is immutable`), + }, + { + Config: businessUnitDivisionTFResourceDef(withBusinessUnitDivisionName("Acme Business Unit - Updated")), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(r, "key", "acme-division"), - resource.TestCheckResourceAttr(r, "status", "Inactive"), - resource.TestCheckResourceAttr(r, "stores.#", "2"), - resource.TestCheckResourceAttr(r, "stores.0.key", "acme-usa"), - resource.TestCheckResourceAttr(r, "stores.1.key", "acme-germany"), - resource.TestCheckResourceAttr(r, "addresses.#", "1"), + resource.TestCheckResourceAttr(r, "name", "Acme Business Unit - Updated"), + ), + }, + { + Config: businessUnitDivisionTFResourceDef(withBusinessUnitDivisionContactEmail("acme-update@example.com")), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(r, "contact_email", "acme-update@example.com"), + ), + }, + { + Config: businessUnitDivisionTFResourceDef(withBusinessUnitDivisionStatus(platform.BusinessUnitConfigurationStatusInactive)), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(r, "status", string(platform.BusinessUnitConfigurationStatusInactive)), + ), + }, + { + Config: businessUnitDivisionTFResourceDef(withBusinessUnitDivisionAssociateMode(platform.BusinessUnitAssociateModeExplicit)), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(r, "associate_mode", string(platform.BusinessUnitAssociateModeExplicit)), + ), + }, + { + Config: businessUnitDivisionTFResourceDef(withBusinessUnitDivisionStoreMode(platform.BusinessUnitStoreModeExplicit)), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(r, "store_mode", string(platform.BusinessUnitStoreModeExplicit)), + ), + }, + { + Config: businessUnitDivisionTFResourceDef(withBusinessUnitDivisionApprovalRuleMode(platform.BusinessUnitApprovalRuleModeExplicit)), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(r, "approval_rule_mode", string(platform.BusinessUnitApprovalRuleModeExplicit)), ), }, }, }) } -func testBusinessUnitDestroy(_ *terraform.State) error { +func testBusinessUnitDivisionDestroy(_ *terraform.State) error { return nil } -func businessUnitTFResourceDef(name, status, email string) string { - if status == "" { - status = "Active" +type option func(map[string]interface{}) + +func withBusinessDivisionKey(key string) option { + return func(data map[string]interface{}) { + data["key"] = key } +} - if email == "" { - email = "acme@example.com" +func withBusinessUnitDivisionName(name string) option { + return func(data map[string]interface{}) { + data["name"] = name } +} - if name == "" { - name = "Acme Company Business Unit" +func withBusinessUnitDivisionStatus(status platform.BusinessUnitConfigurationStatus) option { + return func(data map[string]interface{}) { + data["status"] = status } +} - return utils.HCLTemplate(`resource "commercetools_business_unit_division" "acme_division" { - key = "acme-division" - name = {{ .name }} - status = {{ .status }} - contact_email = {{ .email}} - - store { - key = "acme-usa" - } - - store { - key = "acme-germany" - } - - address { - key = "acme-business-unit-address" - title = "Acme Business Unit Address" - salutation = "Mr." - first_name = "John" - last_name = "Doe" - street_name = "Main Street" - street_number = "1" - additional_street_info = "Additional Street Info" - postal_code = "12345" - city = "Berlin" - region = "Berlin" - country = "DE" - company = "Acme" - department = "IT" - building = "Building" - apartment = "Apartment" - po_box = "P.O. Box" - phone = "123456789" - mobile = "987654321" - } - default_shipping_address_id = "acme-business-unit-address" - default_billing_address_id = "acme-business-unit-address" -}`, map[string]any{ - "name": name, - "status": status, - "email": email, - }) +func withBusinessUnitDivisionContactEmail(email string) option { + return func(data map[string]interface{}) { + data["contact_email"] = email + } +} + +func withBusinessUnitDivisionStoreMode(storeMode platform.BusinessUnitStoreMode) option { + return func(data map[string]interface{}) { + data["store_mode"] = storeMode + } +} + +func withBusinessUnitDivisionAssociateMode(associateMode platform.BusinessUnitAssociateMode) option { + return func(data map[string]interface{}) { + data["associate_mode"] = associateMode + } +} + +func withBusinessUnitDivisionApprovalRuleMode(approvalRuleMode platform.BusinessUnitApprovalRuleMode) option { + return func(data map[string]interface{}) { + data["approval_rule_mode"] = approvalRuleMode + } +} + +func businessUnitDivisionTFResourceDef(options ...option) string { + data := map[string]interface{}{ + "key": "acme-division", + "status": platform.BusinessUnitConfigurationStatusActive, + "contact_email": "acme@example.com", + "name": "Acme Company Business Unit", + "store_mode": platform.BusinessUnitStoreModeFromParent, + "associate_mode": platform.BusinessUnitAssociateModeExplicitAndFromParent, + "approval_rule_mode": platform.BusinessUnitApprovalRuleModeExplicitAndFromParent, + } + + for _, option := range options { + option(data) + } + + return utils.HCLTemplate(` + resource "commercetools_business_unit_company" "acme_company" { + key = "acme-company" + name = "Acme Company" + status = "Active" + } + + resource "commercetools_business_unit_division" "acme_division" { + key = "{{ .key }}" + name = "{{ .name }}" + status = "{{ .status }}" + contact_email = "{{ .contact_email }}" + store_mode = "{{ .store_mode }}" + associate_mode = "{{ .associate_mode }}" + approval_rule_mode = "{{ .approval_rule_mode }}" + + parent_unit { + key = commercetools_business_unit_company.acme_company.key + } + + address { + key = "acme-business-unit-address" + title = "Acme Business Unit Address" + salutation = "Mr." + first_name = "John" + last_name = "Doe" + street_name = "Main Street" + street_number = "1" + additional_street_info = "Additional Street Info" + postal_code = "12345" + city = "Berlin" + region = "Berlin" + country = "DE" + company = "Acme" + department = "IT" + building = "Building" + apartment = "Apartment" + po_box = "P.O. Box" + phone = "123456789" + mobile = "987654321" + } + shipping_address_keys = ["acme-business-unit-address"] + billing_address_keys = ["acme-business-unit-address"] + default_shipping_address_key = "acme-business-unit-address" + default_billing_address_key = "acme-business-unit-address" + } + `, data) } diff --git a/internal/resources/project/upgrade_v1.go b/internal/resources/project/upgrade_v1.go index 5d238422..de1eca6f 100644 --- a/internal/resources/project/upgrade_v1.go +++ b/internal/resources/project/upgrade_v1.go @@ -101,6 +101,14 @@ var ProjectResourceDataV1 = tftypes.Object{ }, }, }, + "business_units": tftypes.List{ + ElementType: tftypes.Object{ + AttributeTypes: map[string]tftypes.Type{ + "my_business_unit_status_on_creation": tftypes.String, + "my_business_unit_associate_role_key_on_creation": tftypes.String, + }, + }, + }, }, } @@ -148,6 +156,7 @@ func upgradeStateV0(ctx context.Context, req resource.UpgradeStateRequest, resp // Values that didn't exist yet "enable_search_index_products": tftypes.NewValue(tftypes.Bool, tftypes.UnknownValue), "enable_search_index_orders": tftypes.NewValue(tftypes.Bool, tftypes.UnknownValue), + "business_units": valueToList(nil, "business_units"), }), ) if err != nil { diff --git a/internal/resources/project/upgrade_v1_test.go b/internal/resources/project/upgrade_v1_test.go index 7f4d584f..4243cda2 100644 --- a/internal/resources/project/upgrade_v1_test.go +++ b/internal/resources/project/upgrade_v1_test.go @@ -65,6 +65,7 @@ func Test_upgradeStateV0(t *testing.T) { EnableSearchIndexProducts: types.BoolUnknown(), EnableSearchIndexOrders: types.BoolUnknown(), + BusinessUnits: []BusinessUnits{}, ExternalOAuth: []ExternalOAuth{}, Carts: []Carts{