Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues:用户个人信息 #22 #23

Merged
merged 12 commits into from
Sep 30, 2023
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