github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/labeldef/resolver_test.go (about) 1 package labeldef_test 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "testing" 8 9 "github.com/kyma-incubator/compass/components/director/pkg/resource" 10 11 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 12 13 "github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest" 14 15 "github.com/kyma-incubator/compass/components/director/internal/domain/labeldef" 16 "github.com/kyma-incubator/compass/components/director/internal/domain/labeldef/automock" 17 "github.com/kyma-incubator/compass/components/director/internal/domain/tenant" 18 "github.com/kyma-incubator/compass/components/director/internal/model" 19 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 20 "github.com/kyma-incubator/compass/components/director/pkg/persistence" 21 pautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock" 22 "github.com/pkg/errors" 23 "github.com/stretchr/testify/assert" 24 "github.com/stretchr/testify/mock" 25 "github.com/stretchr/testify/require" 26 ) 27 28 var ( 29 testScenario = "test-scenario" 30 testScenarios = []string{testScenario} 31 ) 32 33 func TestCreateLabelDefinition(t *testing.T) { 34 scenariosSchema := model.NewScenariosSchema(testScenarios) 35 var scenarioSchemaInt interface{} = scenariosSchema 36 37 labelDefInput := graphql.LabelDefinitionInput{ 38 Key: "scenarios", 39 Schema: getJSONSchemaFromSchema(t, &scenarioSchemaInt), 40 } 41 tnt := "tenant" 42 storedModel := model.LabelDefinition{Key: model.ScenariosKey, Tenant: tnt, ID: fixUUID(), Schema: &scenarioSchemaInt} 43 externalTnt := "external-tenant" 44 testErr := errors.New("test error") 45 notFoundError := apperrors.NewNotFoundErrorWithMessage(resource.LabelDefinition, fixUUID(), "test-error") 46 txGen := txtest.NewTransactionContextGenerator(testErr) 47 48 t.Run("successfully created Label Definition", func(t *testing.T) { 49 // GIVEN 50 persist, transact := txGen.ThatSucceeds() 51 52 mockService := &automock.Service{} 53 defer mockService.AssertExpectations(t) 54 mockConverter := &automock.ModelConverter{} 55 defer mockConverter.AssertExpectations(t) 56 mockFormationsService := &automock.FormationService{} 57 defer mockFormationsService.AssertExpectations(t) 58 59 mockConverter.On("FromGraphQL", labelDefInput, tnt).Return(model.LabelDefinition{ 60 Key: model.ScenariosKey, 61 Tenant: tnt, 62 Schema: &scenarioSchemaInt, 63 }, nil) 64 65 defer mockService.AssertExpectations(t) 66 mockService.On("Get", 67 contextThatHasTenant(tnt), 68 tnt, model.ScenariosKey).Return(nil, notFoundError).Once() 69 70 mockFormationsService.On("CreateFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: testScenario}, model.DefaultTemplateName).Return(nil, nil) 71 72 mockService.On("Get", 73 contextThatHasTenant(tnt), 74 tnt, model.ScenariosKey).Return(&storedModel, nil).Once() 75 76 mockConverter.On("ToGraphQL", storedModel).Return(graphql.LabelDefinition{ 77 Key: model.ScenariosKey, 78 Schema: getJSONSchemaFromSchema(t, &scenarioSchemaInt), 79 }, nil) 80 81 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 82 sut := labeldef.NewResolver(transact, mockService, mockFormationsService, mockConverter) 83 // WHEN 84 actual, err := sut.CreateLabelDefinition(ctx, labelDefInput) 85 // THEN 86 require.NoError(t, err) 87 persist.AssertExpectations(t) 88 transact.AssertExpectations(t) 89 assert.Equal(t, model.ScenariosKey, actual.Key) 90 }) 91 92 t.Run("got error on converting to graphql", func(t *testing.T) { 93 // GIVEN 94 persist, transact := txGen.ThatDoesntExpectCommit() 95 mockService := &automock.Service{} 96 defer mockService.AssertExpectations(t) 97 98 mockFormationsService := &automock.FormationService{} 99 defer mockFormationsService.AssertExpectations(t) 100 mockService.On("Get", 101 contextThatHasTenant(tnt), 102 tnt, model.ScenariosKey).Return(nil, notFoundError).Once() 103 104 mockFormationsService.On("CreateFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: testScenario}, model.DefaultTemplateName).Return(nil, nil) 105 106 mockService.On("Get", 107 contextThatHasTenant(tnt), 108 tnt, model.ScenariosKey).Return(&storedModel, nil).Once() 109 110 mockConverter := &automock.ModelConverter{} 111 defer mockConverter.AssertExpectations(t) 112 mockConverter.On("FromGraphQL", labelDefInput, tnt).Return(model.LabelDefinition{ 113 Key: model.ScenariosKey, 114 Tenant: tnt, 115 Schema: &scenarioSchemaInt, 116 }, nil) 117 mockConverter.On("ToGraphQL", storedModel).Return(graphql.LabelDefinition{}, notFoundError) 118 119 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 120 sut := labeldef.NewResolver(transact, mockService, mockFormationsService, mockConverter) 121 // WHEN 122 _, err := sut.CreateLabelDefinition(ctx, labelDefInput) 123 // THEN 124 require.Error(t, err) 125 require.EqualError(t, err, notFoundError.Error()) 126 persist.AssertExpectations(t) 127 transact.AssertExpectations(t) 128 }) 129 130 t.Run("got error different from not found while getting label definition", func(t *testing.T) { 131 // GIVEN 132 persist, transact := txGen.ThatDoesntExpectCommit() 133 134 mockConverter := &automock.ModelConverter{} 135 defer mockConverter.AssertExpectations(t) 136 mockConverter.On("FromGraphQL", labelDefInput, tnt).Return(model.LabelDefinition{ 137 Key: model.ScenariosKey, 138 Tenant: tnt, 139 Schema: &scenarioSchemaInt, 140 }, nil) 141 142 mockService := &automock.Service{} 143 defer mockService.AssertExpectations(t) 144 mockService.On("Get", 145 contextThatHasTenant(tnt), 146 tnt, model.ScenariosKey).Return(nil, errors.New("db error")).Once() 147 148 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 149 sut := labeldef.NewResolver(transact, mockService, nil, mockConverter) 150 151 // WHEN 152 _, err := sut.CreateLabelDefinition(ctx, labelDefInput) 153 // THEN 154 require.Error(t, err) 155 require.EqualError(t, err, "while getting label definition: db error") 156 persist.AssertExpectations(t) 157 transact.AssertExpectations(t) 158 }) 159 160 t.Run("got error during formation creating", func(t *testing.T) { 161 // GIVEN 162 persist, transact := txGen.ThatDoesntExpectCommit() 163 164 mockService := &automock.Service{} 165 defer mockService.AssertExpectations(t) 166 mockConverter := &automock.ModelConverter{} 167 defer mockConverter.AssertExpectations(t) 168 mockFormationsService := &automock.FormationService{} 169 defer mockFormationsService.AssertExpectations(t) 170 171 mockConverter.On("FromGraphQL", labelDefInput, tnt).Return(model.LabelDefinition{ 172 Key: model.ScenariosKey, 173 Tenant: tnt, 174 Schema: &scenarioSchemaInt, 175 }, nil) 176 177 defer mockService.AssertExpectations(t) 178 mockService.On("Get", 179 contextThatHasTenant(tnt), 180 tnt, model.ScenariosKey).Return(nil, notFoundError).Once() 181 182 mockFormationsService.On("CreateFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: testScenario}, model.DefaultTemplateName).Return(nil, notFoundError) 183 184 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 185 sut := labeldef.NewResolver(transact, mockService, mockFormationsService, mockConverter) 186 // WHEN 187 _, err := sut.CreateLabelDefinition(ctx, labelDefInput) 188 require.Error(t, err) 189 require.EqualError(t, err, fmt.Sprintf("while creating formation with name %s: %s", testScenario, notFoundError.Error())) 190 persist.AssertExpectations(t) 191 transact.AssertExpectations(t) 192 }) 193 194 t.Run("got error during getting updated label definition", func(t *testing.T) { 195 // GIVEN 196 persist, transact := txGen.ThatDoesntExpectCommit() 197 198 mockService := &automock.Service{} 199 defer mockService.AssertExpectations(t) 200 mockConverter := &automock.ModelConverter{} 201 defer mockConverter.AssertExpectations(t) 202 mockFormationsService := &automock.FormationService{} 203 defer mockFormationsService.AssertExpectations(t) 204 205 mockConverter.On("FromGraphQL", labelDefInput, tnt).Return(model.LabelDefinition{ 206 Key: model.ScenariosKey, 207 Tenant: tnt, 208 Schema: &scenarioSchemaInt, 209 }, nil) 210 211 defer mockService.AssertExpectations(t) 212 mockService.On("Get", 213 contextThatHasTenant(tnt), 214 tnt, model.ScenariosKey).Return(nil, notFoundError).Once() 215 216 mockFormationsService.On("CreateFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: testScenario}, model.DefaultTemplateName).Return(nil, nil) 217 218 mockService.On("Get", 219 contextThatHasTenant(tnt), 220 tnt, model.ScenariosKey).Return(nil, notFoundError).Once() 221 222 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 223 sut := labeldef.NewResolver(transact, mockService, mockFormationsService, mockConverter) 224 // WHEN 225 _, err := sut.CreateLabelDefinition(ctx, labelDefInput) 226 require.Error(t, err) 227 require.EqualError(t, err, fmt.Sprintf("while getting label definition: %s", notFoundError.Error())) 228 persist.AssertExpectations(t) 229 transact.AssertExpectations(t) 230 }) 231 232 t.Run("got error when missing tenant in context", func(t *testing.T) { 233 // GIVEN 234 sut := labeldef.NewResolver(nil, nil, nil, nil) 235 // WHEN 236 _, err := sut.CreateLabelDefinition(context.TODO(), graphql.LabelDefinitionInput{}) 237 // THEN 238 require.EqualError(t, err, "cannot read tenant from context") 239 }) 240 241 t.Run("got error on starting transaction", func(t *testing.T) { 242 // GIVEN 243 persist, transact := txGen.ThatFailsOnBegin() 244 ctx := tenant.SaveToContext(context.TODO(), "tenant", "external-tenant") 245 246 mockConverter := &automock.ModelConverter{} 247 defer mockConverter.AssertExpectations(t) 248 sut := labeldef.NewResolver(transact, nil, nil, mockConverter) 249 // WHEN 250 _, err := sut.CreateLabelDefinition(ctx, graphql.LabelDefinitionInput{Key: "scenarios"}) 251 // THEN 252 require.EqualError(t, err, fmt.Sprintf("while starting transaction: %s", testErr.Error())) 253 transact.AssertExpectations(t) 254 persist.AssertExpectations(t) 255 }) 256 257 t.Run("got error on creating Label Definition", func(t *testing.T) { 258 // GIVEN 259 persist, transact := txGen.ThatDoesntExpectCommit() 260 mockService := &automock.Service{} 261 defer mockService.AssertExpectations(t) 262 mockService.On("Get", 263 contextThatHasTenant(tnt), 264 tnt, model.ScenariosKey).Return(&storedModel, nil).Once() 265 266 mockConverter := &automock.ModelConverter{} 267 defer mockConverter.AssertExpectations(t) 268 mockConverter.On("FromGraphQL", labelDefInput, tnt).Return(model.LabelDefinition{ 269 Key: model.ScenariosKey, 270 Tenant: tnt, 271 Schema: &scenarioSchemaInt, 272 }, nil) 273 274 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 275 sut := labeldef.NewResolver(transact, mockService, nil, mockConverter) 276 // WHEN 277 _, err := sut.CreateLabelDefinition(ctx, labelDefInput) 278 // THEN 279 transact.AssertExpectations(t) 280 persist.AssertExpectations(t) 281 require.EqualError(t, err, "Object is not unique [object=labelDefinition]") 282 }) 283 284 t.Run("got error on converting to model", func(t *testing.T) { 285 // GIVEN 286 persist, transact := txGen.ThatDoesntExpectCommit() 287 mockConverter := &automock.ModelConverter{} 288 defer mockConverter.AssertExpectations(t) 289 mockConverter.On("FromGraphQL", labelDefInput, tnt).Return(model.LabelDefinition{}, errors.New("json schema is not valid")) 290 291 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 292 sut := labeldef.NewResolver(transact, nil, nil, mockConverter) 293 // WHEN 294 _, err := sut.CreateLabelDefinition(ctx, labelDefInput) 295 // THEN 296 require.EqualError(t, err, "json schema is not valid") 297 transact.AssertExpectations(t) 298 persist.AssertExpectations(t) 299 }) 300 301 t.Run("got error on committing transaction", func(t *testing.T) { 302 // GIVEN 303 persist, transact := txGen.ThatFailsOnCommit() 304 mockService := &automock.Service{} 305 defer mockService.AssertExpectations(t) 306 mockConverter := &automock.ModelConverter{} 307 defer mockConverter.AssertExpectations(t) 308 mockFormationsService := &automock.FormationService{} 309 defer mockFormationsService.AssertExpectations(t) 310 311 mockConverter.On("FromGraphQL", labelDefInput, tnt).Return(model.LabelDefinition{ 312 Key: model.ScenariosKey, 313 Tenant: tnt, 314 Schema: &scenarioSchemaInt, 315 }, nil) 316 317 defer mockService.AssertExpectations(t) 318 mockService.On("Get", 319 contextThatHasTenant(tnt), 320 tnt, model.ScenariosKey).Return(nil, notFoundError).Once() 321 322 mockFormationsService.On("CreateFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: testScenario}, model.DefaultTemplateName).Return(nil, nil) 323 324 mockService.On("Get", 325 contextThatHasTenant(tnt), 326 tnt, model.ScenariosKey).Return(&storedModel, nil).Once() 327 328 mockConverter.On("ToGraphQL", storedModel).Return(graphql.LabelDefinition{ 329 Key: model.ScenariosKey, 330 Schema: getJSONSchemaFromSchema(t, &scenarioSchemaInt), 331 }, nil) 332 333 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 334 sut := labeldef.NewResolver(transact, mockService, mockFormationsService, mockConverter) 335 // WHEN 336 _, err := sut.CreateLabelDefinition(ctx, labelDefInput) 337 // THEN 338 require.EqualError(t, err, fmt.Sprintf("while committing transaction: %s", testErr.Error())) 339 transact.AssertExpectations(t) 340 persist.AssertExpectations(t) 341 }) 342 } 343 344 func TestQueryLabelDefinitions(t *testing.T) { 345 tnt := "tenant" 346 externalTnt := "external-tenant" 347 testErr := errors.New("test error") 348 txGen := txtest.NewTransactionContextGenerator(testErr) 349 350 t.Run("successfully returns definitions", func(t *testing.T) { 351 // GIVEN 352 persist, transact := txGen.ThatSucceeds() 353 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 354 givenModels := []model.LabelDefinition{{ 355 ID: "id1", 356 Key: "key1", 357 Tenant: tnt, 358 }, {ID: "id2", Key: "key2", Tenant: tnt}} 359 360 mockService := &automock.Service{} 361 defer mockService.AssertExpectations(t) 362 mockService.On("List", 363 contextThatHasTenant(tnt), 364 tnt).Return(givenModels, nil) 365 366 mockConverter := &automock.ModelConverter{} 367 defer mockConverter.AssertExpectations(t) 368 mockConverter.On("ToGraphQL", givenModels[0]).Return(graphql.LabelDefinition{ 369 Key: "key1", 370 }, nil) 371 mockConverter.On("ToGraphQL", givenModels[1]).Return(graphql.LabelDefinition{ 372 Key: "key2", 373 }, nil) 374 375 sut := labeldef.NewResolver(transact, mockService, nil, mockConverter) 376 // WHEN 377 actual, err := sut.LabelDefinitions(ctx) 378 // THEN 379 require.NoError(t, err) 380 require.Len(t, actual, 2) 381 assert.Equal(t, actual[0].Key, "key1") 382 assert.Equal(t, actual[1].Key, "key2") 383 transact.AssertExpectations(t) 384 persist.AssertExpectations(t) 385 }) 386 387 t.Run("got error when convert to graphql failed", func(t *testing.T) { 388 // GIVEN 389 persist, transact := txGen.ThatSucceeds() 390 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 391 givenModels := []model.LabelDefinition{{ID: "id1", Key: "key1", Tenant: tnt}, {ID: "id2", Key: "key2", Tenant: tnt}} 392 393 mockService := &automock.Service{} 394 defer mockService.AssertExpectations(t) 395 mockService.On("List", 396 contextThatHasTenant(tnt), 397 tnt).Return(givenModels, nil) 398 399 mockConverter := &automock.ModelConverter{} 400 defer mockConverter.AssertExpectations(t) 401 mockConverter.On("ToGraphQL", givenModels[0]).Return(graphql.LabelDefinition{Key: "key1"}, nil) 402 mockConverter.On("ToGraphQL", givenModels[1]).Return(graphql.LabelDefinition{}, testErr) 403 404 sut := labeldef.NewResolver(transact, mockService, nil, mockConverter) 405 // WHEN 406 _, err := sut.LabelDefinitions(ctx) 407 // THEN 408 require.Error(t, err) 409 transact.AssertExpectations(t) 410 persist.AssertExpectations(t) 411 }) 412 413 t.Run("successfully returns empty slice if no definitions", func(t *testing.T) { 414 // GIVEN 415 persist, transact := txGen.ThatSucceeds() 416 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 417 418 mockService := &automock.Service{} 419 defer mockService.AssertExpectations(t) 420 mockService.On("List", 421 contextThatHasTenant(tnt), 422 tnt).Return(nil, nil) 423 424 sut := labeldef.NewResolver(transact, mockService, nil, nil) 425 // WHEN 426 actual, err := sut.LabelDefinitions(ctx) 427 // THEN 428 require.NoError(t, err) 429 require.Empty(t, actual) 430 transact.AssertExpectations(t) 431 persist.AssertExpectations(t) 432 }) 433 434 t.Run("got error when missing tenant in context", func(t *testing.T) { 435 // GIVEN 436 sut := labeldef.NewResolver(nil, nil, nil, nil) 437 // WHEN 438 _, err := sut.LabelDefinitions(context.TODO()) 439 // THEN 440 require.EqualError(t, err, "cannot read tenant from context") 441 }) 442 443 t.Run("got error on starting transaction", func(t *testing.T) { 444 // GIVEN 445 persist, transact := txGen.ThatFailsOnBegin() 446 ctx := tenant.SaveToContext(context.TODO(), "tenant", "external-tenant") 447 sut := labeldef.NewResolver(transact, nil, nil, nil) 448 // WHEN 449 _, err := sut.LabelDefinitions(ctx) 450 // THEN 451 require.EqualError(t, err, "while starting transaction: test error") 452 transact.AssertExpectations(t) 453 persist.AssertExpectations(t) 454 }) 455 456 t.Run("got error on getting definitions from service", func(t *testing.T) { 457 // GIVEN 458 persist, transact := txGen.ThatDoesntExpectCommit() 459 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 460 461 mockService := &automock.Service{} 462 defer mockService.AssertExpectations(t) 463 mockService.On("List", contextThatHasTenant(tnt), tnt). 464 Return(nil, testErr) 465 466 sut := labeldef.NewResolver(transact, mockService, nil, nil) 467 // WHEN 468 _, err := sut.LabelDefinitions(ctx) 469 // THEN 470 require.EqualError(t, err, "while listing Label Definitions: test error") 471 transact.AssertExpectations(t) 472 persist.AssertExpectations(t) 473 }) 474 475 t.Run("got error on committing transaction", func(t *testing.T) { 476 // GIVEN 477 persist, transact := txGen.ThatFailsOnCommit() 478 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 479 480 mockService := &automock.Service{} 481 defer mockService.AssertExpectations(t) 482 mockService.On("List", contextThatHasTenant(tnt), tnt).Return(nil, nil) 483 484 sut := labeldef.NewResolver(transact, mockService, nil, nil) 485 // WHEN 486 _, err := sut.LabelDefinitions(ctx) 487 // THEN 488 require.EqualError(t, err, "while committing transaction: test error") 489 transact.AssertExpectations(t) 490 persist.AssertExpectations(t) 491 }) 492 } 493 494 func TestQueryGivenLabelDefinition(t *testing.T) { 495 tnt := "tenant" 496 externalTnt := "external-tenant" 497 testErr := errors.New("test error") 498 txGen := txtest.NewTransactionContextGenerator(testErr) 499 t.Run("successfully returns single definition", func(t *testing.T) { 500 // GIVEN 501 mockPersistanceCtx := &pautomock.PersistenceTx{} 502 defer mockPersistanceCtx.AssertExpectations(t) 503 mockPersistanceCtx.On("Commit").Return(nil) 504 505 mockTransactioner := &pautomock.Transactioner{} 506 mockTransactioner.On("Begin").Return(mockPersistanceCtx, nil) 507 mockTransactioner.On("RollbackUnlessCommitted", mock.Anything, mock.Anything).Return(false) 508 defer mockTransactioner.AssertExpectations(t) 509 510 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 511 givenModel := &model.LabelDefinition{ 512 ID: "id", 513 Key: "key", 514 Tenant: tnt, 515 } 516 517 mockService := &automock.Service{} 518 defer mockService.AssertExpectations(t) 519 mockService.On("Get", 520 contextThatHasTenant(tnt), 521 tnt, "key").Return(givenModel, nil) 522 523 mockConverter := &automock.ModelConverter{} 524 defer mockConverter.AssertExpectations(t) 525 mockConverter.On("ToGraphQL", *givenModel).Return(graphql.LabelDefinition{ 526 Key: "key", 527 }, nil) 528 529 sut := labeldef.NewResolver(mockTransactioner, mockService, nil, mockConverter) 530 // WHEN 531 actual, err := sut.LabelDefinition(ctx, "key") 532 // THEN 533 require.NoError(t, err) 534 assert.Equal(t, "key", actual.Key) 535 assert.Nil(t, actual.Schema) 536 }) 537 538 t.Run("returns error when convert to graphql failed", func(t *testing.T) { 539 // GIVEN 540 persist, transact := txGen.ThatSucceeds() 541 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 542 givenModel := &model.LabelDefinition{ID: "id", Key: "key", Tenant: tnt} 543 544 mockService := &automock.Service{} 545 defer mockService.AssertExpectations(t) 546 mockService.On("Get", contextThatHasTenant(tnt), tnt, "key").Return(givenModel, nil) 547 548 mockConverter := &automock.ModelConverter{} 549 defer mockConverter.AssertExpectations(t) 550 mockConverter.On("ToGraphQL", *givenModel).Return(graphql.LabelDefinition{}, testErr) 551 552 sut := labeldef.NewResolver(transact, mockService, nil, mockConverter) 553 // WHEN 554 _, err := sut.LabelDefinition(ctx, "key") 555 // THEN 556 require.Error(t, err) 557 require.EqualError(t, err, testErr.Error()) 558 transact.AssertExpectations(t) 559 persist.AssertExpectations(t) 560 }) 561 562 t.Run("returns nil if definition does not exist", func(t *testing.T) { 563 // GIVEN 564 mockPersistanceCtx := &pautomock.PersistenceTx{} 565 defer mockPersistanceCtx.AssertExpectations(t) 566 567 mockTransactioner := &pautomock.Transactioner{} 568 mockTransactioner.On("Begin").Return(mockPersistanceCtx, nil) 569 mockPersistanceCtx.On("Commit").Return(nil) 570 mockTransactioner.On("RollbackUnlessCommitted", mock.Anything, mock.Anything).Return(true) 571 defer mockTransactioner.AssertExpectations(t) 572 573 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 574 575 mockService := &automock.Service{} 576 defer mockService.AssertExpectations(t) 577 mockService.On("Get", 578 contextThatHasTenant(tnt), 579 tnt, "key").Return(nil, apperrors.NewNotFoundError(resource.LabelDefinition, "")) 580 581 sut := labeldef.NewResolver(mockTransactioner, mockService, nil, nil) 582 // WHEN 583 _, err := sut.LabelDefinition(ctx, "key") 584 // THEN 585 require.Nil(t, err) 586 }) 587 588 t.Run("got error on getting label definition from service", func(t *testing.T) { 589 // GIVEN 590 mockPersistanceCtx := &pautomock.PersistenceTx{} 591 defer mockPersistanceCtx.AssertExpectations(t) 592 593 mockTransactioner := &pautomock.Transactioner{} 594 mockTransactioner.On("Begin").Return(mockPersistanceCtx, nil) 595 mockTransactioner.On("RollbackUnlessCommitted", mock.Anything, mock.Anything).Return(true) 596 defer mockTransactioner.AssertExpectations(t) 597 598 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 599 600 mockService := &automock.Service{} 601 defer mockService.AssertExpectations(t) 602 mockService.On("Get", mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("error from service")) 603 604 sut := labeldef.NewResolver(mockTransactioner, mockService, nil, nil) 605 // WHEN 606 _, err := sut.LabelDefinition(ctx, "key") 607 // THEN 608 require.EqualError(t, err, "while getting Label Definition: error from service") 609 }) 610 611 t.Run("got error when missing tenant in context", func(t *testing.T) { 612 // GIVEN 613 sut := labeldef.NewResolver(nil, nil, nil, nil) 614 // WHEN 615 _, err := sut.LabelDefinition(context.TODO(), "anything") 616 // THEN 617 require.EqualError(t, err, "cannot read tenant from context") 618 }) 619 620 t.Run("got error on starting transaction", func(t *testing.T) { 621 // GIVEN 622 mockTransactioner := getInvalidMockTransactioner() 623 defer mockTransactioner.AssertExpectations(t) 624 ctx := tenant.SaveToContext(context.TODO(), "tenant", "external-tenant") 625 sut := labeldef.NewResolver(mockTransactioner, nil, nil, nil) 626 // WHEN 627 _, err := sut.LabelDefinition(ctx, "anything") 628 // THEN 629 require.EqualError(t, err, "while starting transaction: some error") 630 }) 631 632 t.Run("got error on committing transaction", func(t *testing.T) { 633 // GIVEN 634 mockPersistanceCtx := &pautomock.PersistenceTx{} 635 defer mockPersistanceCtx.AssertExpectations(t) 636 mockPersistanceCtx.On("Commit").Return(errors.New("commit errror")) 637 638 mockTransactioner := &pautomock.Transactioner{} 639 mockTransactioner.On("Begin").Return(mockPersistanceCtx, nil) 640 mockTransactioner.On("RollbackUnlessCommitted", mock.Anything, mock.Anything).Return(true) 641 defer mockTransactioner.AssertExpectations(t) 642 643 ctx := tenant.SaveToContext(context.TODO(), tnt, externalTnt) 644 645 mockService := &automock.Service{} 646 defer mockService.AssertExpectations(t) 647 mockService.On("Get", 648 contextThatHasTenant(tnt), 649 tnt, "key").Return(nil, nil) 650 651 sut := labeldef.NewResolver(mockTransactioner, mockService, nil, nil) 652 // WHEN 653 _, err := sut.LabelDefinition(ctx, "key") 654 // THEN 655 require.EqualError(t, err, "while committing transaction: commit errror") 656 }) 657 } 658 659 func TestUpdateLabelDefinition(t *testing.T) { 660 tnt := "tenant" 661 externalTnt := "external-tenant" 662 desiredSchema := getScenarioSchemaWithFormations([]string{testScenario, "additional-1"}) 663 var desiredSchemaInt interface{} = desiredSchema 664 initialSchema := getScenarioSchemaWithFormations([]string{testScenario, "initial-1"}) 665 var initialSchemaInt interface{} = initialSchema 666 667 gqlLabelDefinitionInput := graphql.LabelDefinitionInput{ 668 Key: model.ScenariosKey, 669 Schema: getJSONSchemaFromSchema(t, &desiredSchemaInt), 670 } 671 gqlLabelDefinition := model.LabelDefinition{ 672 ID: fixUUID(), 673 Tenant: tnt, 674 Key: model.ScenariosKey, 675 Schema: &desiredSchemaInt, 676 } 677 modelLabelDefinition := model.LabelDefinition{ 678 ID: fixUUID(), 679 Tenant: tnt, 680 Key: model.ScenariosKey, 681 Schema: &initialSchemaInt, 682 } 683 updatedGQLLabelDefinition := graphql.LabelDefinition{ 684 Key: model.ScenariosKey, 685 Schema: getJSONSchemaFromSchema(t, &desiredSchemaInt), 686 } 687 testErr := errors.New("test error") 688 txGen := txtest.NewTransactionContextGenerator(testErr) 689 690 t.Run("successfully updated Label Definition", func(t *testing.T) { 691 // GIVEN 692 mockPersistanceCtx := &pautomock.PersistenceTx{} 693 defer mockPersistanceCtx.AssertExpectations(t) 694 mockPersistanceCtx.On("Commit").Return(nil) 695 696 mockTransactioner := &pautomock.Transactioner{} 697 mockTransactioner.On("Begin").Return(mockPersistanceCtx, nil) 698 mockTransactioner.On("RollbackUnlessCommitted", mock.Anything, mock.Anything).Return(false) 699 defer mockTransactioner.AssertExpectations(t) 700 701 mockConverter := &automock.ModelConverter{} 702 defer mockConverter.AssertExpectations(t) 703 mockConverter.On("FromGraphQL", gqlLabelDefinitionInput, tnt).Return(gqlLabelDefinition, nil) 704 mockConverter.On("ToGraphQL", gqlLabelDefinition).Return(updatedGQLLabelDefinition, nil) 705 706 mockFormationsService := &automock.FormationService{} 707 defer mockFormationsService.AssertExpectations(t) 708 mockFormationsService.On("CreateFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: "additional-1"}, model.DefaultTemplateName).Return(nil, nil) 709 mockFormationsService.On("DeleteFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: "initial-1"}).Return(nil, nil) 710 711 mockService := &automock.Service{} 712 defer mockService.AssertExpectations(t) 713 mockService.On("Get", contextThatHasTenant(tnt), tnt, modelLabelDefinition.Key).Return(&modelLabelDefinition, nil).Once() 714 mockService.On("Get", contextThatHasTenant(tnt), tnt, modelLabelDefinition.Key).Return(&gqlLabelDefinition, nil).Once() 715 716 ctx := persistence.SaveToContext(context.TODO(), nil) 717 ctx = tenant.SaveToContext(ctx, tnt, externalTnt) 718 sut := labeldef.NewResolver(mockTransactioner, mockService, mockFormationsService, mockConverter) 719 // WHEN 720 actual, err := sut.UpdateLabelDefinition(ctx, gqlLabelDefinitionInput) 721 // THEN 722 require.NoError(t, err) 723 assert.Equal(t, model.ScenariosKey, actual.Key) 724 }) 725 726 t.Run("got error when convert to graphql failed", func(t *testing.T) { 727 // GIVEN 728 persist, transact := txGen.ThatDoesntExpectCommit() 729 730 mockConverter := &automock.ModelConverter{} 731 defer mockConverter.AssertExpectations(t) 732 mockConverter.On("FromGraphQL", gqlLabelDefinitionInput, tnt).Return(gqlLabelDefinition, nil) 733 mockConverter.On("ToGraphQL", gqlLabelDefinition).Return(graphql.LabelDefinition{}, testErr) 734 735 mockFormationsService := &automock.FormationService{} 736 defer mockFormationsService.AssertExpectations(t) 737 mockFormationsService.On("CreateFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: "additional-1"}, model.DefaultTemplateName).Return(nil, nil) 738 mockFormationsService.On("DeleteFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: "initial-1"}).Return(nil, nil) 739 740 mockService := &automock.Service{} 741 defer mockService.AssertExpectations(t) 742 mockService.On("Get", contextThatHasTenant(tnt), tnt, modelLabelDefinition.Key).Return(&modelLabelDefinition, nil).Once() 743 mockService.On("Get", contextThatHasTenant(tnt), tnt, modelLabelDefinition.Key).Return(&gqlLabelDefinition, nil).Once() 744 745 ctx := persistence.SaveToContext(context.TODO(), nil) 746 ctx = tenant.SaveToContext(ctx, tnt, externalTnt) 747 sut := labeldef.NewResolver(transact, mockService, mockFormationsService, mockConverter) 748 // WHEN 749 _, err := sut.UpdateLabelDefinition(ctx, gqlLabelDefinitionInput) 750 // THEN 751 require.Error(t, err) 752 require.EqualError(t, err, testErr.Error()) 753 transact.AssertExpectations(t) 754 persist.AssertExpectations(t) 755 }) 756 757 t.Run("missing tenant in context", func(t *testing.T) { 758 // GIVEN 759 sut := labeldef.NewResolver(nil, nil, nil, nil) 760 // WHEN 761 _, err := sut.UpdateLabelDefinition(context.TODO(), graphql.LabelDefinitionInput{}) 762 // THEN 763 require.EqualError(t, err, "cannot read tenant from context") 764 }) 765 766 t.Run("got error on starting transaction", func(t *testing.T) { 767 // GIVEN 768 mockTransactioner := &pautomock.Transactioner{} 769 mockTransactioner.On("Begin").Return(nil, errors.New("some error")) 770 defer mockTransactioner.AssertExpectations(t) 771 772 mockConverter := &automock.ModelConverter{} 773 defer mockConverter.AssertExpectations(t) 774 775 ctx := persistence.SaveToContext(context.TODO(), nil) 776 ctx = tenant.SaveToContext(ctx, tnt, externalTnt) 777 sut := labeldef.NewResolver(mockTransactioner, nil, nil, mockConverter) 778 // WHEN 779 _, err := sut.UpdateLabelDefinition(ctx, gqlLabelDefinitionInput) 780 // THEN 781 require.EqualError(t, err, "while starting transaction: some error") 782 }) 783 784 t.Run("got error when convert to model failed", func(t *testing.T) { 785 // GIVEN 786 persist, transact := txGen.ThatDoesntExpectCommit() 787 788 mockConverter := &automock.ModelConverter{} 789 defer mockConverter.AssertExpectations(t) 790 mockConverter.On("FromGraphQL", gqlLabelDefinitionInput, tnt).Return(model.LabelDefinition{}, testErr) 791 792 ctx := persistence.SaveToContext(context.TODO(), nil) 793 ctx = tenant.SaveToContext(ctx, tnt, externalTnt) 794 sut := labeldef.NewResolver(transact, nil, nil, mockConverter) 795 // WHEN 796 _, err := sut.UpdateLabelDefinition(ctx, gqlLabelDefinitionInput) 797 // THEN 798 require.Error(t, err) 799 require.EqualError(t, err, testErr.Error()) 800 transact.AssertExpectations(t) 801 persist.AssertExpectations(t) 802 }) 803 804 t.Run("got error on creating formation", func(t *testing.T) { 805 // GIVEN 806 mockPersistanceCtx := &pautomock.PersistenceTx{} 807 defer mockPersistanceCtx.AssertExpectations(t) 808 809 mockTransactioner := &pautomock.Transactioner{} 810 mockTransactioner.On("Begin").Return(mockPersistanceCtx, nil) 811 mockTransactioner.On("RollbackUnlessCommitted", mock.Anything, mock.Anything).Return(false) 812 defer mockTransactioner.AssertExpectations(t) 813 814 mockConverter := &automock.ModelConverter{} 815 defer mockConverter.AssertExpectations(t) 816 mockConverter.On("FromGraphQL", gqlLabelDefinitionInput, tnt).Return(gqlLabelDefinition, nil) 817 818 mockService := &automock.Service{} 819 defer mockService.AssertExpectations(t) 820 mockService.On("Get", contextThatHasTenant(tnt), tnt, modelLabelDefinition.Key).Return(&modelLabelDefinition, nil).Once() 821 822 mockFormationsService := &automock.FormationService{} 823 defer mockFormationsService.AssertExpectations(t) 824 mockFormationsService.On("CreateFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: "additional-1"}, model.DefaultTemplateName).Return(nil, testErr) 825 826 ctx := persistence.SaveToContext(context.TODO(), nil) 827 ctx = tenant.SaveToContext(ctx, tnt, externalTnt) 828 sut := labeldef.NewResolver(mockTransactioner, mockService, mockFormationsService, mockConverter) 829 defer mockService.AssertExpectations(t) 830 831 // WHEN 832 _, err := sut.UpdateLabelDefinition(ctx, gqlLabelDefinitionInput) 833 // THEN 834 require.EqualError(t, err, fmt.Sprintf("while creating formation with name %s: %s", "additional-1", testErr.Error())) 835 }) 836 t.Run("got error on deleting formation", func(t *testing.T) { 837 // GIVEN 838 mockPersistanceCtx := &pautomock.PersistenceTx{} 839 defer mockPersistanceCtx.AssertExpectations(t) 840 841 mockTransactioner := &pautomock.Transactioner{} 842 mockTransactioner.On("Begin").Return(mockPersistanceCtx, nil) 843 mockTransactioner.On("RollbackUnlessCommitted", mock.Anything, mock.Anything).Return(false) 844 defer mockTransactioner.AssertExpectations(t) 845 846 mockConverter := &automock.ModelConverter{} 847 defer mockConverter.AssertExpectations(t) 848 mockConverter.On("FromGraphQL", gqlLabelDefinitionInput, tnt).Return(gqlLabelDefinition, nil) 849 850 mockService := &automock.Service{} 851 defer mockService.AssertExpectations(t) 852 mockService.On("Get", contextThatHasTenant(tnt), tnt, modelLabelDefinition.Key).Return(&modelLabelDefinition, nil).Once() 853 854 mockFormationsService := &automock.FormationService{} 855 defer mockFormationsService.AssertExpectations(t) 856 mockFormationsService.On("CreateFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: "additional-1"}, model.DefaultTemplateName).Return(nil, nil) 857 mockFormationsService.On("DeleteFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: "initial-1"}).Return(nil, testErr) 858 859 ctx := persistence.SaveToContext(context.TODO(), nil) 860 ctx = tenant.SaveToContext(ctx, tnt, externalTnt) 861 sut := labeldef.NewResolver(mockTransactioner, mockService, mockFormationsService, mockConverter) 862 defer mockService.AssertExpectations(t) 863 864 // WHEN 865 _, err := sut.UpdateLabelDefinition(ctx, gqlLabelDefinitionInput) 866 // THEN 867 require.EqualError(t, err, fmt.Sprintf("while deleting formation with name %s: %s", "initial-1", testErr.Error())) 868 }) 869 870 t.Run("got error on getting Label Definition", func(t *testing.T) { 871 // GIVEN 872 persist, transact := txGen.ThatDoesntExpectCommit() 873 874 mockConverter := &automock.ModelConverter{} 875 defer mockConverter.AssertExpectations(t) 876 mockConverter.On("FromGraphQL", gqlLabelDefinitionInput, tnt).Return(modelLabelDefinition, nil) 877 878 mockService := &automock.Service{} 879 defer mockService.AssertExpectations(t) 880 mockService.On("Get", contextThatHasTenant(tnt), tnt, modelLabelDefinition.Key).Return(nil, testErr) 881 882 ctx := persistence.SaveToContext(context.TODO(), nil) 883 ctx = tenant.SaveToContext(ctx, tnt, externalTnt) 884 sut := labeldef.NewResolver(transact, mockService, nil, mockConverter) 885 // WHEN 886 _, err := sut.UpdateLabelDefinition(ctx, gqlLabelDefinitionInput) 887 // THEN 888 require.Error(t, err) 889 require.EqualError(t, err, "while receiving stored label definition: test error") 890 transact.AssertExpectations(t) 891 persist.AssertExpectations(t) 892 }) 893 894 t.Run("get error on getting updated label definition", func(t *testing.T) { 895 // GIVEN 896 persist, transact := txGen.ThatDoesntExpectCommit() 897 898 mockConverter := &automock.ModelConverter{} 899 defer mockConverter.AssertExpectations(t) 900 mockConverter.On("FromGraphQL", gqlLabelDefinitionInput, tnt).Return(gqlLabelDefinition, nil) 901 902 mockFormationsService := &automock.FormationService{} 903 defer mockFormationsService.AssertExpectations(t) 904 mockFormationsService.On("CreateFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: "additional-1"}, model.DefaultTemplateName).Return(nil, nil) 905 mockFormationsService.On("DeleteFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: "initial-1"}).Return(nil, nil) 906 907 mockService := &automock.Service{} 908 defer mockService.AssertExpectations(t) 909 mockService.On("Get", contextThatHasTenant(tnt), tnt, modelLabelDefinition.Key).Return(&modelLabelDefinition, nil).Once() 910 mockService.On("Get", contextThatHasTenant(tnt), tnt, modelLabelDefinition.Key).Return(nil, testErr).Once() 911 912 ctx := persistence.SaveToContext(context.TODO(), nil) 913 ctx = tenant.SaveToContext(ctx, tnt, externalTnt) 914 sut := labeldef.NewResolver(transact, mockService, mockFormationsService, mockConverter) 915 // WHEN 916 _, err := sut.UpdateLabelDefinition(ctx, gqlLabelDefinitionInput) 917 // THEN 918 require.Error(t, err) 919 require.EqualError(t, err, "while receiving updated label definition: test error") 920 transact.AssertExpectations(t) 921 persist.AssertExpectations(t) 922 }) 923 924 t.Run("got error on committing transaction", func(t *testing.T) { 925 // GIVEN 926 mockPersistanceCtx := &pautomock.PersistenceTx{} 927 defer mockPersistanceCtx.AssertExpectations(t) 928 mockPersistanceCtx.On("Commit").Return(errors.New("error on commit")) 929 930 mockTransactioner := &pautomock.Transactioner{} 931 mockTransactioner.On("Begin").Return(mockPersistanceCtx, nil) 932 mockTransactioner.On("RollbackUnlessCommitted", mock.Anything, mock.Anything).Return(false) 933 defer mockTransactioner.AssertExpectations(t) 934 935 mockConverter := &automock.ModelConverter{} 936 defer mockConverter.AssertExpectations(t) 937 mockConverter.On("FromGraphQL", gqlLabelDefinitionInput, tnt).Return(gqlLabelDefinition, nil) 938 mockConverter.On("ToGraphQL", gqlLabelDefinition).Return(updatedGQLLabelDefinition, nil) 939 940 mockFormationsService := &automock.FormationService{} 941 defer mockFormationsService.AssertExpectations(t) 942 mockFormationsService.On("CreateFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: "additional-1"}, model.DefaultTemplateName).Return(nil, nil) 943 mockFormationsService.On("DeleteFormation", contextThatHasTenant(tnt), tnt, model.Formation{Name: "initial-1"}).Return(nil, nil) 944 945 mockService := &automock.Service{} 946 defer mockService.AssertExpectations(t) 947 mockService.On("Get", contextThatHasTenant(tnt), tnt, modelLabelDefinition.Key).Return(&modelLabelDefinition, nil).Once() 948 mockService.On("Get", contextThatHasTenant(tnt), tnt, modelLabelDefinition.Key).Return(&gqlLabelDefinition, nil).Once() 949 950 ctx := persistence.SaveToContext(context.TODO(), nil) 951 ctx = tenant.SaveToContext(ctx, tnt, externalTnt) 952 sut := labeldef.NewResolver(mockTransactioner, mockService, mockFormationsService, mockConverter) 953 954 // WHEN 955 _, err := sut.UpdateLabelDefinition(ctx, gqlLabelDefinitionInput) 956 // THEN 957 require.EqualError(t, err, "while committing transaction: error on commit") 958 }) 959 } 960 961 func getInvalidMockTransactioner() *pautomock.Transactioner { 962 mockTransactioner := &pautomock.Transactioner{} 963 mockTransactioner.On("Begin").Return(nil, errors.New("some error")) 964 return mockTransactioner 965 } 966 967 func contextThatHasTenant(expectedTenant string) interface{} { 968 return mock.MatchedBy(func(actual context.Context) bool { 969 actualTenant, err := tenant.LoadFromContext(actual) 970 if err != nil { 971 return false 972 } 973 return actualTenant == expectedTenant 974 }) 975 } 976 977 func getJSONSchemaFromSchema(t *testing.T, schema *interface{}) *graphql.JSONSchema { 978 data, err := json.Marshal(schema) 979 require.NoError(t, err) 980 jsonSchema := graphql.JSONSchema(data) 981 return &jsonSchema 982 } 983 984 func getScenarioSchemaWithFormations(formations []string) map[string]interface{} { 985 return map[string]interface{}{ 986 "type": "array", 987 "minItems": 1, 988 "uniqueItems": true, 989 "items": map[string]interface{}{ 990 "type": "string", 991 "pattern": "^[A-Za-z0-9]([-_A-Za-z0-9\\s]*[A-Za-z0-9])$", 992 "enum": formations, 993 "maxLength": 128, 994 }, 995 } 996 }