fix: new test and extract time.Now to mockable Clock #181
This commit is contained in:
@@ -5,6 +5,7 @@ packages:
|
|||||||
me-fit/service:
|
me-fit/service:
|
||||||
interfaces:
|
interfaces:
|
||||||
RandomGenerator:
|
RandomGenerator:
|
||||||
|
Clock:
|
||||||
me-fit/db:
|
me-fit/db:
|
||||||
interfaces:
|
interfaces:
|
||||||
DbAuth:
|
DbAuth:
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ func GetHandler(d *sql.DB, serverSettings *types.ServerSettings) http.Handler {
|
|||||||
router.HandleFunc("/", service.HandleIndexAnd404(d, serverSettings))
|
router.HandleFunc("/", service.HandleIndexAnd404(d, serverSettings))
|
||||||
|
|
||||||
randomGenerator := service.NewRandomGeneratorImpl()
|
randomGenerator := service.NewRandomGeneratorImpl()
|
||||||
|
clock := service.NewClockImpl()
|
||||||
dbAuth := db.NewDbAuthSqlite(d)
|
dbAuth := db.NewDbAuthSqlite(d)
|
||||||
serviceAuth := service.NewServiceAuthImpl(dbAuth, randomGenerator, serverSettings)
|
serviceAuth := service.NewServiceAuthImpl(dbAuth, randomGenerator, clock, serverSettings)
|
||||||
handlerAuth := NewHandlerAuth(d, serviceAuth, serverSettings)
|
handlerAuth := NewHandlerAuth(d, serviceAuth, serverSettings)
|
||||||
|
|
||||||
// Serve static files (CSS, JS and images)
|
// Serve static files (CSS, JS and images)
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"net/mail"
|
"net/mail"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"me-fit/db"
|
"me-fit/db"
|
||||||
"me-fit/template"
|
"me-fit/template"
|
||||||
@@ -54,14 +53,16 @@ type ServiceAuth interface {
|
|||||||
type ServiceAuthImpl struct {
|
type ServiceAuthImpl struct {
|
||||||
dbAuth db.DbAuth
|
dbAuth db.DbAuth
|
||||||
randomGenerator RandomGenerator
|
randomGenerator RandomGenerator
|
||||||
|
clock Clock
|
||||||
serverSettings *types.ServerSettings
|
serverSettings *types.ServerSettings
|
||||||
mailService MailService
|
mailService MailService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceAuthImpl(dbAuth db.DbAuth, randomGenerator RandomGenerator, serverSettings *types.ServerSettings) *ServiceAuthImpl {
|
func NewServiceAuthImpl(dbAuth db.DbAuth, randomGenerator RandomGenerator, clock Clock, serverSettings *types.ServerSettings) *ServiceAuthImpl {
|
||||||
return &ServiceAuthImpl{
|
return &ServiceAuthImpl{
|
||||||
dbAuth: dbAuth,
|
dbAuth: dbAuth,
|
||||||
randomGenerator: randomGenerator,
|
randomGenerator: randomGenerator,
|
||||||
|
clock: clock,
|
||||||
serverSettings: serverSettings,
|
serverSettings: serverSettings,
|
||||||
mailService: NewMailService(serverSettings),
|
mailService: NewMailService(serverSettings),
|
||||||
}
|
}
|
||||||
@@ -96,9 +97,8 @@ func (service ServiceAuthImpl) SignUp(email string, password string) (*User, err
|
|||||||
return nil, ErrInvalidPassword
|
return nil, ErrInvalidPassword
|
||||||
}
|
}
|
||||||
|
|
||||||
userId, err := uuid.NewRandom()
|
userId, err := service.randomGenerator.UUID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.LogError("Could not generate UUID", err)
|
|
||||||
return nil, types.ErrInternal
|
return nil, types.ErrInternal
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ func (service ServiceAuthImpl) SignUp(email string, password string) (*User, err
|
|||||||
|
|
||||||
hash := GetHashPassword(password, salt)
|
hash := GetHashPassword(password, salt)
|
||||||
|
|
||||||
dbUser := db.NewUser(userId, email, false, nil, false, hash, salt, time.Now())
|
dbUser := db.NewUser(userId, email, false, nil, false, hash, salt, service.clock.Now())
|
||||||
|
|
||||||
err = service.dbAuth.InsertUser(dbUser)
|
err = service.dbAuth.InsertUser(dbUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestSignIn(t *testing.T) {
|
func TestSignIn(t *testing.T) {
|
||||||
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
t.Run("should return user if password is correct", func(t *testing.T) {
|
t.Run("should return user if password is correct", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
@@ -33,8 +34,9 @@ func TestSignIn(t *testing.T) {
|
|||||||
mockDbAuth := mocks.NewMockDbAuth(t)
|
mockDbAuth := mocks.NewMockDbAuth(t)
|
||||||
mockDbAuth.EXPECT().GetUser("test@test.de").Return(user, nil)
|
mockDbAuth.EXPECT().GetUser("test@test.de").Return(user, nil)
|
||||||
mockRandom := mocks.NewMockRandomGenerator(t)
|
mockRandom := mocks.NewMockRandomGenerator(t)
|
||||||
|
mockClock := mocks.NewMockClock(t)
|
||||||
|
|
||||||
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, &types.ServerSettings{})
|
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, mockClock, &types.ServerSettings{})
|
||||||
|
|
||||||
actualUser, err := underTest.SignIn(user.Email, "password")
|
actualUser, err := underTest.SignIn(user.Email, "password")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
@@ -67,8 +69,9 @@ func TestSignIn(t *testing.T) {
|
|||||||
mockDbAuth := mocks.NewMockDbAuth(t)
|
mockDbAuth := mocks.NewMockDbAuth(t)
|
||||||
mockDbAuth.EXPECT().GetUser(user.Email).Return(user, nil)
|
mockDbAuth.EXPECT().GetUser(user.Email).Return(user, nil)
|
||||||
mockRandom := mocks.NewMockRandomGenerator(t)
|
mockRandom := mocks.NewMockRandomGenerator(t)
|
||||||
|
mockClock := mocks.NewMockClock(t)
|
||||||
|
|
||||||
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, &types.ServerSettings{})
|
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, mockClock, &types.ServerSettings{})
|
||||||
|
|
||||||
_, err := underTest.SignIn("test@test.de", "wrong password")
|
_, err := underTest.SignIn("test@test.de", "wrong password")
|
||||||
|
|
||||||
@@ -80,8 +83,9 @@ func TestSignIn(t *testing.T) {
|
|||||||
mockDbAuth := mocks.NewMockDbAuth(t)
|
mockDbAuth := mocks.NewMockDbAuth(t)
|
||||||
mockDbAuth.EXPECT().GetUser("test").Return(nil, db.ErrUserNotFound)
|
mockDbAuth.EXPECT().GetUser("test").Return(nil, db.ErrUserNotFound)
|
||||||
mockRandom := mocks.NewMockRandomGenerator(t)
|
mockRandom := mocks.NewMockRandomGenerator(t)
|
||||||
|
mockClock := mocks.NewMockClock(t)
|
||||||
|
|
||||||
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, &types.ServerSettings{})
|
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, mockClock, &types.ServerSettings{})
|
||||||
|
|
||||||
_, err := underTest.SignIn("test", "test")
|
_, err := underTest.SignIn("test", "test")
|
||||||
assert.Equal(t, ErrInvaidCredentials, err)
|
assert.Equal(t, ErrInvaidCredentials, err)
|
||||||
@@ -92,8 +96,9 @@ func TestSignIn(t *testing.T) {
|
|||||||
mockDbAuth := mocks.NewMockDbAuth(t)
|
mockDbAuth := mocks.NewMockDbAuth(t)
|
||||||
mockDbAuth.EXPECT().GetUser("test").Return(nil, errors.New("Some undefined error"))
|
mockDbAuth.EXPECT().GetUser("test").Return(nil, errors.New("Some undefined error"))
|
||||||
mockRandom := mocks.NewMockRandomGenerator(t)
|
mockRandom := mocks.NewMockRandomGenerator(t)
|
||||||
|
mockClock := mocks.NewMockClock(t)
|
||||||
|
|
||||||
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, &types.ServerSettings{})
|
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, mockClock, &types.ServerSettings{})
|
||||||
|
|
||||||
_, err := underTest.SignIn("test", "test")
|
_, err := underTest.SignIn("test", "test")
|
||||||
|
|
||||||
@@ -108,8 +113,9 @@ func TestSignUp(t *testing.T) {
|
|||||||
|
|
||||||
mockDbAuth := mocks.NewMockDbAuth(t)
|
mockDbAuth := mocks.NewMockDbAuth(t)
|
||||||
mockRandom := mocks.NewMockRandomGenerator(t)
|
mockRandom := mocks.NewMockRandomGenerator(t)
|
||||||
|
mockClock := mocks.NewMockClock(t)
|
||||||
|
|
||||||
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, &types.ServerSettings{})
|
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, mockClock, &types.ServerSettings{})
|
||||||
|
|
||||||
_, err := underTest.SignUp("invalid email address", "SomeStrongPassword123!")
|
_, err := underTest.SignUp("invalid email address", "SomeStrongPassword123!")
|
||||||
|
|
||||||
@@ -120,8 +126,9 @@ func TestSignUp(t *testing.T) {
|
|||||||
|
|
||||||
mockDbAuth := mocks.NewMockDbAuth(t)
|
mockDbAuth := mocks.NewMockDbAuth(t)
|
||||||
mockRandom := mocks.NewMockRandomGenerator(t)
|
mockRandom := mocks.NewMockRandomGenerator(t)
|
||||||
|
mockClock := mocks.NewMockClock(t)
|
||||||
|
|
||||||
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, &types.ServerSettings{})
|
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, mockClock, &types.ServerSettings{})
|
||||||
|
|
||||||
weakPasswords := []string{
|
weakPasswords := []string{
|
||||||
"123!ab", // too short
|
"123!ab", // too short
|
||||||
@@ -135,4 +142,39 @@ func TestSignUp(t *testing.T) {
|
|||||||
assert.Equal(t, ErrInvalidPassword, err)
|
assert.Equal(t, ErrInvalidPassword, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
t.Run("should signup correctly", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
mockDbAuth := mocks.NewMockDbAuth(t)
|
||||||
|
mockRandom := mocks.NewMockRandomGenerator(t)
|
||||||
|
mockClock := mocks.NewMockClock(t)
|
||||||
|
|
||||||
|
expected := User{
|
||||||
|
Id: uuid.New(),
|
||||||
|
Email: "some@valid.email",
|
||||||
|
EmailVerified: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
random := NewRandomGeneratorImpl()
|
||||||
|
salt, err := random.Bytes(16)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
password := "SomeStrongPassword123!"
|
||||||
|
|
||||||
|
mockRandom.EXPECT().UUID().Return(expected.Id, nil)
|
||||||
|
mockRandom.EXPECT().Bytes(16).Return(salt, nil)
|
||||||
|
|
||||||
|
createTime := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||||
|
|
||||||
|
mockClock.EXPECT().Now().Return(createTime)
|
||||||
|
|
||||||
|
mockDbAuth.EXPECT().InsertUser(db.NewUser(expected.Id, expected.Email, false, nil, false, GetHashPassword(password, salt), salt, createTime)).Return(nil)
|
||||||
|
|
||||||
|
underTest := NewServiceAuthImpl(mockDbAuth, mockRandom, mockClock, &types.ServerSettings{})
|
||||||
|
|
||||||
|
actual, err := underTest.SignUp(expected.Email, password)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, expected, *actual)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
17
service/clock.go
Normal file
17
service/clock.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Clock interface {
|
||||||
|
Now() time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClockImpl struct{}
|
||||||
|
|
||||||
|
func NewClockImpl() Clock {
|
||||||
|
return &ClockImpl{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClockImpl) Now() time.Time {
|
||||||
|
return time.Now()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user