github.com/jaylevin/jenkins-library@v1.230.4/pkg/ans/ans_test.go (about)

     1  package ans
     2  
     3  import (
     4  	"encoding/json"
     5  	"github.com/SAP/jenkins-library/pkg/xsuaa"
     6  	"github.com/jarcoal/httpmock"
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  	"io/ioutil"
    10  	"net/http"
    11  	"net/http/httptest"
    12  	"testing"
    13  )
    14  
    15  type Examinee struct {
    16  	xsuaa     *xsuaa.XSUAA
    17  	server    *httptest.Server
    18  	ans       *ANS
    19  	onRequest func(rw http.ResponseWriter, req *http.Request)
    20  }
    21  
    22  func (e *Examinee) request(rw http.ResponseWriter, req *http.Request) {
    23  	e.onRequest(rw, req)
    24  }
    25  
    26  func (e *Examinee) finish() {
    27  	if e.server != nil {
    28  		e.server.Close()
    29  		e.server = nil
    30  	}
    31  }
    32  
    33  func (e *Examinee) init() {
    34  	if e.xsuaa == nil {
    35  		e.xsuaa = &xsuaa.XSUAA{
    36  			OAuthURL:     "https://my.test.oauth.provider",
    37  			ClientID:     "myTestClientID",
    38  			ClientSecret: "super secret",
    39  			CachedAuthToken: xsuaa.AuthToken{
    40  				TokenType:   "bearer",
    41  				AccessToken: "1234",
    42  				ExpiresIn:   12345,
    43  			},
    44  		}
    45  	}
    46  	if e.server == nil {
    47  		e.server = httptest.NewServer(http.HandlerFunc(e.request))
    48  	}
    49  	if e.ans == nil {
    50  		e.ans = &ANS{XSUAA: *e.xsuaa, URL: e.server.URL}
    51  	}
    52  }
    53  
    54  func (e *Examinee) initRun(onRequest func(rw http.ResponseWriter, req *http.Request)) {
    55  	e.init()
    56  	e.onRequest = onRequest
    57  }
    58  
    59  func TestANS_Send(t *testing.T) {
    60  	examinee := Examinee{}
    61  	defer examinee.finish()
    62  
    63  	eventDefault := Event{EventType: "my event", EventTimestamp: 1647526655}
    64  
    65  	t.Run("good", func(t *testing.T) {
    66  		t.Run("pass request attributes", func(t *testing.T) {
    67  			examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
    68  				assert.Equal(t, http.MethodPost, req.Method, "Mismatch in requested method")
    69  				assert.Equal(t, "/cf/producer/v1/resource-events", req.URL.Path, "Mismatch in requested path")
    70  				assert.Equal(t, "bearer 1234", req.Header.Get(authHeaderKey), "Mismatch in requested auth header")
    71  				assert.Equal(t, "application/json", req.Header.Get("Content-Type"), "Mismatch in requested content type header")
    72  			})
    73  			examinee.ans.Send(eventDefault)
    74  		})
    75  		t.Run("pass request attribute event", func(t *testing.T) {
    76  			examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
    77  				eventBody, _ := ioutil.ReadAll(req.Body)
    78  				event := &Event{}
    79  				json.Unmarshal(eventBody, event)
    80  				assert.Equal(t, eventDefault, *event, "Mismatch in requested event body")
    81  			})
    82  			examinee.ans.Send(eventDefault)
    83  		})
    84  		t.Run("on status 202", func(t *testing.T) {
    85  			examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
    86  				rw.WriteHeader(http.StatusAccepted)
    87  			})
    88  			err := examinee.ans.Send(eventDefault)
    89  			require.NoError(t, err, "No error expected.")
    90  		})
    91  	})
    92  
    93  	t.Run("bad", func(t *testing.T) {
    94  		t.Run("on status 400", func(t *testing.T) {
    95  			examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
    96  				rw.WriteHeader(http.StatusBadRequest)
    97  				rw.Write([]byte("an error occurred"))
    98  			})
    99  			err := examinee.ans.Send(eventDefault)
   100  			assert.Error(t, err)
   101  			assert.Contains(t, err.Error(), "Did not get expected status code 202")
   102  		})
   103  	})
   104  }
   105  
   106  func TestANS_CheckCorrectSetup(t *testing.T) {
   107  	examinee := Examinee{}
   108  	defer examinee.finish()
   109  
   110  	t.Run("good", func(t *testing.T) {
   111  		t.Run("pass request attributes", func(t *testing.T) {
   112  			examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
   113  				assert.Equal(t, http.MethodGet, req.Method, "Mismatch in requested method")
   114  				assert.Equal(t, "/cf/consumer/v1/matched-events", req.URL.Path, "Mismatch in requested path")
   115  				assert.Equal(t, "bearer 1234", req.Header.Get(authHeaderKey), "Mismatch in requested auth header")
   116  				assert.Equal(t, "application/json", req.Header.Get("Content-Type"), "Mismatch in requested content type header")
   117  			})
   118  			examinee.ans.CheckCorrectSetup()
   119  		})
   120  		t.Run("on status 200", func(t *testing.T) {
   121  			examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
   122  				rw.WriteHeader(http.StatusOK)
   123  			})
   124  			err := examinee.ans.CheckCorrectSetup()
   125  			require.NoError(t, err, "No error expected.")
   126  		})
   127  	})
   128  
   129  	t.Run("bad", func(t *testing.T) {
   130  		t.Run("on status 400", func(t *testing.T) {
   131  			examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
   132  				rw.WriteHeader(http.StatusBadRequest)
   133  				rw.Write([]byte("an error occurred"))
   134  			})
   135  			err := examinee.ans.CheckCorrectSetup()
   136  			assert.Error(t, err)
   137  			assert.Contains(t, err.Error(), "Did not get expected status code 200")
   138  		})
   139  	})
   140  }
   141  
   142  func TestANS_UnmarshallServiceKey(t *testing.T) {
   143  	t.Parallel()
   144  
   145  	serviceKeyJSONDefault := `{"url": "https://my.test.backend", "client_id": "myTestClientID", "client_secret": "super secret", "oauth_url": "https://my.test.oauth.provider"}`
   146  	serviceKeyDefault := ServiceKey{Url: "https://my.test.backend", ClientId: "myTestClientID", ClientSecret: "super secret", OauthUrl: "https://my.test.oauth.provider"}
   147  
   148  	t.Run("good", func(t *testing.T) {
   149  		t.Run("Proper event JSON yields correct event", func(t *testing.T) {
   150  			serviceKey, err := UnmarshallServiceKeyJSON(serviceKeyJSONDefault)
   151  			require.NoError(t, err, "No error expected.")
   152  			assert.Equal(t, serviceKeyDefault, serviceKey, "Got the wrong ans serviceKey")
   153  		})
   154  	})
   155  
   156  	t.Run("bad", func(t *testing.T) {
   157  		t.Run("JSON key data is an invalid string", func(t *testing.T) {
   158  			serviceKeyDesc := `invalid descriptor`
   159  			_, err := UnmarshallServiceKeyJSON(serviceKeyDesc)
   160  			assert.Error(t, err)
   161  			assert.Contains(t, err.Error(), "error unmarshalling ANS serviceKey")
   162  		})
   163  	})
   164  }
   165  
   166  func TestANS_readResponseBody(t *testing.T) {
   167  	tests := []struct {
   168  		name        string
   169  		response    *http.Response
   170  		want        []byte
   171  		wantErrText string
   172  	}{
   173  		{
   174  			name:     "Straight forward",
   175  			response: httpmock.NewStringResponse(200, "test string"),
   176  			want:     []byte("test string"),
   177  		},
   178  		{
   179  			name:        "No response error",
   180  			wantErrText: "did not retrieve an HTTP response",
   181  		},
   182  	}
   183  	for _, tt := range tests {
   184  		t.Run(tt.name, func(t *testing.T) {
   185  			got, err := readResponseBody(tt.response)
   186  			if tt.wantErrText != "" {
   187  				require.Error(t, err, "Error expected")
   188  				assert.EqualError(t, err, tt.wantErrText, "Error is not equal")
   189  			} else {
   190  				require.NoError(t, err, "No error expected")
   191  				assert.Equal(t, tt.want, got, "Did not receive expected body")
   192  			}
   193  		})
   194  	}
   195  }
   196  
   197  func TestANS_SetServiceKey(t *testing.T) {
   198  	t.Run("ServiceKey sets ANS fields", func(t *testing.T) {
   199  		gotANS := &ANS{}
   200  		serviceKey := ServiceKey{Url: "https://my.test.backend", ClientId: "myTestClientID", ClientSecret: "super secret", OauthUrl: "https://my.test.oauth.provider"}
   201  		gotANS.SetServiceKey(serviceKey)
   202  		wantANS := &ANS{
   203  			XSUAA: xsuaa.XSUAA{
   204  				OAuthURL:     "https://my.test.oauth.provider",
   205  				ClientID:     "myTestClientID",
   206  				ClientSecret: "super secret",
   207  			},
   208  			URL: "https://my.test.backend",
   209  		}
   210  		assert.Equal(t, wantANS, gotANS)
   211  	})
   212  }