github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/scopes_sync/service_test.go (about)

     1  package scopes
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/kyma-incubator/compass/components/director/internal/model"
     8  
     9  	pkgmodel "github.com/kyma-incubator/compass/components/director/pkg/model"
    10  
    11  	"github.com/kyma-incubator/compass/components/director/internal/domain/oauth20"
    12  	"github.com/ory/hydra-client-go/models"
    13  
    14  	"github.com/kyma-incubator/compass/components/director/internal/repo"
    15  	"github.com/kyma-incubator/compass/components/director/internal/scopes_sync/automock"
    16  	"github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest"
    17  	"github.com/kyma-incubator/compass/components/director/pkg/str"
    18  	"github.com/pkg/errors"
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/stretchr/testify/mock"
    21  )
    22  
    23  func TestSyncService_UpdateClientScopes(t *testing.T) {
    24  	const clientID = "client-id"
    25  	selectCondition := repo.Conditions{
    26  		repo.NewNotEqualCondition("(value -> 'Credential' -> 'Oauth')", "null"),
    27  	}
    28  
    29  	t.Run("fails when oauth service cannot list clients", func(t *testing.T) {
    30  		// GIVEN
    31  		oauthSvc := &automock.OAuthService{}
    32  		oauthSvc.On("ListClients").Return(nil, errors.New("error"))
    33  		scopeSyncSvc := NewService(oauthSvc, nil, &automock.SystemAuthRepo{})
    34  		// WHEN
    35  		err := scopeSyncSvc.SynchronizeClientScopes(context.TODO())
    36  		// THEN
    37  		assert.Error(t, err, "while listing clients from hydra")
    38  	})
    39  
    40  	t.Run("fails when cannot begin transaction", func(t *testing.T) {
    41  		// GIVEN
    42  		oauthSvc := &automock.OAuthService{}
    43  		oauthSvc.On("ListClients").Return([]*models.OAuth2Client{}, nil)
    44  		mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error while transaction begin")).ThatFailsOnBegin()
    45  		defer mockedTx.AssertExpectations(t)
    46  		defer transactioner.AssertExpectations(t)
    47  		defer oauthSvc.AssertExpectations(t)
    48  		scopeSyncSvc := NewService(oauthSvc, transactioner, &automock.SystemAuthRepo{})
    49  		// WHEN
    50  		err := scopeSyncSvc.SynchronizeClientScopes(context.TODO())
    51  		// THEN
    52  		assert.Error(t, err, "while opening database transaction")
    53  	})
    54  
    55  	t.Run("fails when cannot list systemAuths", func(t *testing.T) {
    56  		// GIVEN
    57  		oauthSvc := &automock.OAuthService{}
    58  		systemAuthRepo := &automock.SystemAuthRepo{}
    59  		oauthSvc.On("ListClients").Return([]*models.OAuth2Client{}, nil)
    60  		mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error while transaction begin")).ThatDoesntExpectCommit()
    61  		systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return(nil, errors.New("error while listing systemAuths"))
    62  		defer mockedTx.AssertExpectations(t)
    63  		defer transactioner.AssertExpectations(t)
    64  		defer oauthSvc.AssertExpectations(t)
    65  		scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo)
    66  		// WHEN
    67  		err := scopeSyncSvc.SynchronizeClientScopes(context.TODO())
    68  		// THEN
    69  		assert.Error(t, err, "error while listing systemAuths")
    70  	})
    71  	t.Run("fails when cannot commit transaction", func(t *testing.T) {
    72  		// GIVEN
    73  		oauthSvc := &automock.OAuthService{}
    74  		systemAuthRepo := &automock.SystemAuthRepo{}
    75  		oauthSvc.On("ListClients").Return([]*models.OAuth2Client{}, nil)
    76  		mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error during transaction commit")).ThatFailsOnCommit()
    77  		systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{}, nil)
    78  		defer mockedTx.AssertExpectations(t)
    79  		defer transactioner.AssertExpectations(t)
    80  		defer oauthSvc.AssertExpectations(t)
    81  		scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo)
    82  		// WHEN
    83  		err := scopeSyncSvc.SynchronizeClientScopes(context.TODO())
    84  		// THEN
    85  		assert.Error(t, err, "while database transaction commit")
    86  	})
    87  
    88  	t.Run("won't update client when object type is invalid", func(t *testing.T) {
    89  		// GIVEN
    90  		oauthSvc := &automock.OAuthService{}
    91  		systemAuthRepo := &automock.SystemAuthRepo{}
    92  		oauthSvc.On("ListClients").Return([]*models.OAuth2Client{}, nil)
    93  		mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error")).ThatSucceeds()
    94  		systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{
    95  			{
    96  				Value: &model.Auth{
    97  					Credential: model.CredentialData{
    98  						Oauth: &model.OAuthCredentialData{
    99  							ClientID: clientID,
   100  						},
   101  					},
   102  				},
   103  			},
   104  		}, nil)
   105  		defer mockedTx.AssertExpectations(t)
   106  		defer transactioner.AssertExpectations(t)
   107  		defer oauthSvc.AssertExpectations(t)
   108  		scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo)
   109  		// WHEN
   110  		err := scopeSyncSvc.SynchronizeClientScopes(context.TODO())
   111  		// THEN
   112  		assert.EqualError(t, err, "Not all clients were updated successfully")
   113  	})
   114  
   115  	t.Run("won't update client when getting client credentials scopes fails", func(t *testing.T) {
   116  		// GIVEN
   117  		oauthSvc := &automock.OAuthService{}
   118  		systemAuthRepo := &automock.SystemAuthRepo{}
   119  		oauthSvc.On("ListClients").Return([]*models.OAuth2Client{}, nil)
   120  		oauthSvc.On("GetClientDetails", pkgmodel.ApplicationReference).Return(nil, errors.New("error while getting scopes"))
   121  		mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error")).ThatSucceeds()
   122  		systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{
   123  			{
   124  				AppID: str.Ptr("app-id"),
   125  				Value: &model.Auth{
   126  					Credential: model.CredentialData{
   127  						Oauth: &model.OAuthCredentialData{
   128  							ClientID: clientID,
   129  						},
   130  					},
   131  				},
   132  			},
   133  		}, nil)
   134  		defer mockedTx.AssertExpectations(t)
   135  		defer transactioner.AssertExpectations(t)
   136  		defer oauthSvc.AssertExpectations(t)
   137  		scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo)
   138  		// WHEN
   139  		err := scopeSyncSvc.SynchronizeClientScopes(context.TODO())
   140  		// THEN
   141  		assert.EqualError(t, err, "Not all clients were updated successfully")
   142  	})
   143  
   144  	t.Run("won't try to update the client when client is not present in hydra", func(t *testing.T) {
   145  		// GIVEN
   146  		oauthSvc := &automock.OAuthService{}
   147  		systemAuthRepo := &automock.SystemAuthRepo{}
   148  		oauthSvc.On("ListClients").Return([]*models.OAuth2Client{}, nil)
   149  		oauthSvc.On("GetClientDetails", pkgmodel.ApplicationReference).Return(&oauth20.ClientDetails{
   150  			Scopes:     []string{},
   151  			GrantTypes: []string{},
   152  		}, nil)
   153  		mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error")).ThatSucceeds()
   154  		systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{
   155  			{
   156  				AppID: str.Ptr("app-id"),
   157  				Value: &model.Auth{
   158  					Credential: model.CredentialData{
   159  						Oauth: &model.OAuthCredentialData{
   160  							ClientID: clientID,
   161  						},
   162  					},
   163  				},
   164  			},
   165  		}, nil)
   166  		defer mockedTx.AssertExpectations(t)
   167  		defer transactioner.AssertExpectations(t)
   168  		defer oauthSvc.AssertExpectations(t)
   169  		scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo)
   170  		// WHEN
   171  		err := scopeSyncSvc.SynchronizeClientScopes(context.TODO())
   172  		// THEN
   173  		assert.NoError(t, err)
   174  	})
   175  
   176  	t.Run("won't update scopes if not needed", func(t *testing.T) {
   177  		// GIVEN
   178  		oauthSvc := &automock.OAuthService{}
   179  		systemAuthRepo := &automock.SystemAuthRepo{}
   180  		oauthSvc.On("ListClients").Return([]*models.OAuth2Client{
   181  			{
   182  				ClientID: clientID,
   183  				Scope:    "scope",
   184  			},
   185  		}, nil)
   186  		oauthSvc.On("GetClientDetails", pkgmodel.ApplicationReference).Return(&oauth20.ClientDetails{
   187  			Scopes:     []string{"scope"},
   188  			GrantTypes: []string{},
   189  		}, nil)
   190  		mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error")).ThatSucceeds()
   191  		systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{
   192  			{
   193  				AppID: str.Ptr("app-id"),
   194  				Value: &model.Auth{
   195  					Credential: model.CredentialData{
   196  						Oauth: &model.OAuthCredentialData{
   197  							ClientID: clientID,
   198  						},
   199  					},
   200  				},
   201  			},
   202  		}, nil)
   203  		defer mockedTx.AssertExpectations(t)
   204  		defer transactioner.AssertExpectations(t)
   205  		defer oauthSvc.AssertExpectations(t)
   206  		scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo)
   207  		// WHEN
   208  		err := scopeSyncSvc.SynchronizeClientScopes(context.TODO())
   209  		// THEN
   210  		assert.Nil(t, err)
   211  	})
   212  
   213  	t.Run("won't update scopes when returned client is not for update", func(t *testing.T) {
   214  		// GIVEN
   215  		oauthSvc := &automock.OAuthService{}
   216  		systemAuthRepo := &automock.SystemAuthRepo{}
   217  		oauthSvc.On("ListClients").Return([]*models.OAuth2Client{
   218  			{
   219  				ClientID: clientID,
   220  				Scope:    "scope",
   221  			},
   222  		}, nil)
   223  		mockedTx, transactioner := txtest.NewTransactionContextGenerator(nil).ThatSucceeds()
   224  		systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{
   225  			{
   226  				AppID: str.Ptr("app-id"),
   227  				Value: &model.Auth{
   228  					Credential: model.CredentialData{},
   229  				},
   230  			},
   231  		}, nil)
   232  		defer mockedTx.AssertExpectations(t)
   233  		defer transactioner.AssertExpectations(t)
   234  		defer oauthSvc.AssertExpectations(t)
   235  		scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo)
   236  		// WHEN
   237  		err := scopeSyncSvc.SynchronizeClientScopes(context.TODO())
   238  		// THEN
   239  		assert.Nil(t, err)
   240  	})
   241  
   242  	t.Run("fails when client update in Hydra fails", func(t *testing.T) {
   243  		// GIVEN
   244  		oauthSvc := &automock.OAuthService{}
   245  		systemAuthRepo := &automock.SystemAuthRepo{}
   246  		oauthSvc.On("ListClients").Return([]*models.OAuth2Client{
   247  			{
   248  				ClientID: clientID,
   249  				Scope:    "first",
   250  			},
   251  		}, nil)
   252  		oauthSvc.On("GetClientDetails", pkgmodel.ApplicationReference).Return(&oauth20.ClientDetails{
   253  			Scopes:     []string{"scope"},
   254  			GrantTypes: []string{},
   255  		}, nil)
   256  		oauthSvc.On("UpdateClient", mock.Anything, "client-id", pkgmodel.ApplicationReference).Return(errors.New("fail"))
   257  		mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error")).ThatSucceeds()
   258  		systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{
   259  			{
   260  				AppID: str.Ptr("app-id"),
   261  				Value: &model.Auth{
   262  					Credential: model.CredentialData{
   263  						Oauth: &model.OAuthCredentialData{
   264  							ClientID: clientID,
   265  						},
   266  					},
   267  				},
   268  			},
   269  		}, nil)
   270  		defer mockedTx.AssertExpectations(t)
   271  		defer transactioner.AssertExpectations(t)
   272  		defer oauthSvc.AssertExpectations(t)
   273  		scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo)
   274  		// WHEN
   275  		err := scopeSyncSvc.SynchronizeClientScopes(context.TODO())
   276  		// THEN
   277  		assert.EqualError(t, err, "Not all clients were updated successfully")
   278  	})
   279  
   280  	t.Run("will update scopes successfully", func(t *testing.T) {
   281  		// GIVEN
   282  		oauthSvc := &automock.OAuthService{}
   283  		systemAuthRepo := &automock.SystemAuthRepo{}
   284  		oauthSvc.On("ListClients").Return([]*models.OAuth2Client{
   285  			{
   286  				ClientID: clientID,
   287  				Scope:    "first",
   288  			},
   289  		}, nil)
   290  		oauthSvc.On("GetClientDetails", pkgmodel.ApplicationReference).Return(&oauth20.ClientDetails{
   291  			Scopes:     []string{"scope"},
   292  			GrantTypes: []string{},
   293  		}, nil)
   294  		oauthSvc.On("UpdateClient", mock.Anything, "client-id", pkgmodel.ApplicationReference).Return(nil)
   295  		mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error")).ThatSucceeds()
   296  		systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{
   297  			{
   298  				AppID: str.Ptr("app-id"),
   299  				Value: &model.Auth{
   300  					Credential: model.CredentialData{
   301  						Oauth: &model.OAuthCredentialData{
   302  							ClientID: clientID,
   303  						},
   304  					},
   305  				},
   306  			},
   307  		}, nil)
   308  		defer mockedTx.AssertExpectations(t)
   309  		defer transactioner.AssertExpectations(t)
   310  		defer oauthSvc.AssertExpectations(t)
   311  		scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo)
   312  		// WHEN
   313  		err := scopeSyncSvc.SynchronizeClientScopes(context.TODO())
   314  		// THEN
   315  		assert.Nil(t, err)
   316  	})
   317  }