Adding JSON format validation API tests

This commit is contained in:
Denis Makogon
2017-10-01 15:09:56 +03:00
parent 588d9e523b
commit 3ae55af392
6 changed files with 159 additions and 5 deletions

View File

@@ -0,0 +1,8 @@
FROM fnproject/go:dev as build-stage
WORKDIR /function
ADD . /src
RUN cd /src && go build -o func
FROM fnproject/go
WORKDIR /function
COPY --from=build-stage /src/func /function/
ENTRYPOINT ["./func"]

View File

@@ -0,0 +1,68 @@
package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"strconv"
)
type Person struct {
Name string `json:"name"`
}
type JSON struct {
Headers http.Header `json:"headers"`
Body string `json:"body,omitempty"`
StatusCode int `json:"status,omitempty"`
}
func main() {
stdin := json.NewDecoder(os.Stdin)
stdout := json.NewEncoder(os.Stdout)
stderr := json.NewEncoder(os.Stderr)
for {
in := &JSON{}
err := stdin.Decode(in)
if err != nil {
log.Fatalf("Unable to decode incoming data: %s", err.Error())
fmt.Fprintf(os.Stderr, err.Error())
}
person := Person{}
stderr.Encode(in.Body)
if len(in.Body) != 0 {
if err := json.NewDecoder(bytes.NewReader([]byte(in.Body))).Decode(&person); err != nil {
log.Fatalf("Unable to decode Person object data: %s", err.Error())
fmt.Fprintf(os.Stderr, err.Error())
}
}
if person.Name == "" {
person.Name = "World"
}
mapResult := map[string]string{"message": fmt.Sprintf("Hello %s", person.Name)}
b, err := json.Marshal(mapResult)
if err != nil {
log.Fatalf("Unable to marshal JSON response body: %s", err.Error())
fmt.Fprintf(os.Stderr, err.Error())
}
h := http.Header{}
h.Set("Content-Type", "application/json")
h.Set("Content-Length", strconv.Itoa(len(b)))
out := &JSON{
StatusCode: http.StatusOK,
Body: string(b),
Headers: h,
}
stderr.Encode(out)
if err := stdout.Encode(out); err != nil {
log.Fatalf("Unable to encode JSON response: %s", err.Error())
fmt.Fprintf(os.Stderr, err.Error())
}
}
}

View File

@@ -0,0 +1,72 @@
package tests
import (
"bytes"
"encoding/json"
"net/url"
"path"
"strconv"
"strings"
"testing"
)
type JSONResponse struct {
Message string `json:"message"`
}
func TestFnFormats(t *testing.T) {
t.Run("test-json-format", func(t *testing.T) {
t.Parallel()
s := SetupDefaultSuite()
// TODO(treeder): put image in fnproject @ dockerhub
image := "denismakogon/test-hot-json-go:0.0.1"
format := "json"
route := "/test-hot-json-go"
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
CreateRoute(t, s.Context, s.Client, s.AppName, route, image, "sync",
format, s.RouteConfig, s.RouteHeaders)
u := url.URL{
Scheme: "http",
Host: Host(),
}
u.Path = path.Join(u.Path, "r", s.AppName, s.RoutePath)
b, _ := json.Marshal(&struct {
Name string `json:"name"`
}{
Name: "Jimmy",
})
content := bytes.NewBuffer(b)
output := &bytes.Buffer{}
headers, err := CallFN(u.String(), content, output, "POST", []string{})
if err != nil {
t.Errorf("Got unexpected error: %v", err)
}
msg := &JSONResponse{}
json.Unmarshal(output.Bytes(), msg)
expectedOutput := "Hello Jimmy"
if !strings.Contains(expectedOutput, msg.Message) {
t.Errorf("Assertion error.\n\tExpected: %v\n\tActual: %v", expectedOutput, output.String())
}
expectedHeaderNames := []string{"Content-Type", "Content-Length"}
expectedHeaderValues := []string{"application/json; charset=utf-8", strconv.Itoa(output.Len())}
for i, name := range expectedHeaderNames {
actual := headers.Get(name)
expected := expectedHeaderValues[i]
if !strings.Contains(expected, actual) {
t.Errorf("HTTP header assertion error for %v."+
"\n\tExpected: %v\n\tActual: %v", name, expected, actual)
}
}
DeleteApp(t, s.Context, s.Client, s.AppName)
})
}

View File

@@ -89,7 +89,7 @@ func assertRouteFields(t *testing.T, routeObject *models.Route, path, image, rou
}
func createRoute(ctx context.Context, fnclient *client.Fn, appName, image, routePath, routeType string, routeConfig map[string]string, headers map[string][]string) (*routes.PostAppsAppRoutesOK, error) {
func createRoute(ctx context.Context, fnclient *client.Fn, appName, image, routePath, routeType, routeFormat string, routeConfig map[string]string, headers map[string][]string) (*routes.PostAppsAppRoutesOK, error) {
cfg := &routes.PostAppsAppRoutesParams{
App: appName,
Body: &models.RouteWrapper{
@@ -99,6 +99,7 @@ func createRoute(ctx context.Context, fnclient *client.Fn, appName, image, route
Image: image,
Path: routePath,
Type: routeType,
Format: routeFormat,
},
},
Context: ctx,
@@ -119,7 +120,7 @@ func createRoute(ctx context.Context, fnclient *client.Fn, appName, image, route
}
func CreateRoute(t *testing.T, ctx context.Context, fnclient *client.Fn, appName, routePath, image, routeType, routeFormat string, routeConfig map[string]string, headers map[string][]string) {
routeResponse, err := createRoute(ctx, fnclient, appName, image, routePath, routeType, routeConfig, headers)
routeResponse, err := createRoute(ctx, fnclient, appName, image, routePath, routeType, routeFormat, routeConfig, headers)
CheckRouteResponseError(t, err)
assertRouteFields(t, routeResponse.Payload.Route, routePath, image, routeType, routeFormat)

View File

@@ -16,7 +16,7 @@ func TestRoutes(t *testing.T) {
t.Parallel()
s := SetupDefaultSuite()
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
_, err := createRoute(s.Context, s.Client, s.AppName, s.RoutePath, s.Image, "",
_, err := createRoute(s.Context, s.Client, s.AppName, s.RoutePath, s.Image, "", s.Format,
s.RouteConfig, s.RouteHeaders)
if err == nil {
t.Errorf("Should fail with Invalid route Type.")
@@ -128,7 +128,8 @@ func TestRoutes(t *testing.T) {
CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, s.RouteType,
s.Format, s.RouteConfig, s.RouteHeaders)
_, err := createRoute(s.Context, s.Client, s.AppName, s.Image, s.RoutePath, newRouteType, s.RouteConfig, s.RouteHeaders)
_, err := createRoute(s.Context, s.Client, s.AppName, s.Image, s.RoutePath,
newRouteType, s.Format, s.RouteConfig, s.RouteHeaders)
if err == nil {
t.Errorf("Route duplicate error should appear, but it didn't")
}