github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/nsadapter/handler/exposed_systems_handler_test.go (about) 1 package handler_test 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "io" 8 "net/http" 9 "net/http/httptest" 10 "strings" 11 "testing" 12 13 "github.com/stretchr/testify/require" 14 15 "github.com/kyma-incubator/compass/components/director/internal/labelfilter" 16 "github.com/kyma-incubator/compass/components/director/internal/model" 17 "github.com/kyma-incubator/compass/components/director/internal/nsadapter/handler/automock" 18 txautomock "github.com/kyma-incubator/compass/components/director/pkg/persistence/automock" 19 "github.com/kyma-incubator/compass/components/director/pkg/str" 20 "github.com/stretchr/testify/mock" 21 22 "github.com/kyma-incubator/compass/components/director/internal/nsadapter/handler" 23 "github.com/kyma-incubator/compass/components/director/internal/nsadapter/httputil" 24 "github.com/kyma-incubator/compass/components/director/internal/nsadapter/nsmodel" 25 "github.com/kyma-incubator/compass/components/director/pkg/httputils" 26 ) 27 28 const ( 29 testSubaccount = "fd4f2041-fa83-48e0-b292-ff515bb776f0" 30 deltaReportType = "delta" 31 fullReportType = "full" 32 ) 33 34 func TestHandler_ServeHTTP(t *testing.T) { 35 appWithLabel := model.ApplicationWithLabel{ 36 App: &model.Application{ 37 BaseEntity: &model.BaseEntity{ID: "id"}, 38 }, 39 SccLabel: &model.Label{ 40 Value: map[string]interface{}{"LocationID": "loc-id", "Host": "127.0.0.1:8080"}, 41 }, 42 } 43 44 appWithLabel2 := model.ApplicationWithLabel{ 45 App: &model.Application{ 46 BaseEntity: &model.BaseEntity{ID: "id"}, 47 }, 48 SccLabel: &model.Label{ 49 Value: map[string]interface{}{"LocationID": "loc-id-2", "Host": "127.0.0.1:8080"}, 50 }, 51 } 52 53 application := model.Application{ 54 BaseEntity: &model.BaseEntity{ 55 ID: "id", 56 }, 57 } 58 system := nsmodel.System{ 59 SystemBase: nsmodel.SystemBase{ 60 Protocol: "HTTP", 61 Host: "127.0.0.1:8080", 62 SystemType: "otherSAPsys", 63 Description: "description", 64 Status: "disabled", 65 SystemNumber: "number", 66 }, 67 TemplateID: "", 68 } 69 label := &model.LabelInput{ 70 Key: "systemType", 71 Value: system.SystemType, 72 ObjectID: application.ID, 73 ObjectType: model.ApplicationLabelableObject, 74 } 75 76 labelFilter := labelfilter.NewForKeyWithQuery("scc", fmt.Sprintf("{\"LocationID\":\"%s\", \"Subaccount\":\"%s\"}", "loc-id", testSubaccount)) 77 labelFilter2 := labelfilter.NewForKeyWithQuery("scc", fmt.Sprintf("{\"LocationID\":\"%s\", \"Subaccount\":\"%s\"}", "loc-id-2", testSubaccount)) 78 79 protocolLabel := &model.LabelInput{ 80 Key: "systemProtocol", 81 Value: system.Protocol, 82 ObjectID: application.ID, 83 ObjectType: model.ApplicationLabelableObject, 84 } 85 86 body := "{" + 87 "\"type\": \"notification-service\"," + 88 "\"value\": [{" + 89 " \"subaccount\": \"fd4f2041-fa83-48e0-b292-ff515bb776f0\"," + 90 " \"locationId\": \"loc-id\"," + 91 " \"exposedSystems\": [{" + 92 " \"protocol\": \"HTTP\"," + 93 " \"host\": \"127.0.0.1:8080\"," + 94 " \"type\": \"otherSAPsys\"," + 95 " \"status\": \"disabled\"," + 96 " \"description\": \"description\"" + 97 " }]\n " + 98 "}]}" 99 bodyWithSystemNumber := "{" + 100 "\"type\": \"notification-service\"," + 101 "\"value\": [{" + 102 " \"subaccount\": \"fd4f2041-fa83-48e0-b292-ff515bb776f0\"," + 103 " \"locationId\": \"loc-id\"," + 104 " \"exposedSystems\": [{" + 105 " \"protocol\": \"HTTP\"," + 106 " \"host\": \"127.0.0.1:8080\"," + 107 " \"type\": \"otherSAPsys\"," + 108 " \"status\": \"disabled\"," + 109 " \"description\": \"description\"," + 110 " \"systemNumber\": \"number\"" + 111 " }]" + 112 "}]}" 113 bodyWithoutExposedSystems := "{" + 114 "\"type\": \"notification-service\"," + 115 "\"value\": [{" + 116 " \"subaccount\": \"fd4f2041-fa83-48e0-b292-ff515bb776f0\"," + 117 " \"locationId\": \"loc-id\"," + 118 " \"exposedSystems\": []" + 119 "}]}" 120 121 t.Run("failed to parse request body", func(t *testing.T) { 122 endpoint := handler.NewHandler(nil, nil, nil, nil, nil) 123 124 req := createReportSystemsRequest(nil, deltaReportType) 125 rec := httptest.NewRecorder() 126 127 endpoint.ServeHTTP(rec, req) 128 129 resp := rec.Result() 130 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 131 Error: httputil.Error{ 132 Code: http.StatusBadRequest, 133 Message: "failed to parse request body", 134 }, 135 }) 136 require.NoError(t, err) 137 Verify(t, resp, http.StatusBadRequest, httputils.ContentTypeApplicationJSON, string(expectedBody)) 138 }) 139 140 t.Run("failed due to missing report type", func(t *testing.T) { 141 endpoint := handler.NewHandler(nil, nil, nil, nil, nil) 142 143 req := httptest.NewRequest(http.MethodPut, "/v1", nil) 144 rec := httptest.NewRecorder() 145 146 endpoint.ServeHTTP(rec, req) 147 148 resp := rec.Result() 149 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 150 Error: httputil.Error{ 151 Code: http.StatusBadRequest, 152 Message: "the query parameter 'reportType' is missing or invalid", 153 }, 154 }) 155 require.NoError(t, err) 156 Verify(t, resp, http.StatusBadRequest, httputils.ContentTypeApplicationJSON, string(expectedBody)) 157 }) 158 159 t.Run("failed due to unknown report type", func(t *testing.T) { 160 endpoint := handler.NewHandler(nil, nil, nil, nil, nil) 161 162 req := createReportSystemsRequest(nil, "unknown") 163 rec := httptest.NewRecorder() 164 165 endpoint.ServeHTTP(rec, req) 166 167 resp := rec.Result() 168 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 169 Error: httputil.Error{ 170 Code: http.StatusBadRequest, 171 Message: "the query parameter 'reportType' is missing or invalid", 172 }, 173 }) 174 require.NoError(t, err) 175 Verify(t, resp, http.StatusBadRequest, httputils.ContentTypeApplicationJSON, string(expectedBody)) 176 }) 177 178 t.Run("failed while validating request body", func(t *testing.T) { 179 bodyWithoutSubaccount := "{\n \"type\": \"notification-service\",\n \"value\": [\n {\n \"locationId\": \"loc-id\",\n \"exposedSystems\": [\n {\n \"protocol\": \"HTTP\",\n \"host\": \"127.0.0.1:8080\",\n \"type\": \"otherSAPsys\",\n \"status\": \"disabled\",\n \"description\": \"des\"\n }\n ]\n }\n ]\n}" 180 181 endpoint := handler.NewHandler(nil, nil, nil, nil, nil) 182 183 req := createReportSystemsRequest(strings.NewReader(bodyWithoutSubaccount), deltaReportType) 184 rec := httptest.NewRecorder() 185 186 endpoint.ServeHTTP(rec, req) 187 188 resp := rec.Result() 189 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 190 Error: httputil.Error{ 191 Code: http.StatusBadRequest, 192 Message: "value: (subaccount: cannot be blank.).", 193 }, 194 }) 195 require.NoError(t, err) 196 Verify(t, resp, http.StatusBadRequest, httputils.ContentTypeApplicationJSON, string(expectedBody)) 197 }) 198 199 t.Run("failed while opening transaction", func(t *testing.T) { 200 transact := txautomock.Transactioner{} 201 transact.Mock.On("Begin").Return(nil, errors.New("test")) 202 defer transact.AssertExpectations(t) 203 204 endpoint := handler.NewHandler(nil, nil, nil, nil, &transact) 205 206 req := createReportSystemsRequest(strings.NewReader(body), deltaReportType) 207 rec := httptest.NewRecorder() 208 209 endpoint.ServeHTTP(rec, req) 210 211 resp := rec.Result() 212 213 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 214 Error: httputil.Error{ 215 Code: http.StatusInternalServerError, 216 Message: "Update failed", 217 }, 218 }) 219 require.NoError(t, err) 220 Verify(t, resp, http.StatusInternalServerError, httputils.ContentTypeApplicationJSON, string(expectedBody)) 221 }) 222 223 t.Run("failed while listing tenants", func(t *testing.T) { 224 tx := &txautomock.PersistenceTx{} 225 226 transact := txautomock.Transactioner{} 227 transact.Mock.On("Begin").Return(tx, nil) 228 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true) 229 230 ids := []string{testSubaccount} 231 tntSvc := automock.TenantService{} 232 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return(nil, errors.New("test")) 233 defer mock.AssertExpectationsForObjects(t, tx, &transact, &tntSvc) 234 235 endpoint := handler.NewHandler(nil, nil, nil, &tntSvc, &transact) 236 237 req := createReportSystemsRequest(strings.NewReader(body), deltaReportType) 238 rec := httptest.NewRecorder() 239 240 endpoint.ServeHTTP(rec, req) 241 242 resp := rec.Result() 243 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 244 Error: httputil.Error{ 245 Code: http.StatusInternalServerError, 246 Message: "Update failed", 247 }, 248 }) 249 require.NoError(t, err) 250 Verify(t, resp, http.StatusInternalServerError, httputils.ContentTypeApplicationJSON, string(expectedBody)) 251 }) 252 253 t.Run("got error details when provided id is not a subaccount", func(t *testing.T) { 254 tx := &txautomock.PersistenceTx{} 255 tx.Mock.On("Commit").Return(nil) 256 257 transact := txautomock.Transactioner{} 258 transact.Mock.On("Begin").Return(tx, nil) 259 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true) 260 261 ids := []string{testSubaccount} 262 tntSvc := automock.TenantService{} 263 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ExternalTenant: testSubaccount, Type: "customer"}}, nil) 264 defer mock.AssertExpectationsForObjects(t, tx, &transact, &tntSvc) 265 266 endpoint := handler.NewHandler(nil, nil, nil, &tntSvc, &transact) 267 268 req := createReportSystemsRequest(strings.NewReader(body), deltaReportType) 269 rec := httptest.NewRecorder() 270 271 endpoint.ServeHTTP(rec, req) 272 273 resp := rec.Result() 274 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 275 Error: httputil.DetailedError{ 276 Code: http.StatusOK, 277 Message: "Update/create failed for some on-premise systems", 278 Details: []httputil.Detail{ 279 { 280 Message: "Provided id is not subaccount", 281 Subaccount: testSubaccount, 282 LocationID: "loc-id", 283 }, 284 }, 285 }, 286 }) 287 require.NoError(t, err) 288 Verify(t, resp, http.StatusOK, httputils.ContentTypeApplicationJSON, string(expectedBody)) 289 }) 290 291 t.Run("got error details when subaccount is not found", func(t *testing.T) { 292 tx := &txautomock.PersistenceTx{} 293 tx.Mock.On("Commit").Return(nil) 294 295 transact := txautomock.Transactioner{} 296 transact.Mock.On("Begin").Return(tx, nil) 297 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true) 298 299 ids := []string{testSubaccount} 300 tntSvc := automock.TenantService{} 301 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{}, nil) 302 defer mock.AssertExpectationsForObjects(t, tx, &transact, &tntSvc) 303 304 endpoint := handler.NewHandler(nil, nil, nil, &tntSvc, &transact) 305 306 req := createReportSystemsRequest(strings.NewReader(body), deltaReportType) 307 rec := httptest.NewRecorder() 308 309 endpoint.ServeHTTP(rec, req) 310 311 resp := rec.Result() 312 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 313 Error: httputil.DetailedError{ 314 Code: http.StatusOK, 315 Message: "Update/create failed for some on-premise systems", 316 Details: []httputil.Detail{ 317 { 318 Message: "Subaccount not found", 319 Subaccount: testSubaccount, 320 LocationID: "loc-id", 321 }, 322 }, 323 }, 324 }) 325 require.NoError(t, err) 326 Verify(t, resp, http.StatusOK, httputils.ContentTypeApplicationJSON, string(expectedBody)) 327 }) 328 329 //Delta report tests 330 t.Run("got error while upserting application", func(t *testing.T) { 331 tx := &txautomock.PersistenceTx{} 332 tx.Mock.On("Commit").Return(nil) 333 334 listSccsTx := &txautomock.PersistenceTx{} 335 listSccsTx.Mock.On("Commit").Return(nil) 336 337 transact := txautomock.Transactioner{} 338 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 339 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsert 340 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 341 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 342 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 343 344 ids := []string{testSubaccount} 345 tntSvc := automock.TenantService{} 346 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 347 348 setMappings() 349 defer clearMappings() 350 351 appInputJSON := "app-input-json" 352 applicationTemplate := &model.ApplicationTemplate{} 353 354 appTemplateSvc := automock.ApplicationTemplateService{} 355 appTemplateSvc.Mock.On("Get", mock.Anything, "ss").Return(applicationTemplate, nil) 356 appTemplateSvc.Mock.On("PrepareApplicationCreateInputJSON", applicationTemplate, mock.Anything).Return(appInputJSON, nil) 357 358 input := model.ApplicationRegisterInput{} 359 appConverterSvc := automock.ApplicationConverter{} 360 appConverterSvc.Mock.On("CreateInputJSONToModel", mock.Anything, appInputJSON).Return(input, nil) 361 362 appSvc := automock.ApplicationService{} 363 appSvc.Mock.On("Upsert", mock.Anything, input).Return(errors.New("error")) 364 365 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 366 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appTemplateSvc, &appConverterSvc, &appSvc, &tntSvc) 367 368 endpoint := handler.NewHandler(&appSvc, &appConverterSvc, &appTemplateSvc, &tntSvc, &transact) 369 370 req := createReportSystemsRequest(strings.NewReader(bodyWithSystemNumber), deltaReportType) 371 rec := httptest.NewRecorder() 372 373 endpoint.ServeHTTP(rec, req) 374 375 resp := rec.Result() 376 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 377 Error: httputil.DetailedError{ 378 Code: http.StatusOK, 379 Message: "Update/create failed for some on-premise systems", 380 Details: []httputil.Detail{ 381 { 382 Message: "Creation failed", 383 Subaccount: testSubaccount, 384 LocationID: "loc-id", 385 }, 386 }, 387 }, 388 }) 389 require.NoError(t, err) 390 Verify(t, resp, http.StatusOK, httputils.ContentTypeApplicationJSON, string(expectedBody)) 391 }) 392 393 t.Run("successfully upsert application", func(t *testing.T) { 394 tx := &txautomock.PersistenceTx{} 395 tx.Mock.On("Commit").Return(nil) 396 397 listSccsTx := &txautomock.PersistenceTx{} 398 listSccsTx.Mock.On("Commit").Return(nil) 399 400 transact := txautomock.Transactioner{} 401 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 402 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsert 403 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 404 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 405 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 406 407 ids := []string{testSubaccount} 408 tntSvc := automock.TenantService{} 409 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 410 411 setMappings() 412 defer clearMappings() 413 414 appInputJSON := "app-input-json" 415 applicationTemplate := &model.ApplicationTemplate{} 416 417 appTemplateSvc := automock.ApplicationTemplateService{} 418 appTemplateSvc.Mock.On("Get", mock.Anything, "ss").Return(applicationTemplate, nil) 419 appTemplateSvc.Mock.On("PrepareApplicationCreateInputJSON", applicationTemplate, mock.Anything).Return(appInputJSON, nil) 420 421 input := model.ApplicationRegisterInput{} 422 appConverterSvc := automock.ApplicationConverter{} 423 appConverterSvc.Mock.On("CreateInputJSONToModel", mock.Anything, appInputJSON).Return(input, nil) 424 425 appSvc := automock.ApplicationService{} 426 appSvc.Mock.On("Upsert", mock.Anything, input).Return(nil) 427 428 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 429 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appTemplateSvc, &appConverterSvc, &appSvc, &tntSvc) 430 431 endpoint := handler.NewHandler(&appSvc, &appConverterSvc, &appTemplateSvc, &tntSvc, &transact) 432 433 req := createReportSystemsRequest(strings.NewReader(bodyWithSystemNumber), deltaReportType) 434 rec := httptest.NewRecorder() 435 436 endpoint.ServeHTTP(rec, req) 437 438 resp := rec.Result() 439 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 440 }) 441 442 t.Run("failed to get application by subaccount, location ID and virtual host", func(t *testing.T) { 443 tx := &txautomock.PersistenceTx{} 444 tx.Mock.On("Commit").Return(nil) 445 446 listSccsTx := &txautomock.PersistenceTx{} 447 listSccsTx.Mock.On("Commit").Return(nil) 448 449 transact := txautomock.Transactioner{} 450 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 451 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 452 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 453 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 454 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 455 456 ids := []string{testSubaccount} 457 tntSvc := automock.TenantService{} 458 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 459 460 setMappings() 461 defer clearMappings() 462 463 appSvc := automock.ApplicationService{} 464 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080").Return(nil, errors.New("error")) 465 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 466 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 467 468 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 469 470 req := createReportSystemsRequest(strings.NewReader(body), deltaReportType) 471 rec := httptest.NewRecorder() 472 473 endpoint.ServeHTTP(rec, req) 474 475 resp := rec.Result() 476 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 477 Error: httputil.DetailedError{ 478 Code: http.StatusOK, 479 Message: "Update/create failed for some on-premise systems", 480 Details: []httputil.Detail{ 481 { 482 Message: "Creation failed", 483 Subaccount: testSubaccount, 484 LocationID: "loc-id", 485 }, 486 }, 487 }, 488 }) 489 require.NoError(t, err) 490 Verify(t, resp, http.StatusOK, httputils.ContentTypeApplicationJSON, string(expectedBody)) 491 }) 492 493 t.Run("failed to register application from template", func(t *testing.T) { 494 tx := &txautomock.PersistenceTx{} 495 tx.Mock.On("Commit").Return(nil) 496 497 listSccsTx := &txautomock.PersistenceTx{} 498 listSccsTx.Mock.On("Commit").Return(nil) 499 500 transact := txautomock.Transactioner{} 501 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 502 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 503 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 504 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 505 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 506 507 ids := []string{testSubaccount} 508 tntSvc := automock.TenantService{} 509 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 510 511 setMappings() 512 defer clearMappings() 513 514 appInputJSON := "app-input-json" 515 applicationTemplate := &model.ApplicationTemplate{} 516 517 appTemplateSvc := automock.ApplicationTemplateService{} 518 appTemplateSvc.Mock.On("Get", mock.Anything, "ss").Return(applicationTemplate, nil) 519 appTemplateSvc.Mock.On("PrepareApplicationCreateInputJSON", applicationTemplate, mock.Anything).Return(appInputJSON, nil) 520 521 input := model.ApplicationRegisterInput{} 522 appConverterSvc := automock.ApplicationConverter{} 523 appConverterSvc.Mock.On("CreateInputJSONToModel", mock.Anything, appInputJSON).Return(input, nil) 524 525 appSvc := automock.ApplicationService{} 526 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080"). 527 Return(nil, errors.New("Object not found")) 528 appSvc.Mock.On("CreateFromTemplate", mock.Anything, input, str.Ptr("ss")).Return("", errors.New("error")) 529 530 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 531 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appTemplateSvc, &appConverterSvc, &appSvc, &tntSvc) 532 533 endpoint := handler.NewHandler(&appSvc, &appConverterSvc, &appTemplateSvc, &tntSvc, &transact) 534 535 req := createReportSystemsRequest(strings.NewReader(body), deltaReportType) 536 rec := httptest.NewRecorder() 537 538 endpoint.ServeHTTP(rec, req) 539 540 resp := rec.Result() 541 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 542 Error: httputil.DetailedError{ 543 Code: http.StatusOK, 544 Message: "Update/create failed for some on-premise systems", 545 Details: []httputil.Detail{ 546 { 547 Message: "Creation failed", 548 Subaccount: testSubaccount, 549 LocationID: "loc-id", 550 }, 551 }, 552 }, 553 }) 554 require.NoError(t, err) 555 Verify(t, resp, http.StatusOK, httputils.ContentTypeApplicationJSON, string(expectedBody)) 556 }) 557 558 t.Run("successfully create application", func(t *testing.T) { 559 tx := &txautomock.PersistenceTx{} 560 tx.Mock.On("Commit").Return(nil) 561 562 listSccsTx := &txautomock.PersistenceTx{} 563 listSccsTx.Mock.On("Commit").Return(nil) 564 565 transact := txautomock.Transactioner{} 566 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 567 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 568 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 569 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 570 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 571 572 ids := []string{testSubaccount} 573 tntSvc := automock.TenantService{} 574 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 575 576 setMappings() 577 defer clearMappings() 578 579 appInputJSON := "app-input-json" 580 applicationTemplate := &model.ApplicationTemplate{} 581 582 appTemplateSvc := automock.ApplicationTemplateService{} 583 appTemplateSvc.Mock.On("Get", mock.Anything, "ss").Return(applicationTemplate, nil) 584 appTemplateSvc.Mock.On("PrepareApplicationCreateInputJSON", applicationTemplate, mock.Anything).Return(appInputJSON, nil) 585 586 input := model.ApplicationRegisterInput{} 587 appConverterSvc := automock.ApplicationConverter{} 588 appConverterSvc.Mock.On("CreateInputJSONToModel", mock.Anything, appInputJSON).Return(input, nil) 589 590 appSvc := automock.ApplicationService{} 591 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080"). 592 Return(nil, errors.New("Object not found")) 593 appSvc.Mock.On("CreateFromTemplate", mock.Anything, input, str.Ptr("ss")).Return("success", nil) 594 595 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 596 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appTemplateSvc, &appConverterSvc, &appSvc, &tntSvc) 597 598 endpoint := handler.NewHandler(&appSvc, &appConverterSvc, &appTemplateSvc, &tntSvc, &transact) 599 600 req := createReportSystemsRequest(strings.NewReader(body), deltaReportType) 601 rec := httptest.NewRecorder() 602 603 endpoint.ServeHTTP(rec, req) 604 605 resp := rec.Result() 606 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 607 }) 608 609 t.Run("failed to update application", func(t *testing.T) { 610 setMappings() 611 defer clearMappings() 612 613 tx := &txautomock.PersistenceTx{} 614 tx.Mock.On("Commit").Return(nil) 615 616 listSccsTx := &txautomock.PersistenceTx{} 617 listSccsTx.Mock.On("Commit").Return(nil) 618 619 transact := txautomock.Transactioner{} 620 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 621 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 622 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 623 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 624 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 625 626 ids := []string{testSubaccount} 627 tntSvc := automock.TenantService{} 628 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 629 630 input := nsmodel.ToAppUpdateInput(nsmodel.System{ 631 SystemBase: nsmodel.SystemBase{ 632 Protocol: "HTTP", 633 Host: "127.0.0.1:8080", 634 SystemType: "otherSAPsys", 635 Description: "description", 636 Status: "disabled", 637 SystemNumber: "number", 638 }, 639 TemplateID: "", 640 }) 641 642 appSvc := automock.ApplicationService{} 643 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080").Return(&application, nil) 644 appSvc.Mock.On("Update", mock.Anything, application.ID, input).Return(errors.New("error")) 645 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 646 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 647 648 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 649 650 req := createReportSystemsRequest(strings.NewReader(body), deltaReportType) 651 rec := httptest.NewRecorder() 652 653 endpoint.ServeHTTP(rec, req) 654 655 resp := rec.Result() 656 657 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 658 Error: httputil.DetailedError{ 659 Code: http.StatusOK, 660 Message: "Update/create failed for some on-premise systems", 661 Details: []httputil.Detail{ 662 { 663 Message: "Creation failed", 664 Subaccount: testSubaccount, 665 LocationID: "loc-id", 666 }, 667 }, 668 }, 669 }) 670 require.NoError(t, err) 671 Verify(t, resp, http.StatusOK, httputils.ContentTypeApplicationJSON, string(expectedBody)) 672 }) 673 674 t.Run("failed to set label systemType", func(t *testing.T) { 675 setMappings() 676 defer clearMappings() 677 678 tx := &txautomock.PersistenceTx{} 679 tx.Mock.On("Commit").Return(nil) 680 681 listSccsTx := &txautomock.PersistenceTx{} 682 listSccsTx.Mock.On("Commit").Return(nil) 683 684 transact := txautomock.Transactioner{} 685 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 686 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 687 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 688 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 689 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 690 691 ids := []string{testSubaccount} 692 tntSvc := automock.TenantService{} 693 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 694 695 input := nsmodel.ToAppUpdateInput(system) 696 697 appSvc := automock.ApplicationService{} 698 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080").Return(&application, nil) 699 appSvc.Mock.On("Update", mock.Anything, application.ID, input).Return(nil) 700 appSvc.Mock.On("SetLabel", mock.Anything, label).Return(errors.New("error")) 701 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 702 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 703 704 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 705 706 req := createReportSystemsRequest(strings.NewReader(body), deltaReportType) 707 rec := httptest.NewRecorder() 708 709 endpoint.ServeHTTP(rec, req) 710 711 resp := rec.Result() 712 713 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 714 Error: httputil.DetailedError{ 715 Code: http.StatusOK, 716 Message: "Update/create failed for some on-premise systems", 717 Details: []httputil.Detail{ 718 { 719 Message: "Creation failed", 720 Subaccount: testSubaccount, 721 LocationID: "loc-id", 722 }, 723 }, 724 }, 725 }) 726 require.NoError(t, err) 727 Verify(t, resp, http.StatusOK, httputils.ContentTypeApplicationJSON, string(expectedBody)) 728 }) 729 730 t.Run("failed to set label systemProtocol", func(t *testing.T) { 731 setMappings() 732 defer clearMappings() 733 734 tx := &txautomock.PersistenceTx{} 735 tx.Mock.On("Commit").Return(nil) 736 737 listSccsTx := &txautomock.PersistenceTx{} 738 listSccsTx.Mock.On("Commit").Return(nil) 739 740 transact := txautomock.Transactioner{} 741 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 742 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 743 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 744 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 745 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 746 747 ids := []string{testSubaccount} 748 tntSvc := automock.TenantService{} 749 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 750 751 input := nsmodel.ToAppUpdateInput(system) 752 protocolLabel := &model.LabelInput{ 753 Key: "systemProtocol", 754 Value: system.Protocol, 755 ObjectID: application.ID, 756 ObjectType: model.ApplicationLabelableObject, 757 } 758 759 appSvc := automock.ApplicationService{} 760 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080").Return(&application, nil) 761 appSvc.Mock.On("Update", mock.Anything, application.ID, input).Return(nil) 762 appSvc.Mock.On("SetLabel", mock.Anything, label).Return(nil).Once() 763 appSvc.Mock.On("SetLabel", mock.Anything, protocolLabel).Return(errors.New("error")).Once() 764 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 765 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 766 767 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 768 769 req := createReportSystemsRequest(strings.NewReader(body), deltaReportType) 770 rec := httptest.NewRecorder() 771 772 endpoint.ServeHTTP(rec, req) 773 774 resp := rec.Result() 775 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 776 Error: httputil.DetailedError{ 777 Code: http.StatusOK, 778 Message: "Update/create failed for some on-premise systems", 779 Details: []httputil.Detail{ 780 { 781 Message: "Creation failed", 782 Subaccount: testSubaccount, 783 LocationID: "loc-id", 784 }, 785 }, 786 }, 787 }) 788 require.NoError(t, err) 789 Verify(t, resp, http.StatusOK, httputils.ContentTypeApplicationJSON, string(expectedBody)) 790 }) 791 792 t.Run("successfully update system", func(t *testing.T) { 793 setMappings() 794 defer clearMappings() 795 796 tx := &txautomock.PersistenceTx{} 797 tx.Mock.On("Commit").Return(nil) 798 799 listSccsTx := &txautomock.PersistenceTx{} 800 listSccsTx.Mock.On("Commit").Return(nil) 801 802 transact := txautomock.Transactioner{} 803 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 804 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 805 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 806 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 807 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 808 809 ids := []string{testSubaccount} 810 tntSvc := automock.TenantService{} 811 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 812 813 input := nsmodel.ToAppUpdateInput(system) 814 protocolLabel := &model.LabelInput{ 815 Key: "systemProtocol", 816 Value: system.Protocol, 817 ObjectID: application.ID, 818 ObjectType: model.ApplicationLabelableObject, 819 } 820 821 appSvc := automock.ApplicationService{} 822 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080").Return(&application, nil) 823 appSvc.Mock.On("Update", mock.Anything, application.ID, input).Return(nil) 824 appSvc.Mock.On("SetLabel", mock.Anything, label).Return(nil).Once() 825 appSvc.Mock.On("SetLabel", mock.Anything, protocolLabel).Return(nil).Once() 826 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 827 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 828 829 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 830 831 req := createReportSystemsRequest(strings.NewReader(body), deltaReportType) 832 rec := httptest.NewRecorder() 833 834 endpoint.ServeHTTP(rec, req) 835 836 resp := rec.Result() 837 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 838 }) 839 840 t.Run("failed to list by SCC", func(t *testing.T) { 841 tx := &txautomock.PersistenceTx{} 842 tx.Mock.On("Commit").Return(nil) 843 844 listSccsTx := &txautomock.PersistenceTx{} 845 846 transact := txautomock.Transactioner{} 847 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 848 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 849 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Once() 850 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 851 852 ids := []string{testSubaccount} 853 tntSvc := automock.TenantService{} 854 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 855 856 appSvc := automock.ApplicationService{} 857 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return(nil, errors.New("error")) 858 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 859 860 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 861 862 req := createReportSystemsRequest(strings.NewReader(bodyWithoutExposedSystems), deltaReportType) 863 rec := httptest.NewRecorder() 864 865 endpoint.ServeHTTP(rec, req) 866 867 resp := rec.Result() 868 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 869 Error: httputil.DetailedError{ 870 Code: http.StatusOK, 871 Message: "Update/create failed for some on-premise systems", 872 Details: []httputil.Detail{ 873 { 874 Message: "Creation failed", 875 Subaccount: testSubaccount, 876 LocationID: "loc-id", 877 }, 878 }, 879 }, 880 }) 881 require.NoError(t, err) 882 Verify(t, resp, http.StatusOK, httputils.ContentTypeApplicationJSON, string(expectedBody)) 883 }) 884 885 t.Run("fail to mark system as unreachable", func(t *testing.T) { 886 tx := &txautomock.PersistenceTx{} 887 tx.Mock.On("Commit").Return(nil) 888 889 listSccsTx := &txautomock.PersistenceTx{} 890 listSccsTx.Mock.On("Commit").Return(nil) 891 892 transact := txautomock.Transactioner{} 893 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 894 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list by scc 895 transact.Mock.On("Begin").Return(tx, nil).Once() // used for mark as unreachable 896 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 897 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 898 899 ids := []string{testSubaccount} 900 tntSvc := automock.TenantService{} 901 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 902 903 unreachableInput := model.ApplicationUpdateInput{SystemStatus: str.Ptr("unreachable")} 904 905 appSvc := automock.ApplicationService{} 906 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 907 appSvc.Mock.On("Update", mock.Anything, appWithLabel.App.ID, unreachableInput).Return(errors.New("error")) 908 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 909 910 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 911 912 req := createReportSystemsRequest(strings.NewReader(bodyWithoutExposedSystems), deltaReportType) 913 rec := httptest.NewRecorder() 914 915 endpoint.ServeHTTP(rec, req) 916 917 resp := rec.Result() 918 expectedBody, err := json.Marshal(httputil.ErrorResponse{ 919 Error: httputil.DetailedError{ 920 Code: http.StatusOK, 921 Message: "Update/create failed for some on-premise systems", 922 Details: []httputil.Detail{ 923 { 924 Message: "Creation failed", 925 Subaccount: testSubaccount, 926 LocationID: "loc-id", 927 }, 928 }, 929 }, 930 }) 931 require.NoError(t, err) 932 Verify(t, resp, http.StatusOK, httputils.ContentTypeApplicationJSON, string(expectedBody)) 933 }) 934 935 t.Run("successfully mark system as unreachable", func(t *testing.T) { 936 tx := &txautomock.PersistenceTx{} 937 tx.Mock.On("Commit").Return(nil) 938 939 listSccsTx := &txautomock.PersistenceTx{} 940 listSccsTx.Mock.On("Commit").Return(nil) 941 942 transact := txautomock.Transactioner{} 943 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 944 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list by scc 945 transact.Mock.On("Begin").Return(tx, nil).Once() // used for mark as unreachable 946 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 947 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 948 949 ids := []string{testSubaccount} 950 tntSvc := automock.TenantService{} 951 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 952 953 unreachableInput := model.ApplicationUpdateInput{SystemStatus: str.Ptr("unreachable")} 954 955 appSvc := automock.ApplicationService{} 956 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 957 appSvc.Mock.On("Update", mock.Anything, appWithLabel.App.ID, unreachableInput).Return(nil) 958 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 959 960 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 961 962 req := createReportSystemsRequest(strings.NewReader(bodyWithoutExposedSystems), deltaReportType) 963 rec := httptest.NewRecorder() 964 965 endpoint.ServeHTTP(rec, req) 966 967 resp := rec.Result() 968 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 969 }) 970 971 t.Run("successful successfully mark system as unreachable with two sccs connected to one subaccount", func(t *testing.T) { 972 body := strings.NewReader("{\n \"type\": \"notification-service\",\n \"value\": [\n {\n \"subaccount\": \"fd4f2041-fa83-48e0-b292-ff515bb776f0\",\n \"locationId\": \"loc-id\",\n \"exposedSystems\": []\n },{\n \"subaccount\": \"fd4f2041-fa83-48e0-b292-ff515bb776f0\",\n \"locationId\": \"loc-id-2\",\n \"exposedSystems\": []\n }\n ]\n}") 973 974 tx := &txautomock.PersistenceTx{} 975 tx.Mock.On("Commit").Return(nil) 976 977 listSccsTx := &txautomock.PersistenceTx{} 978 listSccsTx.Mock.On("Commit").Return(nil) 979 980 transact := txautomock.Transactioner{} 981 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 982 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list by scc 983 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list by scc 984 transact.Mock.On("Begin").Return(tx, nil).Once() // used for mark as unreachable 985 transact.Mock.On("Begin").Return(tx, nil).Once() // used for mark as unreachable 986 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Times(3) 987 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 988 989 ids := []string{testSubaccount, testSubaccount} 990 tntSvc := automock.TenantService{} 991 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 992 993 unreachableInput := model.ApplicationUpdateInput{SystemStatus: str.Ptr("unreachable")} 994 995 appSvc := automock.ApplicationService{} 996 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 997 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter2).Return([]*model.ApplicationWithLabel{&appWithLabel2}, nil) 998 appSvc.Mock.On("Update", mock.Anything, appWithLabel.App.ID, unreachableInput).Return(nil) 999 appSvc.Mock.On("Update", mock.Anything, appWithLabel2.App.ID, unreachableInput).Return(nil) 1000 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 1001 1002 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 1003 1004 req := createReportSystemsRequest(body, deltaReportType) 1005 rec := httptest.NewRecorder() 1006 1007 endpoint.ServeHTTP(rec, req) 1008 1009 resp := rec.Result() 1010 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1011 }) 1012 1013 t.Run("success when report type is delta and value is empty", func(t *testing.T) { 1014 body := strings.NewReader("{\n \"type\": \"notification-service\",\n \"value\": []\n}") 1015 1016 endpoint := handler.NewHandler(nil, nil, nil, nil, nil) 1017 1018 req := createReportSystemsRequest(body, deltaReportType) 1019 rec := httptest.NewRecorder() 1020 1021 endpoint.ServeHTTP(rec, req) 1022 1023 resp := rec.Result() 1024 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1025 }) 1026 1027 //Full report tests 1028 t.Run("got error while upserting application", func(t *testing.T) { 1029 tx := &txautomock.PersistenceTx{} 1030 tx.Mock.On("Commit").Return(nil) 1031 1032 listSccsTx := &txautomock.PersistenceTx{} 1033 listSccsTx.Mock.On("Commit").Return(nil) 1034 1035 transact := txautomock.Transactioner{} 1036 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1037 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsert 1038 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 1039 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 1040 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1041 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1042 1043 ids := []string{testSubaccount} 1044 tntSvc := automock.TenantService{} 1045 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1046 1047 setMappings() 1048 defer clearMappings() 1049 1050 appInputJSON := "app-input-json" 1051 applicationTemplate := &model.ApplicationTemplate{} 1052 1053 appTemplateSvc := automock.ApplicationTemplateService{} 1054 appTemplateSvc.Mock.On("Get", mock.Anything, "ss").Return(applicationTemplate, nil) 1055 appTemplateSvc.Mock.On("PrepareApplicationCreateInputJSON", applicationTemplate, mock.Anything).Return(appInputJSON, nil) 1056 1057 input := model.ApplicationRegisterInput{} 1058 appConverterSvc := automock.ApplicationConverter{} 1059 appConverterSvc.Mock.On("CreateInputJSONToModel", mock.Anything, appInputJSON).Return(input, nil) 1060 1061 appSvc := automock.ApplicationService{} 1062 appSvc.Mock.On("Upsert", mock.Anything, input).Return(errors.New("error")) 1063 1064 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 1065 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1066 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appTemplateSvc, &appConverterSvc, &appSvc, &tntSvc) 1067 1068 endpoint := handler.NewHandler(&appSvc, &appConverterSvc, &appTemplateSvc, &tntSvc, &transact) 1069 1070 req := createReportSystemsRequest(strings.NewReader(bodyWithSystemNumber), fullReportType) 1071 rec := httptest.NewRecorder() 1072 1073 endpoint.ServeHTTP(rec, req) 1074 1075 resp := rec.Result() 1076 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1077 }) 1078 1079 t.Run("successfully upsert application", func(t *testing.T) { 1080 tx := &txautomock.PersistenceTx{} 1081 tx.Mock.On("Commit").Return(nil) 1082 1083 listSccsTx := &txautomock.PersistenceTx{} 1084 listSccsTx.Mock.On("Commit").Return(nil) 1085 1086 transact := txautomock.Transactioner{} 1087 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1088 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsert 1089 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 1090 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 1091 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1092 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1093 1094 ids := []string{testSubaccount} 1095 tntSvc := automock.TenantService{} 1096 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1097 1098 setMappings() 1099 defer clearMappings() 1100 1101 appInputJSON := "app-input-json" 1102 applicationTemplate := &model.ApplicationTemplate{} 1103 1104 appTemplateSvc := automock.ApplicationTemplateService{} 1105 appTemplateSvc.Mock.On("Get", mock.Anything, "ss").Return(applicationTemplate, nil) 1106 appTemplateSvc.Mock.On("PrepareApplicationCreateInputJSON", applicationTemplate, mock.Anything).Return(appInputJSON, nil) 1107 1108 input := model.ApplicationRegisterInput{} 1109 appConverterSvc := automock.ApplicationConverter{} 1110 appConverterSvc.Mock.On("CreateInputJSONToModel", mock.Anything, appInputJSON).Return(input, nil) 1111 1112 appSvc := automock.ApplicationService{} 1113 appSvc.Mock.On("Upsert", mock.Anything, input).Return(nil) 1114 1115 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 1116 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1117 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appTemplateSvc, &appConverterSvc, &appSvc, &tntSvc) 1118 1119 endpoint := handler.NewHandler(&appSvc, &appConverterSvc, &appTemplateSvc, &tntSvc, &transact) 1120 1121 req := createReportSystemsRequest(strings.NewReader(bodyWithSystemNumber), fullReportType) 1122 rec := httptest.NewRecorder() 1123 1124 endpoint.ServeHTTP(rec, req) 1125 1126 resp := rec.Result() 1127 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1128 }) 1129 1130 t.Run("failed to get application by subaccount, location ID and virtual host", func(t *testing.T) { 1131 tx := &txautomock.PersistenceTx{} 1132 tx.Mock.On("Commit").Return(nil) 1133 1134 listSccsTx := &txautomock.PersistenceTx{} 1135 listSccsTx.Mock.On("Commit").Return(nil) 1136 1137 transact := txautomock.Transactioner{} 1138 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1139 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 1140 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 1141 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 1142 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1143 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1144 1145 ids := []string{testSubaccount} 1146 tntSvc := automock.TenantService{} 1147 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1148 1149 setMappings() 1150 defer clearMappings() 1151 1152 appSvc := automock.ApplicationService{} 1153 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080").Return(nil, errors.New("error")) 1154 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 1155 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1156 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 1157 1158 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 1159 1160 req := createReportSystemsRequest(strings.NewReader(body), fullReportType) 1161 rec := httptest.NewRecorder() 1162 1163 endpoint.ServeHTTP(rec, req) 1164 1165 resp := rec.Result() 1166 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1167 }) 1168 1169 t.Run("failed to register application from template", func(t *testing.T) { 1170 tx := &txautomock.PersistenceTx{} 1171 tx.Mock.On("Commit").Return(nil) 1172 1173 listSccsTx := &txautomock.PersistenceTx{} 1174 listSccsTx.Mock.On("Commit").Return(nil) 1175 1176 transact := txautomock.Transactioner{} 1177 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1178 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 1179 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 1180 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 1181 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1182 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1183 1184 ids := []string{testSubaccount} 1185 tntSvc := automock.TenantService{} 1186 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1187 1188 setMappings() 1189 defer clearMappings() 1190 1191 appInputJSON := "app-input-json" 1192 applicationTemplate := &model.ApplicationTemplate{} 1193 1194 appTemplateSvc := automock.ApplicationTemplateService{} 1195 appTemplateSvc.Mock.On("Get", mock.Anything, "ss").Return(applicationTemplate, nil) 1196 appTemplateSvc.Mock.On("PrepareApplicationCreateInputJSON", applicationTemplate, mock.Anything).Return(appInputJSON, nil) 1197 1198 input := model.ApplicationRegisterInput{} 1199 appConverterSvc := automock.ApplicationConverter{} 1200 appConverterSvc.Mock.On("CreateInputJSONToModel", mock.Anything, appInputJSON).Return(input, nil) 1201 1202 appSvc := automock.ApplicationService{} 1203 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080"). 1204 Return(nil, errors.New("Object not found")) 1205 appSvc.Mock.On("CreateFromTemplate", mock.Anything, input, str.Ptr("ss")).Return("", errors.New("error")) 1206 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 1207 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1208 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appTemplateSvc, &appConverterSvc, &appSvc, &tntSvc) 1209 1210 endpoint := handler.NewHandler(&appSvc, &appConverterSvc, &appTemplateSvc, &tntSvc, &transact) 1211 1212 req := createReportSystemsRequest(strings.NewReader(body), fullReportType) 1213 rec := httptest.NewRecorder() 1214 1215 endpoint.ServeHTTP(rec, req) 1216 1217 resp := rec.Result() 1218 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1219 }) 1220 1221 t.Run("successfully create application", func(t *testing.T) { 1222 tx := &txautomock.PersistenceTx{} 1223 tx.Mock.On("Commit").Return(nil) 1224 1225 listSccsTx := &txautomock.PersistenceTx{} 1226 listSccsTx.Mock.On("Commit").Return(nil) 1227 1228 transact := txautomock.Transactioner{} 1229 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1230 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 1231 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 1232 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 1233 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1234 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1235 1236 ids := []string{testSubaccount} 1237 tntSvc := automock.TenantService{} 1238 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1239 1240 nsmodel.Mappings = append(nsmodel.Mappings, nsmodel.TemplateMapping{ 1241 Name: "", 1242 ID: "ss", 1243 SourceKey: []string{"description"}, 1244 SourceValue: []string{"description"}, 1245 }) 1246 defer clearMappings() 1247 1248 setMappings() 1249 defer clearMappings() 1250 1251 appInputJSON := "app-input-json" 1252 applicationTemplate := &model.ApplicationTemplate{} 1253 1254 appTemplateSvc := automock.ApplicationTemplateService{} 1255 appTemplateSvc.Mock.On("Get", mock.Anything, "ss").Return(applicationTemplate, nil) 1256 appTemplateSvc.Mock.On("PrepareApplicationCreateInputJSON", applicationTemplate, mock.Anything).Return(appInputJSON, nil) 1257 1258 input := model.ApplicationRegisterInput{} 1259 appConverterSvc := automock.ApplicationConverter{} 1260 appConverterSvc.Mock.On("CreateInputJSONToModel", mock.Anything, appInputJSON).Return(input, nil) 1261 1262 appSvc := automock.ApplicationService{} 1263 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080"). 1264 Return(nil, errors.New("Object not found")) 1265 appSvc.Mock.On("CreateFromTemplate", mock.Anything, input, str.Ptr("ss")).Return("success", nil) 1266 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 1267 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1268 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appTemplateSvc, &appConverterSvc, &appSvc, &tntSvc) 1269 1270 endpoint := handler.NewHandler(&appSvc, &appConverterSvc, &appTemplateSvc, &tntSvc, &transact) 1271 1272 req := createReportSystemsRequest(strings.NewReader(body), fullReportType) 1273 rec := httptest.NewRecorder() 1274 1275 endpoint.ServeHTTP(rec, req) 1276 1277 resp := rec.Result() 1278 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1279 }) 1280 1281 t.Run("failed to update application", func(t *testing.T) { 1282 setMappings() 1283 defer clearMappings() 1284 1285 tx := &txautomock.PersistenceTx{} 1286 tx.Mock.On("Commit").Return(nil) 1287 1288 listSccsTx := &txautomock.PersistenceTx{} 1289 listSccsTx.Mock.On("Commit").Return(nil) 1290 1291 transact := txautomock.Transactioner{} 1292 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1293 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 1294 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 1295 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 1296 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1297 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1298 1299 ids := []string{testSubaccount} 1300 tntSvc := automock.TenantService{} 1301 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1302 1303 input := nsmodel.ToAppUpdateInput(nsmodel.System{ 1304 SystemBase: nsmodel.SystemBase{ 1305 Protocol: "HTTP", 1306 Host: "127.0.0.1:8080", 1307 SystemType: "otherSAPsys", 1308 Description: "description", 1309 Status: "disabled", 1310 SystemNumber: "number", 1311 }, 1312 TemplateID: "", 1313 }) 1314 1315 appSvc := automock.ApplicationService{} 1316 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080").Return(&application, nil) 1317 appSvc.Mock.On("Update", mock.Anything, application.ID, input).Return(errors.New("error")) 1318 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 1319 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1320 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 1321 1322 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 1323 1324 req := createReportSystemsRequest(strings.NewReader(body), fullReportType) 1325 rec := httptest.NewRecorder() 1326 1327 endpoint.ServeHTTP(rec, req) 1328 1329 resp := rec.Result() 1330 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1331 }) 1332 1333 t.Run("failed to set label systemType", func(t *testing.T) { 1334 setMappings() 1335 defer clearMappings() 1336 1337 tx := &txautomock.PersistenceTx{} 1338 tx.Mock.On("Commit").Return(nil) 1339 1340 listSccsTx := &txautomock.PersistenceTx{} 1341 listSccsTx.Mock.On("Commit").Return(nil) 1342 1343 transact := txautomock.Transactioner{} 1344 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1345 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 1346 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 1347 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 1348 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1349 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1350 1351 ids := []string{testSubaccount} 1352 tntSvc := automock.TenantService{} 1353 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1354 1355 input := nsmodel.ToAppUpdateInput(system) 1356 1357 appSvc := automock.ApplicationService{} 1358 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080").Return(&application, nil) 1359 appSvc.Mock.On("Update", mock.Anything, application.ID, input).Return(nil) 1360 appSvc.Mock.On("SetLabel", mock.Anything, label).Return(errors.New("error")) 1361 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 1362 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1363 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 1364 1365 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 1366 1367 req := createReportSystemsRequest(strings.NewReader(body), fullReportType) 1368 rec := httptest.NewRecorder() 1369 1370 endpoint.ServeHTTP(rec, req) 1371 1372 resp := rec.Result() 1373 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1374 }) 1375 1376 t.Run("failed to set label systemProtocol", func(t *testing.T) { 1377 setMappings() 1378 defer clearMappings() 1379 1380 tx := &txautomock.PersistenceTx{} 1381 tx.Mock.On("Commit").Return(nil) 1382 1383 listSccsTx := &txautomock.PersistenceTx{} 1384 listSccsTx.Mock.On("Commit").Return(nil) 1385 1386 transact := txautomock.Transactioner{} 1387 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1388 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 1389 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 1390 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 1391 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1392 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1393 1394 ids := []string{testSubaccount} 1395 tntSvc := automock.TenantService{} 1396 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1397 1398 input := nsmodel.ToAppUpdateInput(system) 1399 1400 appSvc := automock.ApplicationService{} 1401 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080").Return(&application, nil) 1402 appSvc.Mock.On("Update", mock.Anything, application.ID, input).Return(nil) 1403 appSvc.Mock.On("SetLabel", mock.Anything, label).Return(nil).Once() 1404 appSvc.Mock.On("SetLabel", mock.Anything, protocolLabel).Return(errors.New("error")).Once() 1405 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 1406 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1407 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 1408 1409 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 1410 1411 req := createReportSystemsRequest(strings.NewReader(body), fullReportType) 1412 rec := httptest.NewRecorder() 1413 1414 endpoint.ServeHTTP(rec, req) 1415 1416 resp := rec.Result() 1417 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1418 }) 1419 1420 t.Run("successfully update system", func(t *testing.T) { 1421 setMappings() 1422 defer clearMappings() 1423 1424 tx := &txautomock.PersistenceTx{} 1425 tx.Mock.On("Commit").Return(nil) 1426 1427 listSccsTx := &txautomock.PersistenceTx{} 1428 listSccsTx.Mock.On("Commit").Return(nil) 1429 1430 transact := txautomock.Transactioner{} 1431 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1432 transact.Mock.On("Begin").Return(tx, nil).Once() // used for upsertSccSystems 1433 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 1434 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 1435 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1436 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1437 1438 ids := []string{testSubaccount} 1439 tntSvc := automock.TenantService{} 1440 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1441 1442 input := nsmodel.ToAppUpdateInput(system) 1443 1444 appSvc := automock.ApplicationService{} 1445 appSvc.Mock.On("GetSccSystem", mock.Anything, testSubaccount, "loc-id", "127.0.0.1:8080").Return(&application, nil) 1446 appSvc.Mock.On("Update", mock.Anything, application.ID, input).Return(nil) 1447 appSvc.Mock.On("SetLabel", mock.Anything, label).Return(nil).Once() 1448 appSvc.Mock.On("SetLabel", mock.Anything, protocolLabel).Return(nil).Once() 1449 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 1450 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1451 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 1452 1453 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 1454 1455 req := createReportSystemsRequest(strings.NewReader(body), fullReportType) 1456 rec := httptest.NewRecorder() 1457 1458 endpoint.ServeHTTP(rec, req) 1459 1460 resp := rec.Result() 1461 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1462 }) 1463 1464 t.Run("failed to list by SCC", func(t *testing.T) { 1465 tx := &txautomock.PersistenceTx{} 1466 tx.Mock.On("Commit").Return(nil) 1467 1468 listSccsTx := &txautomock.PersistenceTx{} 1469 1470 transact := txautomock.Transactioner{} 1471 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1472 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Once() 1473 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 1474 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1475 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1476 1477 ids := []string{testSubaccount} 1478 tntSvc := automock.TenantService{} 1479 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1480 1481 appSvc := automock.ApplicationService{} 1482 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return(nil, errors.New("error")) 1483 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1484 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 1485 1486 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 1487 1488 req := createReportSystemsRequest(strings.NewReader(bodyWithoutExposedSystems), fullReportType) 1489 rec := httptest.NewRecorder() 1490 1491 endpoint.ServeHTTP(rec, req) 1492 1493 resp := rec.Result() 1494 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1495 }) 1496 1497 t.Run("fail to mark system as unreachable", func(t *testing.T) { 1498 tx := &txautomock.PersistenceTx{} 1499 tx.Mock.On("Commit").Return(nil) 1500 1501 listSccsTx := &txautomock.PersistenceTx{} 1502 listSccsTx.Mock.On("Commit").Return(nil) 1503 1504 transact := txautomock.Transactioner{} 1505 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1506 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list by scc 1507 transact.Mock.On("Begin").Return(tx, nil).Once() // used for mark as unreachable 1508 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 1509 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1510 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1511 1512 ids := []string{testSubaccount} 1513 tntSvc := automock.TenantService{} 1514 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1515 1516 unreachableInput := model.ApplicationUpdateInput{SystemStatus: str.Ptr("unreachable")} 1517 1518 appSvc := automock.ApplicationService{} 1519 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 1520 appSvc.Mock.On("Update", mock.Anything, appWithLabel.App.ID, unreachableInput).Return(errors.New("error")) 1521 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1522 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 1523 1524 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 1525 1526 req := createReportSystemsRequest(strings.NewReader(bodyWithoutExposedSystems), fullReportType) 1527 rec := httptest.NewRecorder() 1528 1529 endpoint.ServeHTTP(rec, req) 1530 1531 resp := rec.Result() 1532 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1533 }) 1534 1535 t.Run("successfully mark system as unreachable", func(t *testing.T) { 1536 tx := &txautomock.PersistenceTx{} 1537 tx.Mock.On("Commit").Return(nil) 1538 1539 listSccsTx := &txautomock.PersistenceTx{} 1540 listSccsTx.Mock.On("Commit").Return(nil) 1541 1542 transact := txautomock.Transactioner{} 1543 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1544 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list by scc 1545 transact.Mock.On("Begin").Return(tx, nil).Once() // used for mark as unreachable 1546 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Twice() 1547 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1548 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1549 1550 ids := []string{testSubaccount} 1551 tntSvc := automock.TenantService{} 1552 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1553 1554 unreachableInput := model.ApplicationUpdateInput{SystemStatus: str.Ptr("unreachable")} 1555 1556 appSvc := automock.ApplicationService{} 1557 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 1558 appSvc.Mock.On("Update", mock.Anything, appWithLabel.App.ID, unreachableInput).Return(nil) 1559 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1560 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 1561 1562 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 1563 1564 req := createReportSystemsRequest(strings.NewReader(bodyWithoutExposedSystems), fullReportType) 1565 rec := httptest.NewRecorder() 1566 1567 endpoint.ServeHTTP(rec, req) 1568 1569 resp := rec.Result() 1570 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1571 }) 1572 1573 t.Run("successful successfully mark system as unreachable with two sccs connected to one subaccount", func(t *testing.T) { 1574 body := strings.NewReader("{\n \"type\": \"notification-service\",\n \"value\": [\n {\n \"subaccount\": \"fd4f2041-fa83-48e0-b292-ff515bb776f0\",\n \"locationId\": \"loc-id\",\n \"exposedSystems\": []\n },{\n \"subaccount\": \"fd4f2041-fa83-48e0-b292-ff515bb776f0\",\n \"locationId\": \"loc-id-2\",\n \"exposedSystems\": []\n }\n ]\n}") 1575 1576 tx := &txautomock.PersistenceTx{} 1577 tx.Mock.On("Commit").Return(nil) 1578 1579 listSccsTx := &txautomock.PersistenceTx{} 1580 listSccsTx.Mock.On("Commit").Return(nil) 1581 1582 transact := txautomock.Transactioner{} 1583 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1584 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list by scc 1585 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list by scc 1586 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list by scc 1587 transact.Mock.On("Begin").Return(tx, nil).Once() // used for mark as unreachable 1588 transact.Mock.On("Begin").Return(tx, nil).Once() // used for mark as unreachable 1589 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Times(3) 1590 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Times(3) 1591 1592 ids := []string{testSubaccount, testSubaccount} 1593 tntSvc := automock.TenantService{} 1594 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1595 1596 unreachableInput := model.ApplicationUpdateInput{SystemStatus: str.Ptr("unreachable")} 1597 1598 appSvc := automock.ApplicationService{} 1599 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil) 1600 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter2).Return([]*model.ApplicationWithLabel{&appWithLabel2}, nil) 1601 appSvc.Mock.On("Update", mock.Anything, appWithLabel.App.ID, unreachableInput).Return(nil) 1602 appSvc.Mock.On("Update", mock.Anything, appWithLabel2.App.ID, unreachableInput).Return(nil) 1603 appSvc.Mock.On("ListSCCs", mock.Anything).Return(nil, errors.New("error")) 1604 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 1605 1606 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 1607 1608 req := createReportSystemsRequest(body, fullReportType) 1609 rec := httptest.NewRecorder() 1610 1611 endpoint.ServeHTTP(rec, req) 1612 1613 resp := rec.Result() 1614 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1615 }) 1616 1617 t.Run("success when there no unreachable SCCs", func(t *testing.T) { 1618 tx := &txautomock.PersistenceTx{} 1619 tx.Mock.On("Commit").Return(nil) 1620 1621 listSccsTx := &txautomock.PersistenceTx{} 1622 listSccsTx.Mock.On("Commit").Return(nil) 1623 1624 transact := txautomock.Transactioner{} 1625 transact.Mock.On("Begin").Return(tx, nil).Once() // used for list tenants 1626 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //list for mark unreachable 1627 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1628 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Once() 1629 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Twice() 1630 1631 ids := []string{testSubaccount} 1632 tntSvc := automock.TenantService{} 1633 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil) 1634 1635 appSvc := automock.ApplicationService{} 1636 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return(nil, errors.New("error")) 1637 appSvc.Mock.On("ListSCCs", mock.Anything).Return([]*model.SccMetadata{&model.SccMetadata{ 1638 Subaccount: testSubaccount, 1639 LocationID: "loc-id", 1640 }}, nil) 1641 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 1642 1643 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 1644 1645 req := createReportSystemsRequest(strings.NewReader(bodyWithoutExposedSystems), fullReportType) 1646 rec := httptest.NewRecorder() 1647 1648 endpoint.ServeHTTP(rec, req) 1649 1650 resp := rec.Result() 1651 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1652 }) 1653 1654 t.Run("success when there no unreachable SCCs", func(t *testing.T) { 1655 tx := &txautomock.PersistenceTx{} 1656 tx.Mock.On("Commit").Return(nil) 1657 1658 listSccsTx := &txautomock.PersistenceTx{} 1659 listSccsTx.Mock.On("Commit").Return(nil) 1660 1661 transact := txautomock.Transactioner{} 1662 transact.Mock.On("Begin").Return(tx, nil).Once() //used for list tenants 1663 transact.Mock.On("Begin").Return(tx, nil).Once() //used for getting template 1664 transact.Mock.On("Begin").Return(tx, nil).Once() //list for mark unreachable 1665 transact.Mock.On("Begin").Return(listSccsTx, nil).Once() //used in listSCCs 1666 transact.Mock.On("Begin").Return(tx, nil).Once() //used in listAppsBySCC 1667 transact.Mock.On("Begin").Return(tx, nil).Once() //used in markAsUnreachable for unknown SCC 1668 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, tx).Return(true).Times(5) //used in markAsUnreachable for unknown SCC 1669 transact.Mock.On("RollbackUnlessCommitted", mock.Anything, listSccsTx).Return(true).Once() 1670 1671 ids := []string{testSubaccount} 1672 tntSvc := automock.TenantService{} 1673 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: testSubaccount, Type: "subaccount"}}, nil).Once() 1674 ids = []string{"marked-as-unreachable"} 1675 tntSvc.Mock.On("ListsByExternalIDs", mock.Anything, ids).Return([]*model.BusinessTenantMapping{{ID: "id", ExternalTenant: "marked-as-unreachable", Type: "subaccount"}}, nil).Once() 1676 1677 unreachableInput := model.ApplicationUpdateInput{SystemStatus: str.Ptr("unreachable")} 1678 1679 labelFilter2 := labelfilter.NewForKeyWithQuery("scc", fmt.Sprintf("{\"LocationID\":\"%s\", \"Subaccount\":\"%s\"}", "other-loc-id", "marked-as-unreachable")) 1680 1681 appSvc := automock.ApplicationService{} 1682 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter).Return(nil, errors.New("error")).Once() 1683 appSvc.Mock.On("ListSCCs", mock.Anything).Return([]*model.SccMetadata{ 1684 { 1685 Subaccount: testSubaccount, 1686 LocationID: "loc-id", 1687 }, 1688 { 1689 Subaccount: "marked-as-unreachable", 1690 LocationID: "other-loc-id", 1691 }, 1692 }, nil) 1693 appSvc.Mock.On("ListBySCC", mock.Anything, labelFilter2).Return([]*model.ApplicationWithLabel{&appWithLabel}, nil).Once() 1694 appSvc.Mock.On("Update", mock.Anything, appWithLabel.App.ID, unreachableInput).Return(nil) 1695 defer mock.AssertExpectationsForObjects(t, tx, listSccsTx, &transact, &appSvc, &tntSvc) 1696 1697 endpoint := handler.NewHandler(&appSvc, nil, nil, &tntSvc, &transact) 1698 1699 req := createReportSystemsRequest(strings.NewReader(bodyWithoutExposedSystems), fullReportType) 1700 rec := httptest.NewRecorder() 1701 1702 endpoint.ServeHTTP(rec, req) 1703 1704 resp := rec.Result() 1705 Verify(t, resp, http.StatusNoContent, httputils.ContentTypeApplicationJSON, "{}") 1706 }) 1707 } 1708 1709 func Verify(t *testing.T, resp *http.Response, expectedStatusCode int, expectedContentType string, expectedBody string) { 1710 body, err := io.ReadAll(resp.Body) 1711 respBody := strings.TrimSuffix(string(body), "\n") 1712 if nil != err { 1713 t.Fatalf("Failed to read the response body: %v", err) 1714 } 1715 1716 if status := resp.StatusCode; status != expectedStatusCode { 1717 t.Errorf("handler returned wrong status code: got %v want %v", 1718 status, expectedStatusCode) 1719 } 1720 1721 if contentType := resp.Header.Get(httputils.HeaderContentTypeKey); contentType != expectedContentType { 1722 t.Errorf("the response contains unexpected content type: got %s want %s", 1723 contentType, expectedContentType) 1724 } 1725 1726 if respBody != expectedBody { 1727 t.Errorf("handler returned unexpected body: got '%v' want '%v'", 1728 respBody, expectedBody) 1729 } 1730 } 1731 1732 func clearMappings() { 1733 nsmodel.Mappings = nil 1734 } 1735 1736 func setMappings() { 1737 nsmodel.Mappings = append(nsmodel.Mappings, nsmodel.TemplateMapping{ 1738 Name: "", 1739 ID: "ss", 1740 SourceKey: []string{"type"}, 1741 SourceValue: []string{"otherSAPsys"}, 1742 }) 1743 } 1744 1745 func createReportSystemsRequest(body io.Reader, reportType string) *http.Request { 1746 req := httptest.NewRequest(http.MethodPut, "/v1", body) 1747 q := req.URL.Query() 1748 q.Add("reportType", reportType) 1749 req.URL.RawQuery = q.Encode() 1750 return req 1751 }