event-gateway/internal/source/http/payload_test.go

167 lines
3.9 KiB
Go
Raw Normal View History

2024-04-20 20:31:06 +00:00
// Copyright © 2023 Roberto Hidalgo <event-gateway@un.rob.mx>
// SPDX-License-Identifier: Apache-2.0
package http_test
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http/httptest"
"reflect"
"strings"
"testing"
"time"
"git.rob.mx/nidito/event-gateway/internal/config"
"git.rob.mx/nidito/event-gateway/internal/payload"
"git.rob.mx/nidito/event-gateway/internal/sink"
"git.rob.mx/nidito/event-gateway/internal/sink/debug"
"git.rob.mx/nidito/event-gateway/internal/source/http"
"git.rob.mx/nidito/event-gateway/internal/source/types"
"github.com/sirupsen/logrus"
)
func TestHTTPPayload(t *testing.T) {
logrus.SetLevel(logrus.DebugLevel)
testCases := []struct {
Name string
Payload any
Expect any
ExpectKind payload.Kind
ContentType string
}{
{
Name: "empty-payload",
Payload: nil,
Expect: nil,
ExpectKind: "",
},
{
Name: "text-payload",
Payload: "sup",
Expect: "sup",
ExpectKind: payload.KindText,
},
{
Name: "json-payload",
Payload: map[string]any{"yo": "sup"},
ContentType: "application/json",
Expect: map[string]any{"yo": "sup"},
ExpectKind: payload.KindJSON,
},
{
Name: "form-urlencoded-payload",
Payload: "yo=sup&yo=quihubo&dude=sweet",
ContentType: "application/x-www-form-urlencoded",
Expect: map[string]any{"yo": []string{"sup", "quihubo"}, "dude": "sweet"},
ExpectKind: payload.KindForm,
},
{
Name: "form-data-payload",
Payload: strings.ReplaceAll(`
--424242
Content-Disposition: form-data; name="yo"
sup
--424242
Content-Disposition: form-data; name="yo"
quihubo
--424242
Content-Disposition: form-data; name="dude"
sweet
--424242
Content-Disposition: form-data; name="ignored"; filename="example.txt"
Content-type: text/plain
some ignored text
--424242--
`, "\n", "\r\n"),
ContentType: `multipart/form-data; boundary=424242`,
Expect: map[string]any{"yo": []string{"sup", "quihubo"}, "dude": "sweet"},
ExpectKind: payload.KindForm,
},
}
for _, tc := range testCases {
t.Run(tc.Name, func(t *testing.T) {
sink.Clear()
server := http.New(nil)
target := &debug.Event{}
l := &config.Listener{
ID: tc.Name,
Source: &config.RawSource{
Kind: types.HTTP,
Config: []byte(fmt.Sprintf(`{"path": "%s"}`, tc.Name)),
},
Event: target,
}
if err := server.Register(l); err != nil {
t.Fatalf("failed to register %s", tc.Name)
}
outbound := &bytes.Buffer{}
if tc.Payload != nil {
if tc.ContentType == "application/json" {
if serialized, err := json.Marshal(tc.Payload); err != nil {
t.Fatalf("could not serialize %s payload: %s", tc.Name, err)
} else {
outbound = bytes.NewBuffer(serialized)
}
} else {
outbound = bytes.NewBufferString(tc.Payload.(string))
}
}
res := httptest.NewRecorder()
req := httptest.NewRequest("POST", "/-/"+tc.Name, outbound)
if tc.ContentType != "" {
req.Header["Content-Type"] = []string{tc.ContentType}
}
server.Router.ServeHTTP(res, req)
defer req.Body.Close()
if res.Code > 200 {
body, _ := io.ReadAll(res.Body)
logrus.Errorf("request headers: %+v", req.Header)
t.Fatalf("Request ended with non 200 code: %d: %s", res.Code, body)
}
time.Sleep(15 * time.Millisecond)
sI, err := sink.ForKind(target.Kind())
if err != nil {
t.Fatalf("could not get debug sink %s", err)
}
s := sI.(*debug.Sink)
if len(s.Calls) != 1 {
t.Fatalf("unexpected number of triggers called: %+v", s.Calls)
}
payload, err := payload.FromContext(s.Calls[0])
if err != nil {
t.Fatalf("Could not parse payload: %s", err)
}
var got any = nil
if tc.Expect != nil {
if payload == nil {
t.Fatalf("no payload parsed!")
}
got = payload.Value
}
if !reflect.DeepEqual(got, tc.Expect) {
t.Fatalf("%s: unexpected payload, wanted %v, got: %v", tc.Name, tc.Expect, got)
}
})
}
}