github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/pkg/http/request_test.go (about)

     1  package http_test
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/base64"
     7  	"encoding/json"
     8  	"io"
     9  	"net/http"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/kyma-incubator/compass/components/director/internal/model"
    14  
    15  	"github.com/pkg/errors"
    16  
    17  	httputil "github.com/kyma-incubator/compass/components/director/pkg/http"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  const testURL = "http://localhost:8000"
    22  const testTenant = "testTenant"
    23  
    24  var (
    25  	expectedResp = &http.Response{
    26  		StatusCode: http.StatusOK,
    27  		Body:       nil,
    28  	}
    29  	testErr = errors.New("test error")
    30  )
    31  
    32  type RoundTripFunc func(req *http.Request) *http.Response
    33  
    34  func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
    35  	if resp := f(req); resp == nil {
    36  		return nil, testErr
    37  	}
    38  	return f(req), nil
    39  }
    40  
    41  func newTestClient(fn RoundTripFunc) *http.Client {
    42  	return &http.Client{
    43  		Transport: fn,
    44  	}
    45  }
    46  
    47  func TestRequestWithoutCredentials_Success(t *testing.T) {
    48  	client := newTestClient(func(req *http.Request) *http.Response {
    49  		require.Empty(t, req.Header.Get("Authorization"))
    50  		return expectedResp
    51  	})
    52  
    53  	resp, err := httputil.GetRequestWithoutCredentials(client, testURL, testTenant)
    54  	require.NoError(t, err)
    55  	require.Equal(t, resp, expectedResp)
    56  }
    57  
    58  func TestRequestWithoutCredentials_FailedRequest(t *testing.T) {
    59  	client := newTestClient(func(req *http.Request) *http.Response {
    60  		return nil
    61  	})
    62  
    63  	_, err := httputil.GetRequestWithoutCredentials(client, testURL, testTenant)
    64  	require.ErrorIs(t, err, testErr)
    65  }
    66  
    67  func TestRequestWithCredentials_SuccessWithBasicAuth(t *testing.T) {
    68  	user, pass := "username", "password"
    69  	client := newTestClient(func(req *http.Request) *http.Response {
    70  		username, password, exists := req.BasicAuth()
    71  		require.True(t, exists)
    72  		require.Equal(t, username, user)
    73  		require.Equal(t, password, pass)
    74  		return expectedResp
    75  	})
    76  
    77  	resp, err := httputil.GetRequestWithCredentials(context.Background(), client, testURL, testTenant, &model.Auth{
    78  		Credential: model.CredentialData{
    79  			Basic: &model.BasicCredentialData{
    80  				Username: user,
    81  				Password: pass,
    82  			},
    83  		},
    84  	})
    85  	require.NoError(t, err)
    86  	require.Equal(t, resp, expectedResp)
    87  }
    88  
    89  func TestRequestWithCredentials_FailedWithBasicAuth(t *testing.T) {
    90  	client := newTestClient(func(req *http.Request) *http.Response {
    91  		return nil
    92  	})
    93  
    94  	_, err := httputil.GetRequestWithCredentials(context.Background(), client, testURL, testTenant, &model.Auth{
    95  		Credential: model.CredentialData{
    96  			Basic: &model.BasicCredentialData{
    97  				Username: "user",
    98  				Password: "pass",
    99  			},
   100  		},
   101  	})
   102  	require.ErrorIs(t, err, testErr)
   103  }
   104  
   105  func TestRequestWithCredentials_SuccessWithOAuth(t *testing.T) {
   106  	clientID := "client-id"
   107  	clientSecret := "client-secret"
   108  	tokenURL := "http://oauth-server.com/token"
   109  	testTkn := "test-tkn"
   110  
   111  	client := newTestClient(func(req *http.Request) *http.Response {
   112  		authorizationHeader := req.Header.Get("Authorization")
   113  		if strings.Contains(req.URL.String(), testURL) {
   114  			require.Equal(t, authorizationHeader, "Bearer "+testTkn)
   115  
   116  			return expectedResp
   117  		}
   118  
   119  		auth := strings.TrimLeft(authorizationHeader, "Basic ")
   120  		data, err := base64.StdEncoding.DecodeString(auth)
   121  		require.NoError(t, err)
   122  		clientCreds := strings.Split(string(data), ":")
   123  		require.Equal(t, clientID, clientCreds[0])
   124  		require.Equal(t, clientSecret, clientCreds[1])
   125  		require.Equal(t, tokenURL, req.URL.String())
   126  
   127  		data, err = json.Marshal(struct {
   128  			AccessToken string `json:"access_token"`
   129  		}{
   130  			AccessToken: testTkn,
   131  		})
   132  		require.NoError(t, err)
   133  		return &http.Response{
   134  			StatusCode: http.StatusOK,
   135  			Body:       io.NopCloser(bytes.NewBuffer(data)),
   136  		}
   137  	})
   138  
   139  	resp, err := httputil.GetRequestWithCredentials(context.Background(), client, testURL, testTenant, &model.Auth{
   140  		Credential: model.CredentialData{
   141  			Oauth: &model.OAuthCredentialData{
   142  				ClientID:     clientID,
   143  				ClientSecret: clientSecret,
   144  				URL:          tokenURL,
   145  			},
   146  		},
   147  	})
   148  	require.NoError(t, err)
   149  	require.Equal(t, resp, expectedResp)
   150  }
   151  
   152  func TestRequestWithCredentials_FailedWithOAuthDueToInvalidCredentials(t *testing.T) {
   153  	client := newTestClient(func(req *http.Request) *http.Response {
   154  		return &http.Response{
   155  			StatusCode: http.StatusUnauthorized,
   156  		}
   157  	})
   158  
   159  	_, err := httputil.GetRequestWithCredentials(context.Background(), client, testURL, testTenant, &model.Auth{
   160  		Credential: model.CredentialData{
   161  			Oauth: &model.OAuthCredentialData{},
   162  		},
   163  	})
   164  	require.Error(t, err)
   165  }