Skip to content

Commit

Permalink
Cluster list handling code
Browse files Browse the repository at this point in the history
  • Loading branch information
tisnik committed Oct 30, 2020
1 parent aca1407 commit 4631ec9
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 0 deletions.
40 changes: 40 additions & 0 deletions http/router_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package httputils

import (
"encoding/json"
"errors"
"fmt"
"net/http"
"regexp"
Expand Down Expand Up @@ -247,3 +249,41 @@ func handleClusterNameError(writer http.ResponseWriter, err error) {
func SplitRequestParamArray(arrayParam string) []string {
return strings.Split(arrayParam, ",")
}

// ReadClusterListFromPath retrieves list of clusters from request's path
// if it's not possible, it writes http error to the writer and returns false
func ReadClusterListFromPath(writer http.ResponseWriter, request *http.Request) ([]string, bool) {
rawClusterList, err := GetRouterParam(request, "cluster_list")
if err != nil {
types.HandleServerError(writer, err)
return []string{}, false
}

// basic check that should not happen in reality (because of Gorilla mux checks)
if rawClusterList == "" {
types.HandleServerError(writer, errors.New("cluster list is empty"))
return []string{}, false
}

// split the list into items
clusterList := strings.Split(rawClusterList, ",")

// everything seems ok -> return list of clusters
return clusterList, true
}

// ReadClusterListFromBody retrieves list of clusters from request's body
// if it's not possible, it writes http error to the writer and returns false
func ReadClusterListFromBody(writer http.ResponseWriter, request *http.Request) ([]string, bool) {
var clusterList types.ClusterListInRequest

// try to read cluster list from request parameter
err := json.NewDecoder(request.Body).Decode(&clusterList)
if err != nil {
types.HandleServerError(writer, err)
return []string{}, false
}

// everything seems ok -> return list of clusters
return clusterList.Clusters, true
}
125 changes: 125 additions & 0 deletions http/router_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ import (
"github.com/RedHatInsights/insights-operator-utils/types"
)

const (
cluster1ID = "715e10eb-e6ac-49b3-bd72-61734c35b6fb"
cluster2ID = "931f1495-7b16-4637-a41e-963e117bfd02"
)

func TestGetRouterPositiveIntParam_NonIntError(t *testing.T) {
request := mustGetRequestWithMuxVars(t, http.MethodGet, "", nil, map[string]string{
"id": "non int",
Expand Down Expand Up @@ -351,3 +356,123 @@ func paramsToString(separator string, params ...interface{}) string {
res := strings.Join(stringParams, separator)
return res
}

// TestReadClusterListFromPathMissingClusterList function checks if missing
// cluster list in path is detected and processed correctly by function
// ReadClusterListFromPath.
func TestReadClusterListFromPathMissingClusterList(t *testing.T) {
request, err := http.NewRequest(http.MethodGet, "", nil)
helpers.FailOnError(t, err)

// try to read list of clusters from path
_, successful := httputils.ReadClusterListFromPath(httptest.NewRecorder(), request)

// missing list means that the read operation should fail
assert.False(t, successful)
}

// TestReadClusterListFromPathEmptyClusterList function checks if empty cluster
// list in path is detected and processed correctly by function
// ReadClusterListFromPath.
func TestReadClusterListFromPathEmptyClusterList(t *testing.T) {
request := mustGetRequestWithMuxVars(t, http.MethodGet, "", nil, map[string]string{
"cluster_list": "",
})

// try to read list of clusters from path
_, successful := httputils.ReadClusterListFromPath(httptest.NewRecorder(), request)

// empty list means that the read operation should fail
assert.False(t, successful)
}

// TestReadClusterListFromPathOneCluster function checks if list with one
// cluster ID is processed correctly by function ReadClusterListFromPath.
func TestReadClusterListFromPathOneCluster(t *testing.T) {
request := mustGetRequestWithMuxVars(t, http.MethodGet, "", nil, map[string]string{
"cluster_list": fmt.Sprintf("%v", cluster1ID),
})

// try to read list of clusters from path
list, successful := httputils.ReadClusterListFromPath(httptest.NewRecorder(), request)

// cluster list exists so the read operation should not fail
assert.True(t, successful)

// we expect do get list with one cluster ID
assert.ElementsMatch(t, list, []string{cluster1ID})
}

// TestReadClusterListFromPathTwoClusters function checks if list with two
// cluster IDs is processed correctly by function ReadClusterListFromPath.
func TestReadClusterListFromPathTwoClusters(t *testing.T) {
request := mustGetRequestWithMuxVars(t, http.MethodGet, "", nil, map[string]string{
"cluster_list": fmt.Sprintf("%v,%v", cluster1ID, cluster2ID),
})

// try to read list of clusters from path
list, successful := httputils.ReadClusterListFromPath(httptest.NewRecorder(), request)

// cluster list exists so the read operation should not fail
assert.True(t, successful)

// we expect do get list with two cluster IDs
assert.ElementsMatch(t, list, []string{cluster1ID, cluster2ID})
}

// TestReadClusterListFromBodyNoJSON function checks if reading list of
// clusters from empty request body is detected properly by function
// ReadClusterListFromBody.
func TestReadClusterListFromBodyNoJSON(t *testing.T) {
request, err := http.NewRequest(
http.MethodGet,
"",
strings.NewReader(""),
)
helpers.FailOnError(t, err)

// try to read list of clusters from path
_, successful := httputils.ReadClusterListFromBody(httptest.NewRecorder(), request)

// the read should fail because of empty request body
assert.False(t, successful)
}

// TestReadClusterListFromBodyCorrectJSON function checks if reading list of
// clusters from correct request body containing JSON data is done correctly by
// function ReadClusterListFromBody.
func TestReadClusterListFromBodyCorrectJSON(t *testing.T) {
request, err := http.NewRequest(
http.MethodGet,
"",
strings.NewReader(fmt.Sprintf(`{"clusters": ["%v","%v"]}`, cluster1ID, cluster2ID)),
)
helpers.FailOnError(t, err)

// try to read list of clusters from path
list, successful := httputils.ReadClusterListFromBody(httptest.NewRecorder(), request)

// cluster list exists so the call should not fail
assert.True(t, successful)

// we expect do get list with two cluster IDs
assert.ElementsMatch(t, list, []string{cluster1ID, cluster2ID})
}

// TestReadClusterListFromBodyWrongJSON function checks if reading list of
// clusters from request body with improper format is processed correctly by
// function ReadClusterListFromBody.
func TestReadClusterListFromBodyWrongJSON(t *testing.T) {
request, err := http.NewRequest(
http.MethodGet,
"",
strings.NewReader("this-is-not-json"),
)
helpers.FailOnError(t, err)

// try to read list of clusters from path
_, successful := httputils.ReadClusterListFromBody(httptest.NewRecorder(), request)

// the read should fail because of broken JSON
assert.False(t, successful)
}
5 changes: 5 additions & 0 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,8 @@ func (e *ValidationError) Error() string {
e.ParamName, e.ParamValue, e.ErrString,
)
}

// ClusterListInRequest represents request body containing list of clusters
type ClusterListInRequest struct {
Clusters []string `json:"clusters"`
}

0 comments on commit 4631ec9

Please sign in to comment.