github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/cis/client_test.go (about)

     1  package cis
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"testing"
     9  
    10  	"github.com/kyma-project/kyma-environment-broker/internal/logger"
    11  
    12  	"github.com/gorilla/mux"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  const (
    17  	subAccountTest1 = "fda14cab-bacc-4d0b-a10f-18557a6d9060"
    18  	subAccountTest2 = "7514cf27-41b0-4266-a273-637cb3a2c051"
    19  	subAccountTest3 = "47af15c8-adfe-4404-8675-525a878c4601"
    20  )
    21  
    22  func TestClient_FetchSubaccountsToDelete(t *testing.T) {
    23  	t.Run("client fetched all subaccount IDs to delete", func(t *testing.T) {
    24  		// Given
    25  		testServer := fixHTTPServer(newServer(t))
    26  		defer testServer.Close()
    27  
    28  		client := NewClient(context.TODO(), Config{
    29  			EventServiceURL: testServer.URL,
    30  			PageSize:        "3",
    31  		}, logger.NewLogDummy())
    32  		client.SetHttpClient(testServer.Client())
    33  
    34  		// When
    35  		saList, err := client.FetchSubaccountsToDelete()
    36  
    37  		// Then
    38  		require.NoError(t, err)
    39  		require.Len(t, saList, 3)
    40  		require.ElementsMatch(t, saList, []string{subAccountTest1, subAccountTest2, subAccountTest3})
    41  	})
    42  
    43  	t.Run("error occur during fetch subaccount IDs", func(t *testing.T) {
    44  		// Given
    45  		srv := newServer(t)
    46  		srv.serverErr = true
    47  		testServer := fixHTTPServer(srv)
    48  		defer testServer.Close()
    49  
    50  		client := NewClient(context.TODO(), Config{
    51  			EventServiceURL: testServer.URL,
    52  			PageSize:        "3",
    53  		}, logger.NewLogDummy())
    54  		client.SetHttpClient(testServer.Client())
    55  
    56  		// When
    57  		saList, err := client.FetchSubaccountsToDelete()
    58  
    59  		// Then
    60  		require.Error(t, err)
    61  		require.Len(t, saList, 0)
    62  	})
    63  
    64  	t.Run("should fetch subaccounts ids after request retries", func(t *testing.T) {
    65  		// Given
    66  		srv := newServer(t)
    67  		srv.rateLimiting = true
    68  		srv.requiredRequestRetries = 1
    69  		testServer := fixHTTPServer(srv)
    70  		defer testServer.Close()
    71  
    72  		client := NewClient(context.TODO(), Config{
    73  			EventServiceURL:   testServer.URL,
    74  			PageSize:          "3",
    75  			MaxRequestRetries: 3,
    76  		}, logger.NewLogDummy())
    77  		client.SetHttpClient(testServer.Client())
    78  
    79  		// When
    80  		saList, err := client.FetchSubaccountsToDelete()
    81  
    82  		// Then
    83  		require.NoError(t, err)
    84  		require.Len(t, saList, 3)
    85  		require.ElementsMatch(t, saList, []string{subAccountTest1, subAccountTest2, subAccountTest3})
    86  	})
    87  
    88  	t.Run("should return rate limiting error", func(t *testing.T) {
    89  		// Given
    90  		srv := newServer(t)
    91  		srv.rateLimiting = true
    92  		srv.requiredRequestRetries = 5
    93  		testServer := fixHTTPServer(srv)
    94  		defer testServer.Close()
    95  
    96  		client := NewClient(context.TODO(), Config{
    97  			EventServiceURL:   testServer.URL,
    98  			PageSize:          "3",
    99  			MaxRequestRetries: 3,
   100  		}, logger.NewLogDummy())
   101  		client.SetHttpClient(testServer.Client())
   102  
   103  		// When
   104  		saList, err := client.FetchSubaccountsToDelete()
   105  
   106  		// Then
   107  		require.Error(t, err)
   108  		require.Len(t, saList, 0)
   109  	})
   110  }
   111  
   112  type server struct {
   113  	t                      *testing.T
   114  	serverErr              bool
   115  	rateLimiting           bool
   116  	requestRetriesCount    int
   117  	requiredRequestRetries int
   118  }
   119  
   120  func newServer(t *testing.T) *server {
   121  	return &server{
   122  		t: t,
   123  	}
   124  }
   125  
   126  func fixHTTPServer(srv *server) *httptest.Server {
   127  	r := mux.NewRouter()
   128  
   129  	r.HandleFunc("/events/v1/events/central", srv.returnCISEvents).Methods(http.MethodGet)
   130  
   131  	return httptest.NewServer(r)
   132  }
   133  
   134  func (s *server) returnCISEvents(w http.ResponseWriter, r *http.Request) {
   135  	eventType := r.URL.Query().Get("eventType")
   136  	if eventType != "Subaccount_Deletion" {
   137  		w.WriteHeader(http.StatusNotFound)
   138  		return
   139  	}
   140  
   141  	if s.serverErr {
   142  		s.writeResponse(w, []byte(`{bad}`))
   143  		return
   144  	}
   145  
   146  	if s.rateLimiting {
   147  		if s.requestRetriesCount < s.requiredRequestRetries {
   148  			s.writeRateLimitingResponse(w)
   149  			s.requestRetriesCount++
   150  			return
   151  		}
   152  	}
   153  
   154  	pageNum := r.URL.Query().Get("pageNum")
   155  	var response string
   156  	if pageNum != "0" {
   157  		response = `{}`
   158  	} else {
   159  		response = fmt.Sprintf(`{
   160  			"total": 3,
   161  			"totalPages": 1,
   162  			"pageNum": 0,
   163  			"morePages": "false",
   164  			"events": [
   165  				{
   166  					"id": 631087,
   167  					"actionTime": 1597135762286,
   168  					"creationTime": 1597135763081,
   169  					"details": {
   170  						"description": "Subaccount deleted.",
   171  						"guid": "%s",
   172  						"parentGuid": "a6c5f1b0-9713-45fc-a831-ed0057a7925c",
   173  						"displayName": "trial",
   174  						"subaccountDescription": null,
   175  						"region": "eu10-canary",
   176  						"jobLocation": null,
   177  						"subdomain": "e8b84ae5trial",
   178  						"betaEnabled": false,
   179  						"expiryDate": null
   180  					},
   181  					"globalAccountGUID": "a6c5f1b0-9713-45fc-a831-ed0057a7925c",
   182  					"entityId": "%s",
   183  					"entityType": "Subaccount",
   184  					"eventOrigin": "accounts-service",
   185  					"eventType": "Subaccount_Deletion"
   186  				},
   187  				{
   188  					"id": 629225,
   189  					"actionTime": 1597090087820,
   190  					"creationTime": 1597090088405,
   191  					"details": {
   192  					"description": "Subaccount deleted.",
   193  						"guid": "%s",
   194  						"parentGuid": "ec0a066a-60a1-4d31-b329-80cf97292789",
   195  						"displayName": "Vered-Neo1",
   196  						"subaccountDescription": null,
   197  						"region": "eu1-canary",
   198  						"jobLocation": null,
   199  						"subdomain": "74eb3e9f-d8f5-4dc9-b2fe-5a5c061487c2",
   200  						"betaEnabled": false,
   201  						"expiryDate": null
   202  					},
   203  					"globalAccountGUID": "ec0a066a-60a1-4d31-b329-80cf97292789",
   204  					"entityId": "%s",
   205  					"entityType": "Subaccount",
   206  					"eventOrigin": "accounts-service",
   207  					"eventType": "Subaccount_Deletion"
   208  				},
   209  				{
   210  					"id": 629224,
   211  					"actionTime": 1597090066116,
   212  					"creationTime": 1597090067309,
   213  					"details": {
   214  					"description": "Subaccount deleted.",
   215  						"guid": "%s",
   216  						"parentGuid": "ec0a066a-60a1-4d31-b329-80cf97292789",
   217  						"displayName": "anatneo",
   218  						"subaccountDescription": null,
   219  						"region": "eu1-canary",
   220  						"jobLocation": null,
   221  						"subdomain": "095db937-725d-4ce6-b802-ce33403e90d1",
   222  						"betaEnabled": false,
   223  						"expiryDate": null
   224  					},
   225  					"globalAccountGUID": "ec0a066a-60a1-4d31-b329-80cf97292789",
   226  					"entityId": "%s",
   227  					"entityType": "Subaccount",
   228  					"eventOrigin": "accounts-service",
   229  					"eventType": "Subaccount_Deletion"
   230  				}]
   231  		}`, subAccountTest1, subAccountTest1, subAccountTest2, subAccountTest2, subAccountTest3, subAccountTest3)
   232  	}
   233  
   234  	s.writeResponse(w, []byte(response))
   235  	s.requestRetriesCount = 0
   236  }
   237  
   238  func (s *server) writeResponse(w http.ResponseWriter, response []byte) {
   239  	_, err := w.Write(response)
   240  	if err != nil {
   241  		s.t.Errorf("fakeCisServer cannot write response: %s", err)
   242  		w.WriteHeader(http.StatusInternalServerError)
   243  		return
   244  	}
   245  	w.WriteHeader(http.StatusOK)
   246  }
   247  
   248  func (s *server) writeRateLimitingResponse(w http.ResponseWriter) {
   249  	response := fmt.Sprint(`{
   250  		"error": {
   251  			"message": "Request rate limit exceeded"
   252  		}
   253  	}`)
   254  	w.WriteHeader(http.StatusTooManyRequests)
   255  	_, err := w.Write([]byte(response))
   256  	if err != nil {
   257  		s.t.Errorf("fakeCisServer cannot write response: %s", err)
   258  		w.WriteHeader(http.StatusInternalServerError)
   259  		return
   260  	}
   261  }