1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00
sap-jenkins-library/pkg/ans/ans_test.go
Oliver Feldmann aecf1babd9
[ANS] Add SAP Alert Notification Service to pkg (#3654)
* Add ans implementation

* Remove todo comment

* Rename test function

Co-authored-by: Linda Siebert <39100394+LindaSieb@users.noreply.github.com>

* Better wording

Co-authored-by: Linda Siebert <39100394+LindaSieb@users.noreply.github.com>

* Add reading of response body function

* Use http pkg ReadResponseBody

* Check read error

* Better test case description

* Fix formatting

* Create own package for read response body

* Omit empty nested resource struct

* Separate Resource struct from Event struct

* Merge and unmarshall instead of only unmarshalling

* Improve status code error message

* Remove unchangeable event fields

* Separate event parts

* Change log level setter function

* Restructure ans send test

* Revert exporting readResponseBody function

Instead the code is duplicated in the xsuaa and ans package

* Add check correct ans setup request

* Add set options function for mocking

* Review fixes

* Correct function name

* Use strict unmarshalling

* Validate event

* Move functions

* Add documentation comments

* improve test

Co-authored-by: Linda Siebert <39100394+LindaSieb@users.noreply.github.com>
Co-authored-by: Roland Stengel <r.stengel@sap.com>
2022-06-03 10:16:14 +02:00

213 lines
6.6 KiB
Go

package ans
import (
"encoding/json"
"github.com/SAP/jenkins-library/pkg/xsuaa"
"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
)
type Examinee struct {
xsuaa *xsuaa.XSUAA
server *httptest.Server
ans *ANS
onRequest func(rw http.ResponseWriter, req *http.Request)
}
func (e *Examinee) request(rw http.ResponseWriter, req *http.Request) {
e.onRequest(rw, req)
}
func (e *Examinee) finish() {
if e.server != nil {
e.server.Close()
e.server = nil
}
}
func (e *Examinee) init() {
if e.xsuaa == nil {
e.xsuaa = &xsuaa.XSUAA{
OAuthURL: "https://my.test.oauth.provider",
ClientID: "myTestClientID",
ClientSecret: "super secret",
CachedAuthToken: xsuaa.AuthToken{
TokenType: "bearer",
AccessToken: "1234",
ExpiresIn: 12345,
},
}
}
if e.server == nil {
e.server = httptest.NewServer(http.HandlerFunc(e.request))
}
if e.ans == nil {
e.ans = &ANS{XSUAA: *e.xsuaa, URL: e.server.URL}
}
}
func (e *Examinee) initRun(onRequest func(rw http.ResponseWriter, req *http.Request)) {
e.init()
e.onRequest = onRequest
}
func TestANS_Send(t *testing.T) {
examinee := Examinee{}
defer examinee.finish()
eventDefault := Event{EventType: "my event", EventTimestamp: 1647526655}
t.Run("good", func(t *testing.T) {
t.Run("pass request attributes", func(t *testing.T) {
examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
assert.Equal(t, http.MethodPost, req.Method, "Mismatch in requested method")
assert.Equal(t, "/cf/producer/v1/resource-events", req.URL.Path, "Mismatch in requested path")
assert.Equal(t, "bearer 1234", req.Header.Get(authHeaderKey), "Mismatch in requested auth header")
assert.Equal(t, "application/json", req.Header.Get("Content-Type"), "Mismatch in requested content type header")
})
examinee.ans.Send(eventDefault)
})
t.Run("pass request attribute event", func(t *testing.T) {
examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
eventBody, _ := ioutil.ReadAll(req.Body)
event := &Event{}
json.Unmarshal(eventBody, event)
assert.Equal(t, eventDefault, *event, "Mismatch in requested event body")
})
examinee.ans.Send(eventDefault)
})
t.Run("on status 202", func(t *testing.T) {
examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusAccepted)
})
err := examinee.ans.Send(eventDefault)
require.NoError(t, err, "No error expected.")
})
})
t.Run("bad", func(t *testing.T) {
t.Run("on status 400", func(t *testing.T) {
examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusBadRequest)
rw.Write([]byte("an error occurred"))
})
err := examinee.ans.Send(eventDefault)
assert.Error(t, err)
assert.Contains(t, err.Error(), "Did not get expected status code 202")
})
})
}
func TestANS_CheckCorrectSetup(t *testing.T) {
examinee := Examinee{}
defer examinee.finish()
t.Run("good", func(t *testing.T) {
t.Run("pass request attributes", func(t *testing.T) {
examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
assert.Equal(t, http.MethodGet, req.Method, "Mismatch in requested method")
assert.Equal(t, "/cf/consumer/v1/matched-events", req.URL.Path, "Mismatch in requested path")
assert.Equal(t, "bearer 1234", req.Header.Get(authHeaderKey), "Mismatch in requested auth header")
assert.Equal(t, "application/json", req.Header.Get("Content-Type"), "Mismatch in requested content type header")
})
examinee.ans.CheckCorrectSetup()
})
t.Run("on status 200", func(t *testing.T) {
examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusOK)
})
err := examinee.ans.CheckCorrectSetup()
require.NoError(t, err, "No error expected.")
})
})
t.Run("bad", func(t *testing.T) {
t.Run("on status 400", func(t *testing.T) {
examinee.initRun(func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusBadRequest)
rw.Write([]byte("an error occurred"))
})
err := examinee.ans.CheckCorrectSetup()
assert.Error(t, err)
assert.Contains(t, err.Error(), "Did not get expected status code 200")
})
})
}
func TestANS_UnmarshallServiceKey(t *testing.T) {
t.Parallel()
serviceKeyJSONDefault := `{"url": "https://my.test.backend", "client_id": "myTestClientID", "client_secret": "super secret", "oauth_url": "https://my.test.oauth.provider"}`
serviceKeyDefault := ServiceKey{Url: "https://my.test.backend", ClientId: "myTestClientID", ClientSecret: "super secret", OauthUrl: "https://my.test.oauth.provider"}
t.Run("good", func(t *testing.T) {
t.Run("Proper event JSON yields correct event", func(t *testing.T) {
serviceKey, err := UnmarshallServiceKeyJSON(serviceKeyJSONDefault)
require.NoError(t, err, "No error expected.")
assert.Equal(t, serviceKeyDefault, serviceKey, "Got the wrong ans serviceKey")
})
})
t.Run("bad", func(t *testing.T) {
t.Run("JSON key data is an invalid string", func(t *testing.T) {
serviceKeyDesc := `invalid descriptor`
_, err := UnmarshallServiceKeyJSON(serviceKeyDesc)
assert.Error(t, err)
assert.Contains(t, err.Error(), "error unmarshalling ANS serviceKey")
})
})
}
func TestANS_readResponseBody(t *testing.T) {
tests := []struct {
name string
response *http.Response
want []byte
wantErrText string
}{
{
name: "Straight forward",
response: httpmock.NewStringResponse(200, "test string"),
want: []byte("test string"),
},
{
name: "No response error",
wantErrText: "did not retrieve an HTTP response",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := readResponseBody(tt.response)
if tt.wantErrText != "" {
require.Error(t, err, "Error expected")
assert.EqualError(t, err, tt.wantErrText, "Error is not equal")
} else {
require.NoError(t, err, "No error expected")
assert.Equal(t, tt.want, got, "Did not receive expected body")
}
})
}
}
func TestANS_SetServiceKey(t *testing.T) {
t.Run("ServiceKey sets ANS fields", func(t *testing.T) {
gotANS := &ANS{}
serviceKey := ServiceKey{Url: "https://my.test.backend", ClientId: "myTestClientID", ClientSecret: "super secret", OauthUrl: "https://my.test.oauth.provider"}
gotANS.SetServiceKey(serviceKey)
wantANS := &ANS{
XSUAA: xsuaa.XSUAA{
OAuthURL: "https://my.test.oauth.provider",
ClientID: "myTestClientID",
ClientSecret: "super secret",
},
URL: "https://my.test.backend",
}
assert.Equal(t, wantANS, gotANS)
})
}