From 83c00526b2b95239e87a8c74b563a9196ab38b42 Mon Sep 17 00:00:00 2001 From: Elton Minetto Date: Wed, 7 Oct 2020 22:57:54 -0300 Subject: [PATCH] feat: improvements in entity domain logic --- domain/entity/book.go | 6 +++++- domain/entity/book_test.go | 7 +++---- domain/entity/user.go | 20 +++++++++++++++++--- domain/entity/user_test.go | 9 ++++++--- domain/usecase/book/mock/book.go | 3 +-- domain/usecase/book/service.go | 4 ---- domain/usecase/loan/mock/loan.go | 3 +-- domain/usecase/loan/service.go | 4 ---- domain/usecase/user/mock/user.go | 3 +-- domain/usecase/user/service.go | 6 +----- 10 files changed, 35 insertions(+), 30 deletions(-) diff --git a/domain/entity/book.go b/domain/entity/book.go index f1abac2..b1e0502 100644 --- a/domain/entity/book.go +++ b/domain/entity/book.go @@ -27,12 +27,16 @@ func NewBook(title string, author string, pages int, quantity int) (*Book, error Quantity: quantity, CreatedAt: time.Now(), } + err := b.Validate() + if err != nil { + return nil, domain.ErrInvalidEntity + } return b, nil } //Validate validate book func (b *Book) Validate() error { - if b.Title == "" || b.Author == "" || b.Pages <= 0 { + if b.Title == "" || b.Author == "" || b.Pages <= 0 || b.Quantity <= 0 { return domain.ErrInvalidEntity } return nil diff --git a/domain/entity/book_test.go b/domain/entity/book_test.go index 9e6e2ea..a383e98 100644 --- a/domain/entity/book_test.go +++ b/domain/entity/book_test.go @@ -9,7 +9,7 @@ import ( ) func TestNewBook(t *testing.T) { - b, err := entity.NewBook("American Gods", "Neil Gaiman", 100, 0) + b, err := entity.NewBook("American Gods", "Neil Gaiman", 100, 1) assert.Nil(t, err) assert.Equal(t, b.Title, "American Gods") assert.NotNil(t, b.ID) @@ -37,7 +37,7 @@ func TestBookValidate(t *testing.T) { author: "Neil Gaiman", pages: 100, quantity: 0, - want: nil, + want: domain.ErrInvalidEntity, }, { title: "", @@ -63,8 +63,7 @@ func TestBookValidate(t *testing.T) { } for _, tc := range tests { - b, err := entity.NewBook(tc.title, tc.author, tc.pages, tc.quantity) - err = b.Validate() + _, err := entity.NewBook(tc.title, tc.author, tc.pages, tc.quantity) assert.Equal(t, err, tc.want) } diff --git a/domain/entity/user.go b/domain/entity/user.go index 2401864..b182723 100644 --- a/domain/entity/user.go +++ b/domain/entity/user.go @@ -19,8 +19,9 @@ type User struct { Books []ID } +//NewUser create a new user func NewUser(email, password, firstName, lastName string) (*User, error) { - e := &User{ + u := &User{ ID: NewID(), Email: email, FirstName: firstName, @@ -31,15 +32,25 @@ func NewUser(email, password, firstName, lastName string) (*User, error) { if err != nil { return nil, err } - e.Password = pwd - return e, nil + u.Password = pwd + err = u.Validate() + if err != nil { + return nil, domain.ErrInvalidEntity + } + return u, nil } +//AddBook add a book func (u *User) AddBook(id ID) error { + _, err := u.GetBook(id) + if err == nil { + return domain.ErrBookAlreadyBorrowed + } u.Books = append(u.Books, id) return nil } +//RemoveBook remove a book func (u *User) RemoveBook(id ID) error { for i, j := range u.Books { if j == id { @@ -50,6 +61,7 @@ func (u *User) RemoveBook(id ID) error { return domain.ErrNotFound } +//GetBook get a book func (u *User) GetBook(id ID) (ID, error) { for _, v := range u.Books { if v == id { @@ -59,6 +71,7 @@ func (u *User) GetBook(id ID) (ID, error) { return id, domain.ErrNotFound } +//Validate validate data func (u *User) Validate() error { if u.Email == "" || u.FirstName == "" || u.LastName == "" || u.Password == "" { return domain.ErrInvalidEntity @@ -67,6 +80,7 @@ func (u *User) Validate() error { return nil } +//ValidatePassword func (u *User) ValidatePassword(p string) error { err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(p)) if err != nil { diff --git a/domain/entity/user_test.go b/domain/entity/user_test.go index 86da9a9..9c16439 100644 --- a/domain/entity/user_test.go +++ b/domain/entity/user_test.go @@ -27,9 +27,13 @@ func TestValidatePassword(t *testing.T) { func TestAddBook(t *testing.T) { u, _ := entity.NewUser("sjobs@apple.com", "new_password", "Steve", "Jobs") - err := u.AddBook(entity.NewID()) + bID := entity.NewID() + err := u.AddBook(bID) assert.Nil(t, err) assert.Equal(t, 1, len(u.Books)) + err = u.AddBook(bID) + assert.Equal(t, domain.ErrBookAlreadyBorrowed, err) + } func TestRemoveBook(t *testing.T) { @@ -101,8 +105,7 @@ func TestUserValidate(t *testing.T) { } for _, tc := range tests { - u, err := entity.NewUser(tc.email, tc.password, tc.firstName, tc.lastName) - err = u.Validate() + _, err := entity.NewUser(tc.email, tc.password, tc.firstName, tc.lastName) assert.Equal(t, err, tc.want) } diff --git a/domain/usecase/book/mock/book.go b/domain/usecase/book/mock/book.go index bb72af6..4afe5e9 100644 --- a/domain/usecase/book/mock/book.go +++ b/domain/usecase/book/mock/book.go @@ -5,10 +5,9 @@ package mock import ( - reflect "reflect" - entity "github.com/eminetto/clean-architecture-go-v2/domain/entity" gomock "github.com/golang/mock/gomock" + reflect "reflect" ) // MockReader is a mock of Reader interface diff --git a/domain/usecase/book/service.go b/domain/usecase/book/service.go index 36f5ed7..fdbcaf3 100644 --- a/domain/usecase/book/service.go +++ b/domain/usecase/book/service.go @@ -27,10 +27,6 @@ func (s *Service) CreateBook(title string, author string, pages int, quantity in if err != nil { return b.ID, err } - err = b.Validate() - if err != nil { - return b.ID, err - } return s.repo.Create(b) } diff --git a/domain/usecase/loan/mock/loan.go b/domain/usecase/loan/mock/loan.go index 5d5b355..0d25a74 100644 --- a/domain/usecase/loan/mock/loan.go +++ b/domain/usecase/loan/mock/loan.go @@ -5,10 +5,9 @@ package mock import ( - reflect "reflect" - entity "github.com/eminetto/clean-architecture-go-v2/domain/entity" gomock "github.com/golang/mock/gomock" + reflect "reflect" ) // MockUseCase is a mock of UseCase interface diff --git a/domain/usecase/loan/service.go b/domain/usecase/loan/service.go index 1bb3e3a..edc6c09 100644 --- a/domain/usecase/loan/service.go +++ b/domain/usecase/loan/service.go @@ -35,10 +35,6 @@ func (s *Service) Borrow(u *entity.User, b *entity.Book) error { return domain.ErrNotEnoughBooks } - _, err = u.GetBook(b.ID) - if err == nil { - return domain.ErrBookAlreadyBorrowed - } err = u.AddBook(b.ID) if err != nil { return err diff --git a/domain/usecase/user/mock/user.go b/domain/usecase/user/mock/user.go index adcd3e7..94d58dd 100644 --- a/domain/usecase/user/mock/user.go +++ b/domain/usecase/user/mock/user.go @@ -5,10 +5,9 @@ package mock import ( - reflect "reflect" - entity "github.com/eminetto/clean-architecture-go-v2/domain/entity" gomock "github.com/golang/mock/gomock" + reflect "reflect" ) // MockReader is a mock of Reader interface diff --git a/domain/usecase/user/service.go b/domain/usecase/user/service.go index dbb960d..e43861b 100644 --- a/domain/usecase/user/service.go +++ b/domain/usecase/user/service.go @@ -25,11 +25,7 @@ func NewService(r Repository) *Service { func (s *Service) CreateUser(email, password, firstName, lastName string) (entity.ID, error) { e, err := entity.NewUser(email, password, firstName, lastName) if err != nil { - return e.ID, domain.ErrInvalidEntity - } - err = e.Validate() - if err != nil { - return e.ID, domain.ErrInvalidEntity + return e.ID, err } return s.repo.Create(e) }