fix: move some logic to domain entities

This commit is contained in:
Elton Minetto
2020-10-05 08:49:21 -03:00
parent c008dbab29
commit 098477169a
25 changed files with 493 additions and 183 deletions
+23
View File
@@ -2,6 +2,8 @@ package entity
import (
"time"
"github.com/eminetto/clean-architecture-go-v2/domain"
)
//Book data
@@ -14,3 +16,24 @@ type Book struct {
CreatedAt time.Time
UpdatedAt time.Time
}
//NewBook create a new book
func NewBook(title string, author string, pages int, quantity int) (*Book, error) {
b := &Book{
ID: NewID(),
Title: title,
Author: author,
Pages: pages,
Quantity: quantity,
CreatedAt: time.Now(),
}
return b, nil
}
//Validate validate book
func (b *Book) Validate() error {
if b.Title == "" || b.Author == "" || b.Pages <= 0 {
return domain.ErrInvalidEntity
}
return nil
}
-16
View File
@@ -1,16 +0,0 @@
package entity
import (
"time"
)
func NewFixtureBook() *Book {
return &Book{
ID: NewID(),
Title: "I Am Ozzy",
Author: "Ozzy Osbourne",
Pages: 294,
Quantity: 1,
CreatedAt: time.Now(),
}
}
+71
View File
@@ -0,0 +1,71 @@
package entity_test
import (
"testing"
"github.com/eminetto/clean-architecture-go-v2/domain"
"github.com/eminetto/clean-architecture-go-v2/domain/entity"
"github.com/stretchr/testify/assert"
)
func TestNewBook(t *testing.T) {
b, err := entity.NewBook("American Gods", "Neil Gaiman", 100, 0)
assert.Nil(t, err)
assert.Equal(t, b.Title, "American Gods")
assert.NotNil(t, b.ID)
}
func TestBookValidate(t *testing.T) {
type test struct {
title string
author string
pages int
quantity int
want error
}
tests := []test{
{
title: "American Gods",
author: "Neil Gaiman",
pages: 100,
quantity: 1,
want: nil,
},
{
title: "American Gods",
author: "Neil Gaiman",
pages: 100,
quantity: 0,
want: nil,
},
{
title: "",
author: "Neil Gaiman",
pages: 100,
quantity: 1,
want: domain.ErrInvalidEntity,
},
{
title: "American Gods",
author: "",
pages: 100,
quantity: 1,
want: domain.ErrInvalidEntity,
},
{
title: "American Gods",
author: "Neil Gaiman",
pages: 0,
quantity: 1,
want: domain.ErrInvalidEntity,
},
}
for _, tc := range tests {
b, err := entity.NewBook(tc.title, tc.author, tc.pages, tc.quantity)
err = b.Validate()
assert.Equal(t, err, tc.want)
}
}
+67
View File
@@ -2,6 +2,9 @@ package entity
import (
"time"
"github.com/eminetto/clean-architecture-go-v2/domain"
"golang.org/x/crypto/bcrypt"
)
//User data
@@ -15,3 +18,67 @@ type User struct {
UpdatedAt time.Time
Books []ID
}
func NewUser(email, password, firstName, lastName string) (*User, error) {
e := &User{
ID: NewID(),
Email: email,
FirstName: firstName,
LastName: lastName,
CreatedAt: time.Now(),
}
pwd, err := generatePassword(password)
if err != nil {
return nil, err
}
e.Password = pwd
return e, nil
}
func (u *User) AddBook(id ID) error {
u.Books = append(u.Books, id)
return nil
}
func (u *User) RemoveBook(id ID) error {
for i, j := range u.Books {
if j == id {
u.Books = append(u.Books[:i], u.Books[i+1:]...)
return nil
}
}
return domain.ErrNotFound
}
func (u *User) GetBook(id ID) (ID, error) {
for _, v := range u.Books {
if v == id {
return id, nil
}
}
return id, domain.ErrNotFound
}
func (u *User) Validate() error {
if u.Email == "" || u.FirstName == "" || u.LastName == "" || u.Password == "" {
return domain.ErrInvalidEntity
}
return nil
}
func (u *User) ValidatePassword(p string) error {
err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(p))
if err != nil {
return err
}
return nil
}
func generatePassword(raw string) (string, error) {
hash, err := bcrypt.GenerateFromPassword([]byte(raw), 10)
if err != nil {
return "", err
}
return string(hash), nil
}
-16
View File
@@ -1,16 +0,0 @@
package entity
import (
"time"
)
func NewFixtureUser() *User {
return &User{
ID: NewID(),
Email: "[email protected]",
Password: "123456",
FirstName: "Ozzy",
LastName: "Osbourne",
CreatedAt: time.Now(),
}
}
+109
View File
@@ -0,0 +1,109 @@
package entity_test
import (
"testing"
"github.com/eminetto/clean-architecture-go-v2/domain"
"github.com/eminetto/clean-architecture-go-v2/domain/entity"
"github.com/stretchr/testify/assert"
)
func TestNewUser(t *testing.T) {
u, err := entity.NewUser("[email protected]", "new_password", "Steve", "Jobs")
assert.Nil(t, err)
assert.Equal(t, u.FirstName, "Steve")
assert.NotNil(t, u.ID)
assert.NotEqual(t, u.Password, "new_password")
}
func TestValidatePassword(t *testing.T) {
u, _ := entity.NewUser("[email protected]", "new_password", "Steve", "Jobs")
err := u.ValidatePassword("new_password")
assert.Nil(t, err)
err = u.ValidatePassword("wrong_password")
assert.NotNil(t, err)
}
func TestAddBook(t *testing.T) {
u, _ := entity.NewUser("[email protected]", "new_password", "Steve", "Jobs")
err := u.AddBook(entity.NewID())
assert.Nil(t, err)
assert.Equal(t, 1, len(u.Books))
}
func TestRemoveBook(t *testing.T) {
u, _ := entity.NewUser("[email protected]", "new_password", "Steve", "Jobs")
err := u.RemoveBook(entity.NewID())
assert.Equal(t, domain.ErrNotFound, err)
bID := entity.NewID()
_ = u.AddBook(bID)
err = u.RemoveBook(bID)
assert.Nil(t, err)
}
func TestGetBook(t *testing.T) {
u, _ := entity.NewUser("[email protected]", "new_password", "Steve", "Jobs")
bID := entity.NewID()
_ = u.AddBook(bID)
id, err := u.GetBook(bID)
assert.Nil(t, err)
assert.Equal(t, id, bID)
_, err = u.GetBook(entity.NewID())
assert.Equal(t, domain.ErrNotFound, err)
}
func TestUserValidate(t *testing.T) {
type test struct {
email string
password string
firstName string
lastName string
want error
}
tests := []test{
{
email: "[email protected]",
password: "new_password",
firstName: "Steve",
lastName: "Jobs",
want: nil,
},
{
email: "",
password: "new_password",
firstName: "Steve",
lastName: "Jobs",
want: domain.ErrInvalidEntity,
},
{
email: "[email protected]",
password: "",
firstName: "Steve",
lastName: "Jobs",
want: nil,
},
{
email: "[email protected]",
password: "new_password",
firstName: "",
lastName: "Jobs",
want: domain.ErrInvalidEntity,
},
{
email: "[email protected]",
password: "new_password",
firstName: "Steve",
lastName: "",
want: domain.ErrInvalidEntity,
},
}
for _, tc := range tests {
u, err := entity.NewUser(tc.email, tc.password, tc.firstName, tc.lastName)
err = u.Validate()
assert.Equal(t, err, tc.want)
}
}