feat: remove phone (#349)

* feat: remove phone number

* feat: remove phone number tests

* feat: remove phone number tests

* fix: regenerate protos
This commit is contained in:
Fabi
2020-07-06 15:48:24 +02:00
committed by GitHub
parent 0e1ef5758a
commit c8cdbe136c
31 changed files with 1947 additions and 1430 deletions

View File

@@ -130,6 +130,10 @@ func (repo *UserRepo) ChangeMyPhone(ctx context.Context, phone *model.Phone) (*m
return repo.UserEvents.ChangePhone(ctx, phone)
}
func (repo *UserRepo) RemoveMyPhone(ctx context.Context) error {
return repo.UserEvents.RemovePhone(ctx, auth.GetCtxData(ctx).UserID)
}
func (repo *UserRepo) VerifyMyPhone(ctx context.Context, code string) error {
return repo.UserEvents.VerifyPhone(ctx, auth.GetCtxData(ctx).UserID, code)
}

View File

@@ -66,6 +66,7 @@ func (p *User) ProcessUser(event *models.Event) (err error) {
es_model.UserEmailVerified,
es_model.UserPhoneChanged,
es_model.UserPhoneVerified,
es_model.UserPhoneRemoved,
es_model.UserAddressChanged,
es_model.UserDeactivated,
es_model.UserReactivated,

View File

@@ -42,6 +42,7 @@ type myUserRepo interface {
MyPhone(ctx context.Context) (*model.Phone, error)
ChangeMyPhone(ctx context.Context, phone *model.Phone) (*model.Phone, error)
RemoveMyPhone(ctx context.Context) error
VerifyMyPhone(ctx context.Context, code string) error
ResendMyPhoneVerificationCode(ctx context.Context) error

View File

@@ -182,6 +182,10 @@ func (repo *UserRepo) ChangePhone(ctx context.Context, email *usr_model.Phone) (
return repo.UserEvents.ChangePhone(ctx, email)
}
func (repo *UserRepo) RemovePhone(ctx context.Context, userID string) error {
return repo.UserEvents.RemovePhone(ctx, userID)
}
func (repo *UserRepo) CreatePhoneVerificationCode(ctx context.Context, userID string) error {
return repo.UserEvents.CreatePhoneVerificationCode(ctx, userID)
}

View File

@@ -66,6 +66,7 @@ func (p *User) ProcessUser(event *models.Event) (err error) {
es_model.UserEmailVerified,
es_model.UserPhoneChanged,
es_model.UserPhoneVerified,
es_model.UserPhoneRemoved,
es_model.UserAddressChanged,
es_model.UserDeactivated,
es_model.UserReactivated,

View File

@@ -32,6 +32,7 @@ type UserRepository interface {
PhoneByID(ctx context.Context, userID string) (*model.Phone, error)
ChangePhone(ctx context.Context, email *model.Phone) (*model.Phone, error)
RemovePhone(ctx context.Context, userID string) error
CreatePhoneVerificationCode(ctx context.Context, userID string) error
AddressByID(ctx context.Context, userID string) (*model.Address, error)

View File

@@ -46,7 +46,8 @@ func (p *NotifyUser) Reduce(event *models.Event) (err error) {
es_model.UserEmailChanged,
es_model.UserEmailVerified,
es_model.UserPhoneChanged,
es_model.UserPhoneVerified:
es_model.UserPhoneVerified,
es_model.UserPhoneRemoved:
user, err = p.view.NotifyUserByID(event.AggregateID)
if err != nil {
return err

View File

@@ -895,6 +895,22 @@ func (es *UserEventstore) PhoneVerificationCodeSent(ctx context.Context, userID
return nil
}
func (es *UserEventstore) RemovePhone(ctx context.Context, userID string) error {
existing, err := es.UserByID(ctx, userID)
if err != nil {
return err
}
repoExisting := model.UserFromModel(existing)
removeAggregate := PhoneRemovedAggregate(es.AggregateCreator(), repoExisting)
err = es_sdk.Push(ctx, es.PushAggregates, repoExisting.AppendEvents, removeAggregate)
if err != nil {
return err
}
es.userCache.cacheUser(repoExisting)
return nil
}
func (es *UserEventstore) AddressByID(ctx context.Context, userID string) (*usr_model.Address, error) {
if userID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-di8ws", "Errors.User.UserIDMissing")

View File

@@ -2604,6 +2604,70 @@ func TestVerifyPhone(t *testing.T) {
}
}
func TestRemovePhone(t *testing.T) {
ctrl := gomock.NewController(t)
type args struct {
es *UserEventstore
ctx context.Context
userID string
code string
}
type res struct {
errFunc func(err error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "remove phone ok",
args: args{
es: GetMockManipulateUserVerifiedPhone(ctrl),
ctx: auth.NewMockContext("orgID", "userID"),
userID: "AggregateID",
code: "code",
},
res: res{},
},
{
name: "empty userid",
args: args{
es: GetMockManipulateUser(ctrl),
ctx: auth.NewMockContext("orgID", "userID"),
code: "Code",
},
res: res{
errFunc: caos_errs.IsPreconditionFailed,
},
},
{
name: "existing user not found",
args: args{
es: GetMockManipulateUserNoEvents(ctrl),
ctx: auth.NewMockContext("orgID", "userID"),
userID: "AggregateID",
code: "Code",
},
res: res{
errFunc: caos_errs.IsNotFound,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.args.es.RemovePhone(tt.args.ctx, tt.args.userID)
if tt.res.errFunc == nil && err != nil {
t.Errorf("should not get err %v", err)
}
if tt.res.errFunc != nil && !tt.res.errFunc(err) {
t.Errorf("got wrong err: %v ", err)
}
})
}
}
func TestCreatePhoneVerificationCode(t *testing.T) {
ctrl := gomock.NewController(t)
type args struct {

View File

@@ -81,6 +81,11 @@ func (u *User) appendUserPhoneVerifiedEvent() {
u.IsPhoneVerified = true
}
func (u *User) appendUserPhoneRemovedEvent() {
u.Phone = nil
u.PhoneCode = nil
}
func (p *Phone) setData(event *es_models.Event) error {
p.ObjectRoot.AppendEvent(event)
if err := json.Unmarshal(event.Data, p); err != nil {

View File

@@ -38,6 +38,7 @@ const (
UserEmailCodeSent models.EventType = "user.email.code.sent"
UserPhoneChanged models.EventType = "user.phone.changed"
UserPhoneRemoved models.EventType = "user.phone.removed"
UserPhoneVerified models.EventType = "user.phone.verified"
UserPhoneVerificationFailed models.EventType = "user.phone.verification.failed"
UserPhoneCodeAdded models.EventType = "user.phone.code.added"

View File

@@ -161,6 +161,8 @@ func (u *User) AppendEvent(event *es_models.Event) (err error) {
err = u.appendUserPhoneCodeAddedEvent(event)
case UserPhoneVerified:
u.appendUserPhoneVerifiedEvent()
case UserPhoneRemoved:
u.appendUserPhoneRemovedEvent()
case UserAddressChanged:
err = u.appendUserAddressChangedEvent(event)
case MfaOtpAdded:

View File

@@ -508,6 +508,16 @@ func PhoneChangeAggregate(aggCreator *es_models.AggregateCreator, existing *mode
}
}
func PhoneRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.User) es_sdk.AggregateFunc {
return func(ctx context.Context) (*es_models.Aggregate, error) {
agg, err := UserAggregate(ctx, aggCreator, existing)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.UserPhoneRemoved, nil)
}
}
func PhoneVerifiedAggregate(aggCreator *es_models.AggregateCreator, existing *model.User) es_sdk.AggregateFunc {
return func(ctx context.Context) (*es_models.Aggregate, error) {
agg, err := UserAggregate(ctx, aggCreator, existing)

View File

@@ -1621,6 +1621,56 @@ func TestVerifyPhoneAggregate(t *testing.T) {
}
}
func TestRemovePhoneAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *model.User
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
eventTypes []models.EventType
errFunc func(err error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "user phone removed aggregate ok",
args: args{
ctx: auth.NewMockContext("orgID", "userID"),
existing: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"},
Phone: &model.Phone{PhoneNumber: "PhoneNumber"},
},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
eventTypes: []models.EventType{model.UserPhoneRemoved},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := PhoneRemovedAggregate(tt.args.aggCreator, tt.args.existing)(tt.args.ctx)
if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
}
for i := 0; i < tt.res.eventLen; i++ {
if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] {
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String())
}
}
if tt.res.errFunc != nil && !tt.res.errFunc(err) {
t.Errorf("got wrong err: %v ", err)
}
})
}
}
func TestVerificationFailedPhoneAggregate(t *testing.T) {
type args struct {
ctx context.Context

View File

@@ -99,6 +99,9 @@ func (u *NotifyUser) AppendEvent(event *models.Event) (err error) {
u.VerifiedEmail = u.LastEmail
case es_model.UserPhoneChanged:
err = u.setData(event)
case es_model.UserPhoneRemoved:
u.VerifiedPhone = ""
u.LastPhone = ""
case es_model.UserPhoneVerified:
u.VerifiedPhone = u.LastPhone
case es_model.UserPasswordChanged:

View File

@@ -193,6 +193,9 @@ func (u *UserView) AppendEvent(event *models.Event) (err error) {
err = u.setData(event)
case es_model.UserPhoneVerified:
u.IsPhoneVerified = true
case es_model.UserPhoneRemoved:
u.Phone = ""
u.IsPhoneVerified = false
case es_model.UserDeactivated:
u.State = int32(model.UserStateInactive)
case es_model.UserReactivated,