This is an automated email from the ASF dual-hosted git repository. vinci pushed a commit to branch refactor in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git
The following commit(s) were added to refs/heads/refactor by this push: new 4df9d6d feat: append stock check for generic store 4df9d6d is described below commit 4df9d6d161230363301060565421d1f00d723c7b Author: ShiningRush <277040...@qq.com> AuthorDate: Sat Sep 19 11:17:00 2020 +0800 feat: append stock check for generic store --- api/internal/core/store/store.go | 32 ++++++++++++++------ api/internal/core/store/store_test.go | 51 ++++++++++++++++++++++++++++++++ api/internal/core/store/validate_test.go | 4 +-- 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/api/internal/core/store/store.go b/api/internal/core/store/store.go index 7296082..46793e6 100644 --- a/api/internal/core/store/store.go +++ b/api/internal/core/store/store.go @@ -20,10 +20,11 @@ type GenericStore struct { } type GenericStoreOption struct { - BasePath string - ObjType reflect.Type - KeyFunc func(obj interface{}) string - Validator Validator + BasePath string + ObjType reflect.Type + KeyFunc func(obj interface{}) string + StockCheck func(obj interface{}, stockObj interface{}) error + Validator Validator } func NewGenericStore(opt GenericStoreOption) (*GenericStore, error) { @@ -145,13 +146,28 @@ func (s *GenericStore) List(input ListInput) (*ListOutput, error) { return output, nil } -func (s *GenericStore) Create(ctx context.Context, obj interface{}) error { +func (s *GenericStore) ingestValidate(obj interface{}) error { if s.opt.Validator != nil { if err := s.opt.Validator.Validate(obj); err != nil { return err } } + if s.opt.StockCheck != nil { + for k := range s.cache { + if err := s.opt.StockCheck(obj, s.cache[k]); err != nil { + return err + } + } + } + return nil +} + +func (s *GenericStore) Create(ctx context.Context, obj interface{}) error { + if err := s.ingestValidate(obj); err != nil { + return err + } + key := s.opt.KeyFunc(obj) if key == "" { return fmt.Errorf("key is required") @@ -173,10 +189,8 @@ func (s *GenericStore) Create(ctx context.Context, obj interface{}) error { } func (s *GenericStore) Update(ctx context.Context, obj interface{}) error { - if s.opt.Validator != nil { - if err := s.opt.Validator.Validate(obj); err != nil { - return err - } + if err := s.ingestValidate(obj); err != nil { + return err } key := s.opt.KeyFunc(obj) diff --git a/api/internal/core/store/store_test.go b/api/internal/core/store/store_test.go index 4895258..536cc79 100644 --- a/api/internal/core/store/store_test.go +++ b/api/internal/core/store/store_test.go @@ -397,6 +397,57 @@ func TestGenericStore_List(t *testing.T) { } } +func TestGenericStore_ingestValidate(t *testing.T) { + tests := []struct { + giveStore *GenericStore + giveObj interface{} + giveStockCheck func(obj interface{}, stockObj interface{}) error + giveValidateErr error + wantErr error + }{ + { + giveStore: &GenericStore{ + cache: map[string]interface{}{ + "test1-f1": &TestStruct{Field1: "test1-f1", Field2: "test1-f2"}, + "test2-f1": &TestStruct{Field1: "test2-f1", Field2: "test2-f2"}, + }, + }, + giveObj: &TestStruct{ + Field1: "test3-f1", + Field2: "test2-f2", + }, + giveStockCheck: func(obj interface{}, stockObj interface{}) error { + if obj.(*TestStruct).Field2 == stockObj.(*TestStruct).Field2 { + return fmt.Errorf("field2: %s is conflicted", obj.(*TestStruct).Field2) + } + return nil + }, + wantErr: fmt.Errorf("field2: test2-f2 is conflicted"), + }, + { + giveStore: &GenericStore{}, + giveObj: &TestStruct{}, + giveValidateErr: fmt.Errorf("validate failed"), + wantErr: fmt.Errorf("validate failed"), + }, + } + + for _, tc := range tests { + validateCalled := false + mValidator := &MockValidator{} + mValidator.On("Validate", mock.Anything).Run(func(args mock.Arguments) { + validateCalled = true + assert.Equal(t, tc.giveObj, args.Get(0)) + }).Return(tc.giveValidateErr) + + tc.giveStore.opt.Validator = mValidator + tc.giveStore.opt.StockCheck = tc.giveStockCheck + err := tc.giveStore.ingestValidate(tc.giveObj) + assert.True(t, validateCalled) + assert.Equal(t, tc.wantErr, err) + } +} + func TestGenericStore_Create(t *testing.T) { tests := []struct { caseDesc string diff --git a/api/internal/core/store/validate_test.go b/api/internal/core/store/validate_test.go index f7d1ac9..bf5ab05 100644 --- a/api/internal/core/store/validate_test.go +++ b/api/internal/core/store/validate_test.go @@ -6,7 +6,7 @@ import ( "testing" ) -type TestOjb struct { +type TestObj struct { Name string `json:"name"` Email string `json:"email"` Age int `json:"age"` @@ -21,7 +21,7 @@ func TestJsonSchemaValidator_Validate(t *testing.T) { }{ { givePath: "./test_case.json", - giveObj: TestOjb{ + giveObj: TestObj{ Name: "lessName", Email: "too long name greater than 10", Age: 12,