diff --git a/pkg/v2/service/patch.go b/pkg/v2/service/patch.go index f966db1d..418a7b6d 100644 --- a/pkg/v2/service/patch.go +++ b/pkg/v2/service/patch.go @@ -83,13 +83,13 @@ func (s *patchService) Do(ctx context.Context, req *PatchRequest) (resp *PatchRe return } - resource, err := s.database.Get(ctx, req.ResourceID, nil) + ref, err := s.database.Get(ctx, req.ResourceID, nil) if err != nil { return } if s.config.ETag.Supported && req.MatchCriteria != nil { - if !req.MatchCriteria(resource) { + if !req.MatchCriteria(ref) { err = fmt.Errorf("%w: resource does not meet pre condition", spec.ErrConflict) return } @@ -98,7 +98,7 @@ func (s *patchService) Do(ctx context.Context, req *PatchRequest) (resp *PatchRe // To save another database round trip, we use Clone to retain independent copy of the fetched resource. // However, because the cloned instance share subscribers, it is better to work on the original instance. // Hence, we assign reference to the clone, which will not be modified. - ref := resource.Clone() + resource := ref.Clone() for _, f := range s.preFilters { if err = f.FilterRef(ctx, resource, ref); err != nil { diff --git a/pkg/v2/service/patch_test.go b/pkg/v2/service/patch_test.go index 22ee09d7..bbb9eff5 100644 --- a/pkg/v2/service/patch_test.go +++ b/pkg/v2/service/patch_test.go @@ -43,6 +43,13 @@ func (s *PatchServiceTestSuite) TestDo() { err := database.Insert(context.TODO(), s.resourceOf(t, map[string]interface{}{ "schemas": []interface{}{"urn:ietf:params:scim:schemas:core:2.0:User"}, "id": "foo", + "meta": map[string]interface{}{ + "resourceType": "User", + "created": "2019-11-20T13:09:00", + "lastModified": "2019-11-20T13:09:00", + "location": "https://identity.imulab.io/Users/foo", + "version": "W/\"1\"", + }, "userName": "foo", "timezone": "Asia/Shanghai", "emails": []interface{}{ @@ -90,6 +97,7 @@ func (s *PatchServiceTestSuite) TestDo() { }, expect: func(t *testing.T, resp *PatchResponse, err error) { assert.Nil(t, err) + require.NotNil(t, resp) assert.True(t, resp.Patched) assert.NotEmpty(t, resp.Resource.MetaVersionOrEmpty()) assert.NotEqual(t, resp.Ref.MetaVersionOrEmpty(), resp.Resource.MetaVersionOrEmpty()) @@ -105,6 +113,13 @@ func (s *PatchServiceTestSuite) TestDo() { err := database.Insert(context.TODO(), s.resourceOf(t, map[string]interface{}{ "schemas": []interface{}{"urn:ietf:params:scim:schemas:core:2.0:User"}, "id": "foo", + "meta": map[string]interface{}{ + "resourceType": "User", + "created": "2019-11-20T13:09:00", + "lastModified": "2019-11-20T13:09:00", + "location": "https://identity.imulab.io/Users/foo", + "version": "W/\"1\"", + }, "userName": "foo", "timezone": "Asia/Shanghai", "emails": []interface{}{ @@ -143,6 +158,7 @@ func (s *PatchServiceTestSuite) TestDo() { }, expect: func(t *testing.T, resp *PatchResponse, err error) { assert.Nil(t, err) + require.NotNil(t, resp) assert.False(t, resp.Patched) }, }, @@ -153,6 +169,13 @@ func (s *PatchServiceTestSuite) TestDo() { err := database.Insert(context.TODO(), s.resourceOf(t, map[string]interface{}{ "schemas": []interface{}{"urn:ietf:params:scim:schemas:core:2.0:User"}, "id": "foo", + "meta": map[string]interface{}{ + "resourceType": "User", + "created": "2019-11-20T13:09:00", + "lastModified": "2019-11-20T13:09:00", + "location": "https://identity.imulab.io/Users/foo", + "version": "W/\"1\"", + }, "userName": "foo", "timezone": "Asia/Shanghai", "emails": []interface{}{ @@ -200,6 +223,7 @@ func (s *PatchServiceTestSuite) TestDo() { }, expect: func(t *testing.T, resp *PatchResponse, err error) { assert.Nil(t, err) + require.NotNil(t, resp) assert.True(t, resp.Patched) assert.NotEmpty(t, resp.Resource.MetaVersionOrEmpty()) assert.NotEqual(t, resp.Ref.MetaVersionOrEmpty(), resp.Resource.MetaVersionOrEmpty()) @@ -215,6 +239,13 @@ func (s *PatchServiceTestSuite) TestDo() { err := database.Insert(context.TODO(), s.resourceOf(t, map[string]interface{}{ "schemas": []interface{}{"urn:ietf:params:scim:schemas:core:2.0:User"}, "id": "foo", + "meta": map[string]interface{}{ + "resourceType": "User", + "created": "2019-11-20T13:09:00", + "lastModified": "2019-11-20T13:09:00", + "location": "https://identity.imulab.io/Users/foo", + "version": "W/\"1\"", + }, "userName": "foo", "timezone": "Asia/Shanghai", "emails": []interface{}{ @@ -255,6 +286,7 @@ func (s *PatchServiceTestSuite) TestDo() { }, expect: func(t *testing.T, resp *PatchResponse, err error) { assert.Nil(t, err) + require.NotNil(t, resp) assert.True(t, resp.Patched) assert.Equal(t, "bar", resp.Resource.Navigator().Dot("userName").Current().Raw()) assert.Nil(t, bcrypt.CompareHashAndPassword( @@ -273,6 +305,13 @@ func (s *PatchServiceTestSuite) TestDo() { "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User", }, "id": "foo", + "meta": map[string]interface{}{ + "resourceType": "User", + "created": "2019-11-20T13:09:00", + "lastModified": "2019-11-20T13:09:00", + "location": "https://identity.imulab.io/Users/foo", + "version": "W/\"1\"", + }, "userName": "foo", "emails": []interface{}{ map[string]interface{}{ @@ -313,6 +352,7 @@ func (s *PatchServiceTestSuite) TestDo() { }, expect: func(t *testing.T, resp *PatchResponse, err error) { assert.Nil(t, err) + require.NotNil(t, resp) assert.True(t, resp.Patched) assert.Equal(t, "6546579", resp.Resource.Navigator().Dot("urn:ietf:params:scim:schemas:extension:enterprise:2.0:User").Dot("employeeNumber").Current().Raw()) },