github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/oauth20/resolver_test.go (about) 1 package oauth20_test 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/pkg/str" 12 13 "github.com/kyma-incubator/compass/components/director/internal/domain/oauth20" 14 "github.com/kyma-incubator/compass/components/director/internal/domain/oauth20/automock" 15 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 16 persistenceautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock" 17 "github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest" 18 "github.com/pkg/errors" 19 "github.com/stretchr/testify/assert" 20 "github.com/stretchr/testify/require" 21 ) 22 23 func TestResolver_CommonRequestClientCredentialsSuccess(t *testing.T) { 24 // GIVEN 25 id := "foo" 26 clientID := "clientid" 27 txGen := txtest.NewTransactionContextGenerator(nil) 28 expectedResult := fixGQLSystemAuth(clientID) 29 credsData := &model.OAuthCredentialDataInput{ 30 ClientID: "clientid", 31 ClientSecret: "secret", 32 URL: "url", 33 } 34 authInput := &model.AuthInput{Credential: &model.CredentialDataInput{Oauth: credsData}} 35 36 testCases := []struct { 37 Name string 38 ObjType pkgmodel.SystemAuthReferenceObjectType 39 Method func(resolver *oauth20.Resolver, ctx context.Context, id string) (graphql.SystemAuth, error) 40 RtmID *string 41 AppID *string 42 IntSysID *string 43 RuntimeServiceFn func() *automock.RuntimeService 44 ApplicationServiceFn func() *automock.ApplicationService 45 IntegrationSystemServiceFn func() *automock.IntegrationSystemService 46 }{ 47 { 48 Name: "Runtime", 49 RtmID: &id, 50 ObjType: pkgmodel.RuntimeReference, 51 RuntimeServiceFn: func() *automock.RuntimeService { 52 rtmSvc := &automock.RuntimeService{} 53 rtmSvc.On("Exist", txtest.CtxWithDBMatcher(), id).Return(true, nil).Once() 54 return rtmSvc 55 }, 56 ApplicationServiceFn: func() *automock.ApplicationService { 57 appSvc := &automock.ApplicationService{} 58 return appSvc 59 }, 60 IntegrationSystemServiceFn: func() *automock.IntegrationSystemService { 61 isSvc := &automock.IntegrationSystemService{} 62 return isSvc 63 }, 64 Method: func(resolver *oauth20.Resolver, ctx context.Context, id string) (graphql.SystemAuth, error) { 65 return resolver.RequestClientCredentialsForRuntime(ctx, id) 66 }, 67 }, 68 { 69 Name: "Application", 70 AppID: &id, 71 ObjType: pkgmodel.ApplicationReference, 72 RuntimeServiceFn: func() *automock.RuntimeService { 73 rtmSvc := &automock.RuntimeService{} 74 return rtmSvc 75 }, 76 ApplicationServiceFn: func() *automock.ApplicationService { 77 appSvc := &automock.ApplicationService{} 78 appSvc.On("Exist", txtest.CtxWithDBMatcher(), id).Return(true, nil).Once() 79 return appSvc 80 }, 81 IntegrationSystemServiceFn: func() *automock.IntegrationSystemService { 82 isSvc := &automock.IntegrationSystemService{} 83 return isSvc 84 }, 85 Method: func(resolver *oauth20.Resolver, ctx context.Context, id string) (graphql.SystemAuth, error) { 86 return resolver.RequestClientCredentialsForApplication(ctx, id) 87 }, 88 }, 89 { 90 Name: "Integration System", 91 IntSysID: &id, 92 ObjType: pkgmodel.IntegrationSystemReference, 93 RuntimeServiceFn: func() *automock.RuntimeService { 94 rtmSvc := &automock.RuntimeService{} 95 return rtmSvc 96 }, 97 ApplicationServiceFn: func() *automock.ApplicationService { 98 appSvc := &automock.ApplicationService{} 99 return appSvc 100 }, 101 IntegrationSystemServiceFn: func() *automock.IntegrationSystemService { 102 isSvc := &automock.IntegrationSystemService{} 103 isSvc.On("Exists", txtest.CtxWithDBMatcher(), id).Return(true, nil).Once() 104 return isSvc 105 }, 106 Method: func(resolver *oauth20.Resolver, ctx context.Context, id string) (graphql.SystemAuth, error) { 107 return resolver.RequestClientCredentialsForIntegrationSystem(ctx, id) 108 }, 109 }, 110 } 111 112 for _, testCase := range testCases { 113 t.Run(testCase.Name, func(t *testing.T) { 114 modelSystemAuth := fixModelSystemAuth(clientID, testCase.RtmID, testCase.AppID, testCase.IntSysID) 115 116 persist, transact := txGen.ThatSucceeds() 117 defer persist.AssertExpectations(t) 118 defer transact.AssertExpectations(t) 119 120 svc := &automock.Service{} 121 svc.On("CreateClientCredentials", txtest.CtxWithDBMatcher(), testCase.ObjType).Return(credsData, nil).Once() 122 defer svc.AssertExpectations(t) 123 124 rtmSvc := testCase.RuntimeServiceFn() 125 defer rtmSvc.AssertExpectations(t) 126 127 appSvc := testCase.ApplicationServiceFn() 128 defer appSvc.AssertExpectations(t) 129 130 isSvc := testCase.IntegrationSystemServiceFn() 131 defer isSvc.AssertExpectations(t) 132 133 systemAuthSvc := &automock.SystemAuthService{} 134 systemAuthSvc.On("CreateWithCustomID", txtest.CtxWithDBMatcher(), clientID, testCase.ObjType, id, authInput).Return(clientID, nil).Once() 135 systemAuthSvc.On("GetByIDForObject", txtest.CtxWithDBMatcher(), testCase.ObjType, clientID).Return(modelSystemAuth, nil).Once() 136 defer systemAuthSvc.AssertExpectations(t) 137 138 systemAuthConv := &automock.SystemAuthConverter{} 139 systemAuthConv.On("ToGraphQL", modelSystemAuth).Return(expectedResult, nil).Once() 140 defer systemAuthConv.AssertExpectations(t) 141 142 resolver := oauth20.NewResolver(transact, svc, appSvc, rtmSvc, isSvc, systemAuthSvc, systemAuthConv) 143 144 // When 145 result, err := testCase.Method(resolver, context.TODO(), id) 146 147 // Then 148 assert.Equal(t, expectedResult, result) 149 assert.Nil(t, err) 150 }) 151 } 152 } 153 154 func TestResolver_CommonRequestClientCredentialsError(t *testing.T) { 155 // GIVEN 156 id := "foo" 157 objType := pkgmodel.RuntimeReference 158 clientID := "clientid" 159 testErr := errors.New("test error") 160 txGen := txtest.NewTransactionContextGenerator(testErr) 161 modelSystemAuth := fixModelSystemAuth(clientID, &id, nil, nil) 162 credsData := &model.OAuthCredentialDataInput{ 163 ClientID: "clientid", 164 ClientSecret: "secret", 165 URL: "url", 166 } 167 authInput := &model.AuthInput{Credential: &model.CredentialDataInput{Oauth: credsData}} 168 169 testCases := []struct { 170 Name string 171 ExpectedError error 172 RuntimeServiceFn func() *automock.RuntimeService 173 ServiceFn func() *automock.Service 174 SystemAuthServiceFn func() *automock.SystemAuthService 175 TransactionerFn func() (*persistenceautomock.PersistenceTx, *persistenceautomock.Transactioner) 176 }{ 177 { 178 Name: "Error - Transaction Commit", 179 ExpectedError: testErr, 180 TransactionerFn: txGen.ThatFailsOnCommit, 181 RuntimeServiceFn: func() *automock.RuntimeService { 182 rtmSvc := &automock.RuntimeService{} 183 rtmSvc.On("Exist", txtest.CtxWithDBMatcher(), id).Return(true, nil).Once() 184 return rtmSvc 185 }, 186 ServiceFn: func() *automock.Service { 187 svc := &automock.Service{} 188 svc.On("CreateClientCredentials", txtest.CtxWithDBMatcher(), objType).Return(credsData, nil).Once() 189 svc.On("DeleteClientCredentials", txtest.CtxWithDBMatcher(), clientID).Return(nil).Once() 190 return svc 191 }, 192 SystemAuthServiceFn: func() *automock.SystemAuthService { 193 systemAuthSvc := &automock.SystemAuthService{} 194 systemAuthSvc.On("CreateWithCustomID", txtest.CtxWithDBMatcher(), clientID, objType, id, authInput).Return(clientID, nil).Once() 195 systemAuthSvc.On("GetByIDForObject", txtest.CtxWithDBMatcher(), objType, clientID).Return(modelSystemAuth, nil).Once() 196 return systemAuthSvc 197 }, 198 }, 199 { 200 Name: "Error - Get System Auth", 201 ExpectedError: testErr, 202 TransactionerFn: txGen.ThatDoesntExpectCommit, 203 RuntimeServiceFn: func() *automock.RuntimeService { 204 rtmSvc := &automock.RuntimeService{} 205 rtmSvc.On("Exist", txtest.CtxWithDBMatcher(), id).Return(true, nil).Once() 206 return rtmSvc 207 }, 208 ServiceFn: func() *automock.Service { 209 svc := &automock.Service{} 210 svc.On("CreateClientCredentials", txtest.CtxWithDBMatcher(), objType).Return(credsData, nil).Once() 211 svc.On("DeleteClientCredentials", txtest.CtxWithDBMatcher(), clientID).Return(nil).Once() 212 return svc 213 }, 214 SystemAuthServiceFn: func() *automock.SystemAuthService { 215 systemAuthSvc := &automock.SystemAuthService{} 216 systemAuthSvc.On("CreateWithCustomID", txtest.CtxWithDBMatcher(), clientID, objType, id, authInput).Return(clientID, nil).Once() 217 systemAuthSvc.On("GetByIDForObject", txtest.CtxWithDBMatcher(), objType, clientID).Return(nil, testErr).Once() 218 return systemAuthSvc 219 }, 220 }, 221 { 222 Name: "Error - Create System Auth", 223 ExpectedError: testErr, 224 TransactionerFn: txGen.ThatDoesntExpectCommit, 225 RuntimeServiceFn: func() *automock.RuntimeService { 226 rtmSvc := &automock.RuntimeService{} 227 rtmSvc.On("Exist", txtest.CtxWithDBMatcher(), id).Return(true, nil).Once() 228 return rtmSvc 229 }, 230 ServiceFn: func() *automock.Service { 231 svc := &automock.Service{} 232 svc.On("CreateClientCredentials", txtest.CtxWithDBMatcher(), objType).Return(credsData, nil).Once() 233 svc.On("DeleteClientCredentials", txtest.CtxWithDBMatcher(), clientID).Return(nil).Once() 234 return svc 235 }, 236 SystemAuthServiceFn: func() *automock.SystemAuthService { 237 systemAuthSvc := &automock.SystemAuthService{} 238 systemAuthSvc.On("CreateWithCustomID", txtest.CtxWithDBMatcher(), clientID, objType, id, authInput).Return("", testErr).Once() 239 return systemAuthSvc 240 }, 241 }, 242 { 243 Name: "Error - Multiple: Create System Auth and Delete Client", 244 ExpectedError: errors.New("2 errors occurred:\n\t* test error\n\t* test error"), 245 TransactionerFn: txGen.ThatDoesntExpectCommit, 246 RuntimeServiceFn: func() *automock.RuntimeService { 247 rtmSvc := &automock.RuntimeService{} 248 rtmSvc.On("Exist", txtest.CtxWithDBMatcher(), id).Return(true, nil).Once() 249 return rtmSvc 250 }, 251 ServiceFn: func() *automock.Service { 252 svc := &automock.Service{} 253 svc.On("CreateClientCredentials", txtest.CtxWithDBMatcher(), objType).Return(credsData, nil).Once() 254 svc.On("DeleteClientCredentials", txtest.CtxWithDBMatcher(), clientID).Return(testErr).Once() 255 return svc 256 }, 257 SystemAuthServiceFn: func() *automock.SystemAuthService { 258 systemAuthSvc := &automock.SystemAuthService{} 259 systemAuthSvc.On("CreateWithCustomID", txtest.CtxWithDBMatcher(), clientID, objType, id, authInput).Return("", testErr).Once() 260 return systemAuthSvc 261 }, 262 }, 263 { 264 Name: "Error - Create Client", 265 ExpectedError: testErr, 266 TransactionerFn: txGen.ThatDoesntExpectCommit, 267 RuntimeServiceFn: func() *automock.RuntimeService { 268 rtmSvc := &automock.RuntimeService{} 269 rtmSvc.On("Exist", txtest.CtxWithDBMatcher(), id).Return(true, nil).Once() 270 return rtmSvc 271 }, 272 ServiceFn: func() *automock.Service { 273 svc := &automock.Service{} 274 svc.On("CreateClientCredentials", txtest.CtxWithDBMatcher(), objType).Return(nil, testErr).Once() 275 return svc 276 }, 277 SystemAuthServiceFn: func() *automock.SystemAuthService { 278 systemAuthSvc := &automock.SystemAuthService{} 279 return systemAuthSvc 280 }, 281 }, 282 { 283 Name: "Error - Empty Credentials", 284 ExpectedError: errors.New("client credentials cannot be empty"), 285 TransactionerFn: txGen.ThatDoesntExpectCommit, 286 RuntimeServiceFn: func() *automock.RuntimeService { 287 rtmSvc := &automock.RuntimeService{} 288 rtmSvc.On("Exist", txtest.CtxWithDBMatcher(), id).Return(true, nil).Once() 289 return rtmSvc 290 }, 291 ServiceFn: func() *automock.Service { 292 svc := &automock.Service{} 293 svc.On("CreateClientCredentials", txtest.CtxWithDBMatcher(), objType).Return(nil, nil).Once() 294 return svc 295 }, 296 SystemAuthServiceFn: func() *automock.SystemAuthService { 297 systemAuthSvc := &automock.SystemAuthService{} 298 return systemAuthSvc 299 }, 300 }, 301 { 302 Name: "Error - Exists", 303 ExpectedError: testErr, 304 TransactionerFn: txGen.ThatDoesntExpectCommit, 305 RuntimeServiceFn: func() *automock.RuntimeService { 306 rtmSvc := &automock.RuntimeService{} 307 rtmSvc.On("Exist", txtest.CtxWithDBMatcher(), id).Return(false, testErr).Once() 308 return rtmSvc 309 }, 310 ServiceFn: func() *automock.Service { 311 svc := &automock.Service{} 312 return svc 313 }, 314 SystemAuthServiceFn: func() *automock.SystemAuthService { 315 systemAuthSvc := &automock.SystemAuthService{} 316 return systemAuthSvc 317 }, 318 }, 319 { 320 Name: "Error - Doesn't Exist", 321 ExpectedError: errors.New("Runtime with ID 'foo' not found"), 322 TransactionerFn: txGen.ThatDoesntExpectCommit, 323 RuntimeServiceFn: func() *automock.RuntimeService { 324 rtmSvc := &automock.RuntimeService{} 325 rtmSvc.On("Exist", txtest.CtxWithDBMatcher(), id).Return(false, nil).Once() 326 return rtmSvc 327 }, 328 ServiceFn: func() *automock.Service { 329 svc := &automock.Service{} 330 return svc 331 }, 332 SystemAuthServiceFn: func() *automock.SystemAuthService { 333 systemAuthSvc := &automock.SystemAuthService{} 334 return systemAuthSvc 335 }, 336 }, 337 { 338 Name: "Error - Transaction Begin error", 339 ExpectedError: testErr, 340 TransactionerFn: txGen.ThatFailsOnBegin, 341 RuntimeServiceFn: func() *automock.RuntimeService { 342 rtmSvc := &automock.RuntimeService{} 343 return rtmSvc 344 }, 345 ServiceFn: func() *automock.Service { 346 svc := &automock.Service{} 347 return svc 348 }, 349 SystemAuthServiceFn: func() *automock.SystemAuthService { 350 systemAuthSvc := &automock.SystemAuthService{} 351 return systemAuthSvc 352 }, 353 }, 354 } 355 356 for _, testCase := range testCases { 357 t.Run(testCase.Name, func(t *testing.T) { 358 persist, transact := testCase.TransactionerFn() 359 defer persist.AssertExpectations(t) 360 defer transact.AssertExpectations(t) 361 362 svc := testCase.ServiceFn() 363 defer svc.AssertExpectations(t) 364 365 rtmSvc := testCase.RuntimeServiceFn() 366 defer rtmSvc.AssertExpectations(t) 367 368 systemAuthSvc := testCase.SystemAuthServiceFn() 369 defer systemAuthSvc.AssertExpectations(t) 370 371 resolver := oauth20.NewResolver(transact, svc, nil, rtmSvc, nil, systemAuthSvc, nil) 372 373 // When 374 _, err := resolver.RequestClientCredentialsForRuntime(context.TODO(), id) 375 376 // Then 377 require.Error(t, err) 378 assert.Contains(t, err.Error(), testCase.ExpectedError.Error()) 379 }) 380 } 381 } 382 383 func fixModelSystemAuth(clientID string, rtmID, appID, isID *string) *pkgmodel.SystemAuth { 384 return &pkgmodel.SystemAuth{ 385 ID: clientID, 386 TenantID: str.Ptr(""), 387 RuntimeID: rtmID, 388 IntegrationSystemID: isID, 389 AppID: appID, 390 Value: &model.Auth{ 391 Credential: model.CredentialData{ 392 Oauth: &model.OAuthCredentialData{ 393 ClientID: clientID, 394 ClientSecret: "secret", 395 URL: "url", 396 }, 397 }, 398 }, 399 } 400 } 401 402 func fixGQLSystemAuth(clientID string) graphql.SystemAuth { 403 oauthCredsData := graphql.OAuthCredentialData{ 404 ClientID: clientID, 405 ClientSecret: "secret", 406 URL: "url", 407 } 408 return &graphql.IntSysSystemAuth{ 409 ID: "sysauth-id", 410 Auth: &graphql.Auth{ 411 Credential: oauthCredsData, 412 }, 413 } 414 }