feat: move entity and usecase to root folder

This commit is contained in:
Elton Minetto
2020-10-12 07:35:29 -03:00
parent 2c0f46aff1
commit 3e4eb2e616
33 changed files with 109 additions and 138 deletions
+41
View File
@@ -0,0 +1,41 @@
package entity
import (
"time"
)
//Book data
type Book struct {
ID ID
Title string
Author string
Pages int
Quantity int
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(),
}
err := b.Validate()
if err != nil {
return nil, ErrInvalidEntity
}
return b, nil
}
//Validate validate book
func (b *Book) Validate() error {
if b.Title == "" || b.Author == "" || b.Pages <= 0 || b.Quantity <= 0 {
return ErrInvalidEntity
}
return nil
}
+69
View File
@@ -0,0 +1,69 @@
package entity_test
import (
"testing"
"github.com/eminetto/clean-architecture-go-v2/entity"
"github.com/stretchr/testify/assert"
)
func TestNewBook(t *testing.T) {
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)
}
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: entity.ErrInvalidEntity,
},
{
title: "",
author: "Neil Gaiman",
pages: 100,
quantity: 1,
want: entity.ErrInvalidEntity,
},
{
title: "American Gods",
author: "",
pages: 100,
quantity: 1,
want: entity.ErrInvalidEntity,
},
{
title: "American Gods",
author: "Neil Gaiman",
pages: 0,
quantity: 1,
want: entity.ErrInvalidEntity,
},
}
for _, tc := range tests {
_, err := entity.NewBook(tc.title, tc.author, tc.pages, tc.quantity)
assert.Equal(t, err, tc.want)
}
}
+14
View File
@@ -0,0 +1,14 @@
package entity
import "github.com/google/uuid"
type ID = uuid.UUID
func NewID() ID {
return ID(uuid.New())
}
func StringToID(s string) (ID, error) {
id, err := uuid.Parse(s)
return ID(id), err
}
+21
View File
@@ -0,0 +1,21 @@
package entity
import "errors"
//ErrNotFound not found
var ErrNotFound = errors.New("Not found")
//ErrInvalidEntity invalid entity
var ErrInvalidEntity = errors.New("Invalid entity")
//ErrCannotBeDeleted cannot be deleted
var ErrCannotBeDeleted = errors.New("Cannot Be Deleted")
//ErrNotEnoughBooks cannot borrow
var ErrNotEnoughBooks = errors.New("Not enough books")
//ErrBookAlreadyBorrowed cannot borrow
var ErrBookAlreadyBorrowed = errors.New("Book already borrowed")
//ErrBookNotBorrowed cannot return
var ErrBookNotBorrowed = errors.New("Book not borrowed")
+97
View File
@@ -0,0 +1,97 @@
package entity
import (
"time"
"golang.org/x/crypto/bcrypt"
)
//User data
type User struct {
ID ID
Email string
Password string
FirstName string
LastName string
CreatedAt time.Time
UpdatedAt time.Time
Books []ID
}
//NewUser create a new user
func NewUser(email, password, firstName, lastName string) (*User, error) {
u := &User{
ID: NewID(),
Email: email,
FirstName: firstName,
LastName: lastName,
CreatedAt: time.Now(),
}
pwd, err := generatePassword(password)
if err != nil {
return nil, err
}
u.Password = pwd
err = u.Validate()
if err != nil {
return nil, ErrInvalidEntity
}
return u, nil
}
//AddBook add a book
func (u *User) AddBook(id ID) error {
_, err := u.GetBook(id)
if err == nil {
return 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 {
u.Books = append(u.Books[:i], u.Books[i+1:]...)
return nil
}
}
return ErrNotFound
}
//GetBook get a book
func (u *User) GetBook(id ID) (ID, error) {
for _, v := range u.Books {
if v == id {
return id, nil
}
}
return id, ErrNotFound
}
//Validate validate data
func (u *User) Validate() error {
if u.Email == "" || u.FirstName == "" || u.LastName == "" || u.Password == "" {
return ErrInvalidEntity
}
return nil
}
//ValidatePassword
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
}
+111
View File
@@ -0,0 +1,111 @@
package entity_test
import (
"testing"
"github.com/eminetto/clean-architecture-go-v2/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")
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, entity.ErrBookAlreadyBorrowed, err)
}
func TestRemoveBook(t *testing.T) {
u, _ := entity.NewUser("[email protected]", "new_password", "Steve", "Jobs")
err := u.RemoveBook(entity.NewID())
assert.Equal(t, entity.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, entity.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: entity.ErrInvalidEntity,
},
{
email: "[email protected]",
password: "",
firstName: "Steve",
lastName: "Jobs",
want: nil,
},
{
email: "[email protected]",
password: "new_password",
firstName: "",
lastName: "Jobs",
want: entity.ErrInvalidEntity,
},
{
email: "[email protected]",
password: "new_password",
firstName: "Steve",
lastName: "",
want: entity.ErrInvalidEntity,
},
}
for _, tc := range tests {
_, err := entity.NewUser(tc.email, tc.password, tc.firstName, tc.lastName)
assert.Equal(t, err, tc.want)
}
}