mirror of
https://github.com/foomo/shop.git
synced 2026-10-06 07:16:54 +00:00
Improve validation for address, person and customer. Add IsComlete() functions for each and TrimSpace() for address and person // update tests
This commit is contained in:
+15
-13
@@ -1,5 +1,7 @@
|
||||
package address
|
||||
|
||||
import "strings"
|
||||
|
||||
type AddressType string
|
||||
type ContactType string
|
||||
type SalutationType string
|
||||
@@ -52,19 +54,6 @@ type Address struct {
|
||||
Custom interface{}
|
||||
}
|
||||
|
||||
// Person is a field Customer and of Address
|
||||
// Only Customer->Person has Contacts
|
||||
type Person struct {
|
||||
FirstName string
|
||||
MiddleName string
|
||||
LastName string
|
||||
Title TitleType
|
||||
Salutation SalutationType
|
||||
Birthday string
|
||||
Contacts map[string]*Contact // key must be contactID
|
||||
DefaultContacts map[ContactType]string // reference by contactID
|
||||
}
|
||||
|
||||
func (address *Address) GetID() string {
|
||||
return address.Id
|
||||
}
|
||||
@@ -97,3 +86,16 @@ func (address *Address) Equals(otherAddress *Address) bool {
|
||||
|
||||
return equal
|
||||
}
|
||||
|
||||
func (address *Address) TrimSpace() {
|
||||
if address == nil {
|
||||
return
|
||||
}
|
||||
address.Person.TrimSpace()
|
||||
address.Street = strings.TrimSpace(address.Street)
|
||||
address.StreetNumber = strings.TrimSpace(address.StreetNumber)
|
||||
address.ZIP = strings.TrimSpace(address.ZIP)
|
||||
address.City = strings.TrimSpace(address.City)
|
||||
address.Country = strings.TrimSpace(address.Country)
|
||||
address.CountryCode = strings.TrimSpace(address.CountryCode)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package address
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Person is a field Customer and of Address
|
||||
// Only Customer->Person has Contacts
|
||||
type Person struct {
|
||||
FirstName string
|
||||
MiddleName string
|
||||
LastName string
|
||||
Title TitleType
|
||||
Salutation SalutationType
|
||||
Birthday string
|
||||
Contacts map[string]*Contact // key must be contactID
|
||||
DefaultContacts map[ContactType]string // reference by contactID
|
||||
}
|
||||
|
||||
func (person *Person) TrimSpace() {
|
||||
if person == nil {
|
||||
return
|
||||
}
|
||||
person.FirstName = strings.TrimSpace(person.FirstName)
|
||||
person.MiddleName = strings.TrimSpace(person.MiddleName)
|
||||
person.LastName = strings.TrimSpace(person.LastName)
|
||||
person.Title = TitleType(strings.TrimSpace(string(person.Title)))
|
||||
person.Salutation = SalutationType(strings.TrimSpace(string(person.Salutation)))
|
||||
person.Birthday = strings.TrimSpace(person.Birthday)
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package address
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
)
|
||||
|
||||
func (addr *Address) IsComplete() error {
|
||||
addr.TrimSpace()
|
||||
// Return error if required field is missing
|
||||
var mErr *multierror.Error
|
||||
|
||||
if addr == nil {
|
||||
mErr = multierror.Append(mErr, errors.New("address is nil"))
|
||||
return mErr.ErrorOrNil()
|
||||
}
|
||||
|
||||
errPerson := addr.Person.IsComplete()
|
||||
if errPerson != nil {
|
||||
mErr = multierror.Append(mErr, errPerson)
|
||||
}
|
||||
|
||||
if addr.Street == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("address street is empty"))
|
||||
}
|
||||
if addr.StreetNumber == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("address street number is empty"))
|
||||
}
|
||||
if len(addr.ZIP) < 4 {
|
||||
mErr = multierror.Append(mErr, errors.New("address zip is not valid"))
|
||||
}
|
||||
if addr.City == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("address city is empty"))
|
||||
}
|
||||
if addr.Country == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("address country is empty"))
|
||||
}
|
||||
if addr.CountryCode == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("address country code is empty"))
|
||||
}
|
||||
|
||||
return mErr.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (person *Person) IsComplete() error {
|
||||
var mErr *multierror.Error
|
||||
if person == nil {
|
||||
mErr = multierror.Append(mErr, errors.New("person is nil"))
|
||||
return mErr.ErrorOrNil()
|
||||
}
|
||||
person.TrimSpace()
|
||||
if person.Salutation == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("person salutation is empty"))
|
||||
}
|
||||
if person.FirstName == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("person firstname is empty"))
|
||||
}
|
||||
if person.LastName == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("person lastname is empty"))
|
||||
}
|
||||
return mErr.ErrorOrNil()
|
||||
}
|
||||
+2
-41
@@ -61,7 +61,6 @@ type Customer struct {
|
||||
Email string // unique, used as Login Credential
|
||||
Person *address.Person
|
||||
IsGuest bool
|
||||
IsComplete bool // upsert checks if customer data is complete, so that a customer could place an order
|
||||
Company *Company
|
||||
Addresses []*address.Address
|
||||
Localization *Localization
|
||||
@@ -189,44 +188,6 @@ func (customer *Customer) OverrideId(id string) error {
|
||||
return customer.Upsert()
|
||||
}
|
||||
|
||||
// checkFields Checks if all required fields are specified
|
||||
// @TODO which are teh required fields
|
||||
func CheckRequiredAddressFields(address *address.Address) error {
|
||||
// Return error if required field is missing
|
||||
var mErr *multierror.Error
|
||||
|
||||
if address.Person == nil {
|
||||
mErr = multierror.Append(mErr, errors.New("required person is nil"))
|
||||
} else {
|
||||
if address.Person.Salutation == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("required person salutation is empty"))
|
||||
}
|
||||
if address.Person.FirstName == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("required person firstname is empty"))
|
||||
}
|
||||
if address.Person.LastName == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("required person lastname is empty"))
|
||||
}
|
||||
}
|
||||
if address.Street == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("required address street is empty"))
|
||||
}
|
||||
if address.StreetNumber == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("required address street number is empty"))
|
||||
}
|
||||
if address.ZIP == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("required address zip is empty"))
|
||||
}
|
||||
if address.City == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("required address city is empty"))
|
||||
}
|
||||
if address.Country == "" {
|
||||
mErr = multierror.Append(mErr, errors.New("required address country is empty"))
|
||||
}
|
||||
|
||||
return mErr.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (customer *Customer) AddDefaultBillingAddress(addr *address.Address) (string, error) {
|
||||
addr.Type = address.AddressDefaultBilling
|
||||
return customer.AddAddress(addr)
|
||||
@@ -239,7 +200,7 @@ func (customer *Customer) AddDefaultShippingAddress(addr *address.Address) (stri
|
||||
|
||||
// AddAddress adds a new address to the customers profile and returns its unique id
|
||||
func (customer *Customer) AddAddress(addr *address.Address) (string, error) {
|
||||
err := CheckRequiredAddressFields(addr)
|
||||
err := addr.IsComplete()
|
||||
if err != nil {
|
||||
log.Println("Error", err)
|
||||
return "", err
|
||||
@@ -307,7 +268,7 @@ func (customer *Customer) ChangeAddress(addr *address.Address) error {
|
||||
log.Println("Error: Could not find address with id "+addr.GetID(), "for customer ", customer.Person.LastName)
|
||||
return err
|
||||
}
|
||||
err = CheckRequiredAddressFields(addr)
|
||||
err = addr.IsComplete()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -149,7 +149,8 @@ func TestCustomerChangeAddress(t *testing.T) {
|
||||
Street: "Holzweg",
|
||||
StreetNumber: "5",
|
||||
City: "Bern",
|
||||
Country: "CH",
|
||||
Country: "Schweiz",
|
||||
CountryCode: "CH",
|
||||
ZIP: "1234",
|
||||
}
|
||||
log.Println("Original Address:")
|
||||
@@ -170,7 +171,8 @@ func TestCustomerChangeAddress(t *testing.T) {
|
||||
Street: "Steinweg",
|
||||
StreetNumber: "5",
|
||||
City: "Bern",
|
||||
Country: "CH",
|
||||
Country: "Schweiz",
|
||||
CountryCode: "CH",
|
||||
ZIP: "1234",
|
||||
}
|
||||
err = customer.ChangeAddress(addressNew)
|
||||
@@ -193,7 +195,7 @@ func TestCustomerChangeAddress(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckRequiredAddressFields(t *testing.T) {
|
||||
func TestAddressComplete(t *testing.T) {
|
||||
type args struct {
|
||||
address *address.Address
|
||||
}
|
||||
@@ -207,7 +209,7 @@ func TestCheckRequiredAddressFields(t *testing.T) {
|
||||
args: args{
|
||||
address: &address.Address{},
|
||||
},
|
||||
wantErr: "6 errors occurred:\n\t* required person is nil\n\t* required address street is empty\n\t* required address street number is empty\n\t* required address zip is empty\n\t* required address city is empty\n\t* required address country is empty\n\n",
|
||||
wantErr: "7 errors occurred:\n\t* person is nil\n\t* address street is empty\n\t* address street number is empty\n\t* address zip is not valid\n\t* address city is empty\n\t* address country is empty\n\t* address country code is empty\n\n",
|
||||
},
|
||||
{
|
||||
name: "all person fields empty",
|
||||
@@ -216,12 +218,13 @@ func TestCheckRequiredAddressFields(t *testing.T) {
|
||||
Person: &address.Person{},
|
||||
Street: "x",
|
||||
StreetNumber: "x",
|
||||
ZIP: "x",
|
||||
ZIP: "xxxx",
|
||||
City: "x",
|
||||
Country: "x",
|
||||
CountryCode: "x",
|
||||
},
|
||||
},
|
||||
wantErr: "3 errors occurred:\n\t* required person salutation is empty\n\t* required person firstname is empty\n\t* required person lastname is empty\n\n",
|
||||
wantErr: "3 errors occurred:\n\t* person salutation is empty\n\t* person firstname is empty\n\t* person lastname is empty\n\n",
|
||||
},
|
||||
{
|
||||
name: "all fields set",
|
||||
@@ -234,9 +237,10 @@ func TestCheckRequiredAddressFields(t *testing.T) {
|
||||
},
|
||||
Street: "x",
|
||||
StreetNumber: "x",
|
||||
ZIP: "x",
|
||||
ZIP: "xxxx",
|
||||
City: "x",
|
||||
Country: "x",
|
||||
CountryCode: "x",
|
||||
},
|
||||
},
|
||||
wantErr: "",
|
||||
@@ -244,7 +248,7 @@ func TestCheckRequiredAddressFields(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := CheckRequiredAddressFields(tt.args.address)
|
||||
err := tt.args.address.IsComplete()
|
||||
if tt.wantErr != "" {
|
||||
assert.EqualError(t, err, tt.wantErr)
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package customer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
)
|
||||
|
||||
// IsCustomerComplete returns an error if not all mandatory data is set
|
||||
func (customer *Customer) IsCustomerComplete() error {
|
||||
addr, err := customer.GetDefaultBillingAddress()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var mErr *multierror.Error
|
||||
if e := customer.GetEmail(); !strings.ContainsRune(e, '@') {
|
||||
mErr = multierror.Append(mErr, fmt.Errorf("invalid email address %q", e))
|
||||
}
|
||||
|
||||
if err := addr.IsComplete(); err != nil {
|
||||
mErr = multierror.Append(mErr, err)
|
||||
}
|
||||
|
||||
person := customer.GetPerson()
|
||||
if err := person.IsComplete(); err != nil {
|
||||
mErr = multierror.Append(mErr, fmt.Errorf("person is not complete"))
|
||||
}
|
||||
|
||||
// Birthday is not part of regular person.IsComplete() check
|
||||
if person != nil {
|
||||
if len(person.Birthday) != 10 {
|
||||
mErr = multierror.Append(mErr, fmt.Errorf("person birthday not valid"))
|
||||
}
|
||||
}
|
||||
|
||||
return mErr.ErrorOrNil()
|
||||
}
|
||||
Reference in New Issue
Block a user