Skip to content

Commit

Permalink
Issues:用户个人信息 #22 (#23)
Browse files Browse the repository at this point in the history
* email service 简单的 failvover 策略

* e2e

* test

* 增加zap日志

* 增加zap日志

* 增加zap日志

* 实现个人信息编辑接口

* 实现个人信息编辑接口

* 实现个人信息编辑接口

* 实现个人信息编辑接口-补测试

---------

Co-authored-by: frankiejun <[email protected]>
  • Loading branch information
frankiejun and frankiejun authored Sep 30, 2023
1 parent 0d66edc commit 0b3593f
Show file tree
Hide file tree
Showing 13 changed files with 427 additions and 6 deletions.
3 changes: 3 additions & 0 deletions internal/domain/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ type User struct {
Email string
EmailVerified bool
Password string
NickName string
Birthday string
AboutMe string
CreateTime time.Time
UpdateTime time.Time
}
14 changes: 14 additions & 0 deletions internal/repository/dao/mocks/user.mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 19 additions & 2 deletions internal/repository/dao/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package dao

import (
"context"
"database/sql"
"errors"
"time"

Expand All @@ -16,6 +17,7 @@ var (
type UserDAO interface {
Insert(ctx context.Context, u User) error
UpdateEmailVerified(ctx context.Context, email string) error
UpdateUserProfile(ctx context.Context, u User) error
FindByEmail(ctx context.Context, email string) (User, error)
}

Expand All @@ -24,8 +26,13 @@ type User struct {
Email string `gorm:"unique"`
EmailVerified bool
Password string
CreateTime int64
UpdateTime int64

NickName sql.NullString
Birthday sql.NullString
AboutMe sql.NullString

CreateTime int64
UpdateTime int64
}

type GormUserDAO struct {
Expand Down Expand Up @@ -68,3 +75,13 @@ func (dao *GormUserDAO) FindByEmail(ctx context.Context, email string) (User, er
err := dao.db.WithContext(ctx).First(&u, "email = ?", email).Error
return u, err
}

func (dao *GormUserDAO) UpdateUserProfile(ctx context.Context, u User) error {
now := time.Now().UnixMilli()
return dao.db.WithContext(ctx).Model(&User{}).Where("id=?", u.Id).Updates(map[string]interface{}{
"nick_name": u.NickName,
"birthday": u.Birthday,
"about_me": u.AboutMe,
"update_time": now}).Error

}
78 changes: 78 additions & 0 deletions internal/repository/dao/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,81 @@ func TestGormUserDAO_UpdateEmailVerified(t *testing.T) {
})
}
}

func TestGormUserDAO_UpdateUserProfile(t *testing.T) {
testCases := []struct {
name string
ctx context.Context
user User
mock func(t *testing.T) *sql.DB
wantErr error
}{
{
name: "更新成功",
ctx: context.Background(),
user: User{
Id: 1,
NickName: sql.NullString{
String: "frankiejun",
Valid: true,
},
Birthday: sql.NullString{
String: "2000-01-01",
Valid: true,
},
AboutMe: sql.NullString{
String: "I am a programmer",
Valid: true,
},
},
mock: func(t *testing.T) *sql.DB {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
mock.ExpectExec("UPDATE `users` .*").WillReturnResult(sqlmock.NewResult(1, 1))
return mockDB
},
wantErr: nil,
},
{
name: "更新失败",
ctx: context.Background(),
user: User{
Id: 1,
NickName: sql.NullString{
String: "frankiejun",
Valid: true,
},
Birthday: sql.NullString{
String: "2000-01-01",
Valid: true,
},
AboutMe: sql.NullString{
String: "I am a programmer",
Valid: true,
},
},
mock: func(t *testing.T) *sql.DB {
mockDB, mock, err := sqlmock.New()
require.NoError(t, err)
mock.ExpectExec("UPDATE `users` .*").WillReturnError(errors.New("update failed"))
return mockDB
},
wantErr: errors.New("update failed"),
},
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
db, err := gorm.Open(gormMysql.New(gormMysql.Config{
Conn: tt.mock(t),
SkipInitializeWithVersion: true,
}), &gorm.Config{
DisableAutomaticPing: true,
SkipDefaultTransaction: true,
})
assert.NoError(t, err)
dao := NewUserInfoDAO(db)
err = dao.UpdateUserProfile(tt.ctx, tt.user)
assert.Equal(t, tt.wantErr, err)
})
}
}
14 changes: 14 additions & 0 deletions internal/repository/mocks/user.mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions internal/repository/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package repository

import (
"context"
"database/sql"

"github.com/ecodeclub/webook/internal/domain"
"github.com/ecodeclub/webook/internal/repository/dao"
Expand All @@ -15,6 +16,7 @@ type UserRepository interface {
Create(ctx context.Context, u *domain.User) error
UpdateEmailVerified(ctx context.Context, email string) error
FindByEmail(ctx context.Context, email string) (domain.User, error)
UpdateUserProfile(ctx context.Context, u domain.User) error
}

type UserInfoRepository struct {
Expand Down Expand Up @@ -57,3 +59,21 @@ func (ur *UserInfoRepository) FindByEmail(ctx context.Context, email string) (do
}
return ur.userToDomain(user), err
}

func (ur *UserInfoRepository) UpdateUserProfile(ctx context.Context, u domain.User) error {
return ur.dao.UpdateUserProfile(ctx, dao.User{
Id: u.Id,
NickName: sql.NullString{
String: u.NickName,
Valid: len(u.NickName) > 0,
},
Birthday: sql.NullString{
String: u.Birthday,
Valid: len(u.Birthday) > 0,
},
AboutMe: sql.NullString{
String: u.AboutMe,
Valid: len(u.AboutMe) > 0,
},
})
}
54 changes: 54 additions & 0 deletions internal/repository/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package repository

import (
"context"
"errors"
"testing"
"time"

Expand Down Expand Up @@ -131,3 +132,56 @@ func TestUserInfoRepository_FindByEmail(t *testing.T) {
})
}
}

func TestUserInfoRepository_UpdateUserProfile(t *testing.T) {
testCases := []struct {
name string
mock func(*gomock.Controller) dao.UserDAO
ctx context.Context
user domain.User
wantErr error
}{
{
name: "更新失败",
mock: func(ctrl *gomock.Controller) dao.UserDAO {
d := daomocks.NewMockUserDAO(ctrl)
d.EXPECT().UpdateUserProfile(gomock.Any(), gomock.Any()).Return(errors.New("更新失败"))
return d
},
ctx: context.Background(),
user: domain.User{
Id: 1,
NickName: "frankiejun",
AboutMe: "I am a good boy",
Birthday: "1999-01-01",
},
wantErr: errors.New("更新失败"),
},
{
name: "更新成功",
mock: func(ctrl *gomock.Controller) dao.UserDAO {
d := daomocks.NewMockUserDAO(ctrl)
d.EXPECT().UpdateUserProfile(gomock.Any(), gomock.Any()).Return(nil)
return d
},
ctx: context.Background(),
user: domain.User{
Id: 1,
NickName: "frankiejun",
AboutMe: "I am a good boy",
Birthday: "1999-01-01",
},
wantErr: nil,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

repo := NewUserInfoRepository(tc.mock(ctrl))
err := repo.UpdateUserProfile(tc.ctx, tc.user)
assert.Equal(t, tc.wantErr, err)
})
}
}
14 changes: 14 additions & 0 deletions internal/service/mocks/user.mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions internal/service/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type UserService interface {
Signup(ctx context.Context, u *domain.User) error
SendVerifyEmail(ctx context.Context, email string) error
VerifyEmail(ctx context.Context, tokenStr string) error
EditUserProfile(ctx context.Context, u domain.User) error
}

type userService struct {
Expand Down Expand Up @@ -79,3 +80,7 @@ func (svc *userService) VerifyEmail(ctx context.Context, tokenStr string) error

return svc.r.UpdateEmailVerified(ctx, ec.Email)
}

func (svc *userService) EditUserProfile(ctx context.Context, u domain.User) error {
return svc.r.UpdateUserProfile(ctx, u)
}
37 changes: 37 additions & 0 deletions internal/service/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,40 @@ func genToken(emailAddr string, timeout int) string {
tokenStr, _ := token.SignedString([]byte(EmailJWTKey))
return tokenStr
}

func Test_userService_EditUserProfile(t *testing.T) {
testCases := []struct {
name string
ctx context.Context
mock func(*gomock.Controller) repository.UserRepository
user domain.User
wantErr error
}{
{
name: "修改成功",
ctx: context.Background(),
mock: func(ctrl *gomock.Controller) repository.UserRepository {
mock := repomocks.NewMockUserRepository(ctrl)
mock.EXPECT().UpdateUserProfile(gomock.Any(), gomock.Any()).Return(nil)
return mock
},
user: domain.User{
Id: 1,
NickName: "frankiejun",
Birthday: "2020-01-01",
AboutMe: "I am a good boy",
},
wantErr: nil,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

svc := NewUserService(tc.mock(ctrl), nil)
err := svc.EditUserProfile(tc.ctx, tc.user)
assert.Equal(t, tc.wantErr, err)
})
}
}
1 change: 1 addition & 0 deletions internal/web/init_web.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ func (u *UserHandler) RegisterRoutes(server *gin.Engine) {
server.POST("/users/signup", u.SignUp)
server.POST("/users/email/verify/:token", u.EmailVerify)
server.POST("/users/login", u.Login)
server.POST("/users/edit", u.Edit)
}
Loading

0 comments on commit 0b3593f

Please sign in to comment.