github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/pkg/scope/directive_test.go (about) 1 package scope_test 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 8 9 "github.com/kyma-incubator/compass/components/director/pkg/scope" 10 "github.com/kyma-incubator/compass/components/director/pkg/scope/automock" 11 12 "github.com/pkg/errors" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 ) 16 17 const ( 18 readScope = "read" 19 writeScope = "write" 20 deleteScope = "delete" 21 ) 22 23 func TestHasScope(t *testing.T) { 24 t.Run("has all required scopes", func(t *testing.T) { 25 // GIVEN 26 mockRequiredScopesGetter := &automock.ScopesGetter{} 27 defer mockRequiredScopesGetter.AssertExpectations(t) 28 sut := scope.NewDirective(mockRequiredScopesGetter, &scope.HasScopesErrorProvider{}) 29 mockRequiredScopesGetter.On("GetRequiredScopes", fixScopesDefinition()).Return([]string{readScope, writeScope}, nil).Once() 30 31 next := dummyResolver{} 32 ctx := scope.SaveToContext(context.TODO(), []string{readScope, writeScope, deleteScope}) 33 // WHEN 34 act, err := sut.VerifyScopes(ctx, nil, next.SuccessResolve, fixScopesDefinition()) 35 // THEN 36 require.NoError(t, err) 37 assert.Equal(t, fixNextOutput(), act) 38 assert.True(t, next.called) 39 }) 40 41 t.Run("has insufficient scopes", func(t *testing.T) { 42 // GIVEN 43 mockRequiredScopesGetter := &automock.ScopesGetter{} 44 defer mockRequiredScopesGetter.AssertExpectations(t) 45 sut := scope.NewDirective(mockRequiredScopesGetter, &scope.HasScopesErrorProvider{}) 46 mockRequiredScopesGetter.On("GetRequiredScopes", fixScopesDefinition()).Return([]string{readScope, writeScope}, nil).Once() 47 ctx := scope.SaveToContext(context.TODO(), []string{deleteScope}) 48 // WHEN 49 _, err := sut.VerifyScopes(ctx, nil, nil, fixScopesDefinition()) 50 // THEN 51 require.Error(t, err) 52 assert.Contains(t, err.Error(), "required=read;write") 53 assert.Contains(t, err.Error(), "actual=delete") 54 }) 55 56 t.Run("returns error on getting scopes from context", func(t *testing.T) { 57 // GIVEN 58 sut := scope.NewDirective(nil, &scope.HasScopesErrorProvider{}) 59 // WHEN 60 _, err := sut.VerifyScopes(context.TODO(), nil, nil, fixScopesDefinition()) 61 // THEN 62 assert.EqualError(t, err, "cannot read scopes from context") 63 }) 64 65 t.Run("returns error on getting required scopes", func(t *testing.T) { 66 // GIVEN 67 mockRequiredScopesGetter := &automock.ScopesGetter{} 68 defer mockRequiredScopesGetter.AssertExpectations(t) 69 mockRequiredScopesGetter.On("GetRequiredScopes", fixScopesDefinition()).Return(nil, fixGivenError()).Once() 70 sut := scope.NewDirective(mockRequiredScopesGetter, &scope.HasScopesErrorProvider{}) 71 ctx := scope.SaveToContext(context.TODO(), []string{readScope, writeScope, deleteScope}) 72 // WHEN 73 _, err := sut.VerifyScopes(ctx, nil, nil, fixScopesDefinition()) 74 // THEN 75 assert.EqualError(t, err, "while getting required scopes: some error") 76 }) 77 } 78 79 func TestSanitize(t *testing.T) { 80 t.Run("should return sensitive fields when the required scopes are present", func(t *testing.T) { 81 // GIVEN 82 mockRequiredScopesGetter := &automock.ScopesGetter{} 83 mockRequiredScopesGetter.On("GetRequiredScopes", fixScopesDefinition()).Return([]string{readScope, writeScope}, nil).Once() 84 defer mockRequiredScopesGetter.AssertExpectations(t) 85 86 next := dummyResolver{} 87 ctx := scope.SaveToContext(context.TODO(), []string{readScope, writeScope, deleteScope}) 88 89 dir := scope.NewDirective(mockRequiredScopesGetter, &scope.SanitizeErrorProvider{}) 90 // WHEN 91 act, err := dir.VerifyScopes(ctx, nil, next.SuccessResolve, fixScopesDefinition()) 92 // THEN 93 require.NoError(t, err) 94 assert.Equal(t, fixNextOutput(), act) 95 assert.True(t, next.called) 96 }) 97 98 t.Run("should return nil when scopes are insufficient", func(t *testing.T) { 99 // GIVEN 100 mockRequiredScopesGetter := &automock.ScopesGetter{} 101 mockRequiredScopesGetter.On("GetRequiredScopes", fixScopesDefinition()).Return([]string{readScope, writeScope}, nil).Once() 102 defer mockRequiredScopesGetter.AssertExpectations(t) 103 104 ctx := scope.SaveToContext(context.TODO(), []string{deleteScope}) 105 dir := scope.NewDirective(mockRequiredScopesGetter, &scope.SanitizeErrorProvider{}) 106 // WHEN 107 act, err := dir.VerifyScopes(ctx, nil, nil, fixScopesDefinition()) 108 // THEN 109 require.NoError(t, err) 110 require.Nil(t, act) 111 }) 112 113 t.Run("returns error on getting scopes from context", func(t *testing.T) { 114 // GIVEN 115 dir := scope.NewDirective(nil, &scope.SanitizeErrorProvider{}) 116 // WHEN 117 _, err := dir.VerifyScopes(context.TODO(), nil, nil, fixScopesDefinition()) 118 // THEN 119 assert.EqualError(t, err, apperrors.NoScopesInContextMsg) 120 }) 121 122 t.Run("returns error on getting required scopes", func(t *testing.T) { 123 // GIVEN 124 mockRequiredScopesGetter := &automock.ScopesGetter{} 125 mockRequiredScopesGetter.On("GetRequiredScopes", fixScopesDefinition()).Return(nil, fixGivenError()).Once() 126 defer mockRequiredScopesGetter.AssertExpectations(t) 127 dir := scope.NewDirective(mockRequiredScopesGetter, &scope.SanitizeErrorProvider{}) 128 ctx := scope.SaveToContext(context.TODO(), []string{readScope, writeScope, deleteScope}) 129 // WHEN 130 _, err := dir.VerifyScopes(ctx, nil, nil, fixScopesDefinition()) 131 // THEN 132 assert.EqualError(t, err, "while getting required scopes: some error") 133 }) 134 } 135 136 func fixGivenError() error { 137 return errors.New("some error") 138 } 139 140 type dummyResolver struct { 141 called bool 142 } 143 144 func (d *dummyResolver) SuccessResolve(_ context.Context) (res interface{}, err error) { 145 d.called = true 146 return fixNextOutput(), nil 147 } 148 149 func fixScopesDefinition() string { 150 return "mutations.create.application" 151 } 152 153 func fixNextOutput() string { 154 return "nextOutput" 155 }