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  }