Skip to content

Commit

Permalink
refactor: value objects
Browse files Browse the repository at this point in the history
  • Loading branch information
diyor28 committed Mar 3, 2025
1 parent ea9c139 commit 3090225
Show file tree
Hide file tree
Showing 29 changed files with 164 additions and 104 deletions.
5 changes: 0 additions & 5 deletions modules/core/domain/entities/country/interface.go

This file was deleted.

10 changes: 5 additions & 5 deletions modules/core/domain/entities/passport/passport.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"time"

"github.com/google/uuid"
"github.com/iota-uz/iota-sdk/modules/core/domain/value_objects/general"
)

type Passport interface {
Expand All @@ -14,7 +15,7 @@ type Passport interface {
FirstName() string
LastName() string
MiddleName() string
Gender() string
Gender() general.Gender
BirthDate() time.Time
BirthPlace() string
Nationality() string
Expand All @@ -40,7 +41,7 @@ func WithFullName(firstName, lastName, middleName string) Option {
}
}

func WithGender(gender string) Option {
func WithGender(gender general.Gender) Option {
return func(p *passport) {
p.gender = gender
}
Expand Down Expand Up @@ -142,7 +143,7 @@ type passport struct {
firstName string
lastName string
middleName string
gender string
gender general.Gender
birthDate time.Time
birthPlace string
nationality string
Expand Down Expand Up @@ -187,7 +188,7 @@ func (p *passport) MiddleName() string {
return p.middleName
}

func (p *passport) Gender() string {
func (p *passport) Gender() general.Gender {
return p.gender
}

Expand Down Expand Up @@ -238,4 +239,3 @@ func (p *passport) SignatureImage() []byte {
func (p *passport) Remarks() string {
return p.remarks
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import (
"slices"
)

type Country interface {
String() string
}

type country string

var (
Expand Down
47 changes: 47 additions & 0 deletions modules/core/domain/value_objects/general/general.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package general

import (
"errors"
)

type Gender interface {
String() string
}

var (
Male Gender = gender("male")
Female Gender = gender("female")
Other Gender = gender("other")
)

type gender string

var (
ErrInvalidGender = errors.New("invalid gender")
NilGender = gender("")
)

func (g gender) String() string {
return string(g)
}

// IsValid checks if a given country code is valid.
func IsValid(c string) bool {
switch c {
case "male":
return true
case "female":
return true
case "other":
return true
default:
return false
}
}

func NewGender(c string) (Gender, error) {
if IsValid(c) {
return gender(c), nil
}
return nil, ErrInvalidGender
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package internet_test

import (
"github.com/iota-uz/iota-sdk/modules/core/domain/entities/internet"
"github.com/iota-uz/iota-sdk/modules/core/domain/value_objects/internet"
"testing"
)

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package internet_test

import (
"github.com/iota-uz/iota-sdk/modules/core/domain/entities/internet"
"github.com/iota-uz/iota-sdk/modules/core/domain/value_objects/internet"
"testing"
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package phone

import (
"github.com/iota-uz/iota-sdk/modules/core/domain/entities/country"
"github.com/iota-uz/iota-sdk/modules/core/domain/value_objects/country"
)

// PhoneCodeToCountry maps phone number prefixes to their respective countries
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package phone

import (
country2 "github.com/iota-uz/iota-sdk/modules/core/domain/value_objects/country"
"unicode"

"github.com/go-faster/errors"
"github.com/iota-uz/iota-sdk/modules/core/domain/entities/country"
)

var (
Expand All @@ -14,7 +14,7 @@ var (

// AreaCode represents the mapping between area codes and countries
type AreaCode struct {
Country country.Country
Country country2.Country
AreaCodes []string
CodeLength int // Expected length of phone number for this country
}
Expand All @@ -34,10 +34,10 @@ func Strip(v string) string {
}

// ParseCountry attempts to determine the country from a phone number
func ParseCountry(phoneNumber string) (country.Country, error) {
func ParseCountry(phoneNumber string) (country2.Country, error) {
cleaned := Strip(phoneNumber)
if cleaned == "" {
return country.NilCountry, errors.Wrap(ErrUnknownCountry, "phone number is empty")
return country2.NilCountry, errors.Wrap(ErrUnknownCountry, "phone number is empty")
}

// Try different prefix lengths (from longest to shortest)
Expand Down Expand Up @@ -65,10 +65,10 @@ func ParseCountry(phoneNumber string) (country.Country, error) {
}
}

return country.NilCountry, errors.Wrapf(ErrUnknownCountry, "could not determine country for phone number: %s", phoneNumber)
return country2.NilCountry, errors.Wrapf(ErrUnknownCountry, "could not determine country for phone number: %s", phoneNumber)
}

func New(v string, c country.Country) (Phone, error) {
func New(v string, c country2.Country) (Phone, error) {
if v == "" {
return phone(""), errors.Wrap(ErrInvalidPhoneNumber, "phone number is empty")
}
Expand Down Expand Up @@ -140,9 +140,9 @@ func IsValidGlobalPhoneNumber(v string) bool {
return true
}

func IsValidPhoneNumber(v string, c country.Country) bool {
func IsValidPhoneNumber(v string, c country2.Country) bool {
switch c {
case country.UnitedStates:
case country2.UnitedStates:
return IsValidUSPhoneNumber(v)
default:
return IsValidGlobalPhoneNumber(v)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,51 @@ package phone_test

import (
"errors"
country2 "github.com/iota-uz/iota-sdk/modules/core/domain/value_objects/country"
"github.com/iota-uz/iota-sdk/modules/core/domain/value_objects/phone"
"testing"

"github.com/iota-uz/iota-sdk/modules/core/domain/entities/country"
"github.com/iota-uz/iota-sdk/modules/core/domain/entities/phone"
)

func TestNewPhoneNumber(t *testing.T) {
tests := []struct {
phone string
country country.Country
country country2.Country
err error
}{
// ✅ Valid US numbers
{"415-555-1234", country.UnitedStates, nil},
{"(415) 555-1234", country.UnitedStates, nil},
{"+1 415-555-1234", country.UnitedStates, nil},
{"415.555.1234", country.UnitedStates, nil},
{"14155551234", country.UnitedStates, nil},
{"800-555-1234", country.UnitedStates, nil}, // Toll-free
{"415-555-1234", country2.UnitedStates, nil},
{"(415) 555-1234", country2.UnitedStates, nil},
{"+1 415-555-1234", country2.UnitedStates, nil},
{"415.555.1234", country2.UnitedStates, nil},
{"14155551234", country2.UnitedStates, nil},
{"800-555-1234", country2.UnitedStates, nil}, // Toll-free

// ❌ Invalid US numbers
{"911-555-1234", country.UnitedStates, phone.ErrInvalidPhoneNumber}, // Exchange cannot be 911
{"123-456-7890", country.UnitedStates, phone.ErrInvalidPhoneNumber}, // Area code cannot start with 1
{"000-555-1234", country.UnitedStates, phone.ErrInvalidPhoneNumber}, // Invalid area code
{"555-555-5555", country.UnitedStates, phone.ErrInvalidPhoneNumber}, // Reserved 555 number
{"415555", country.UnitedStates, phone.ErrInvalidPhoneNumber}, // Too short
{"415555123456789", country.UnitedStates, phone.ErrInvalidPhoneNumber}, // Too long
{"911-555-1234", country2.UnitedStates, phone.ErrInvalidPhoneNumber}, // Exchange cannot be 911
{"123-456-7890", country2.UnitedStates, phone.ErrInvalidPhoneNumber}, // Area code cannot start with 1
{"000-555-1234", country2.UnitedStates, phone.ErrInvalidPhoneNumber}, // Invalid area code
{"555-555-5555", country2.UnitedStates, phone.ErrInvalidPhoneNumber}, // Reserved 555 number
{"415555", country2.UnitedStates, phone.ErrInvalidPhoneNumber}, // Too short
{"415555123456789", country2.UnitedStates, phone.ErrInvalidPhoneNumber}, // Too long

// ✅ Valid international numbers
{"+1 415-555-1234", country.UnitedStates, nil},
{"+44 20 7946 0958", country.UnitedKingdom, nil},
{"+91-9876543210", country.India, nil},
{"08123456789", country.Indonesia, nil},
{"+81 90-1234-5678", country.Japan, nil},
{"+49 170 1234567", country.Germany, nil},
{"+33 6 12 34 56 78", country.France, nil},
{"+254712345678", country.Kenya, nil},
{"+61 400 123 456", country.Australia, nil},
{"+358 50 1234567", country.Finland, nil},
{"+1 415-555-1234", country2.UnitedStates, nil},
{"+44 20 7946 0958", country2.UnitedKingdom, nil},
{"+91-9876543210", country2.India, nil},
{"08123456789", country2.Indonesia, nil},
{"+81 90-1234-5678", country2.Japan, nil},
{"+49 170 1234567", country2.Germany, nil},
{"+33 6 12 34 56 78", country2.France, nil},
{"+254712345678", country2.Kenya, nil},
{"+61 400 123 456", country2.Australia, nil},
{"+358 50 1234567", country2.Finland, nil},

// ❌ Invalid international numbers
{"001-555-234-5678", country.UnitedStates, phone.ErrInvalidPhoneNumber}, // Invalid country code (001)
{"+0 1234567890", country.UnitedStates, phone.ErrInvalidPhoneNumber}, // Country code cannot start with 0
{"123456", country.UnitedStates, phone.ErrInvalidPhoneNumber}, // Too short
{"99999999999999999999", country.UnitedStates, phone.ErrInvalidPhoneNumber}, // Too long
{"abcd-1234-5678", country.UnitedStates, phone.ErrInvalidPhoneNumber}, // Non-numeric
{"001-555-234-5678", country2.UnitedStates, phone.ErrInvalidPhoneNumber}, // Invalid country code (001)
{"+0 1234567890", country2.UnitedStates, phone.ErrInvalidPhoneNumber}, // Country code cannot start with 0
{"123456", country2.UnitedStates, phone.ErrInvalidPhoneNumber}, // Too short
{"99999999999999999999", country2.UnitedStates, phone.ErrInvalidPhoneNumber}, // Too long
{"abcd-1234-5678", country2.UnitedStates, phone.ErrInvalidPhoneNumber}, // Non-numeric
}

for _, tt := range tests {
Expand Down Expand Up @@ -190,48 +189,48 @@ func TestParseCountry(t *testing.T) {
name string
phone string
expectedError error
expectedCountry country.Country
expectedCountry country2.Country
}{
// North America
{
name: "US Number",
phone: "+14155551234",
expectedError: nil,
expectedCountry: country.UnitedStates,
expectedCountry: country2.UnitedStates,
},
{
name: "Canadian Number",
phone: "+14165551234",
expectedError: nil,
expectedCountry: country.Canada,
expectedCountry: country2.Canada,
},

// Europe
{
name: "UK Number",
phone: "+447911123456",
expectedError: nil,
expectedCountry: country.UnitedKingdom,
expectedCountry: country2.UnitedKingdom,
},
{
name: "German Number",
phone: "+4917012345678",
expectedError: nil,
expectedCountry: country.Germany,
expectedCountry: country2.Germany,
},

// Asia
{
name: "Chinese Number",
phone: "+8613912345678",
expectedError: nil,
expectedCountry: country.China,
expectedCountry: country2.China,
},
{
name: "Japanese Number",
phone: "+819012345678",
expectedError: nil,
expectedCountry: country.Japan,
expectedCountry: country2.Japan,
},

// Shared Codes
Expand All @@ -254,19 +253,19 @@ func TestParseCountry(t *testing.T) {
name: "Empty Number",
phone: "",
expectedError: phone.ErrUnknownCountry,
expectedCountry: country.NilCountry,
expectedCountry: country2.NilCountry,
},
{
name: "Invalid Country Code",
phone: "+0123456789",
expectedError: phone.ErrUnknownCountry,
expectedCountry: country.NilCountry,
expectedCountry: country2.NilCountry,
},
{
name: "Non-numeric",
phone: "+abcdefghijk",
expectedError: phone.ErrUnknownCountry,
expectedCountry: country.NilCountry,
expectedCountry: country2.NilCountry,
},
}

Expand Down
4 changes: 3 additions & 1 deletion modules/core/domain/value_objects/tax/interfaces.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package tax

import "github.com/iota-uz/iota-sdk/modules/core/domain/entities/country"
import (
"github.com/iota-uz/iota-sdk/modules/core/domain/value_objects/country"
)

// Tin - Taxpayer Identification Number (ИНН - Идентификационный номер налогоплательщика)
type Tin interface {
Expand Down
Loading

0 comments on commit 3090225

Please sign in to comment.