Skip to content

Commit

Permalink
improve the function RunTestCase
Browse files Browse the repository at this point in the history
  • Loading branch information
LinuxSuRen committed Apr 18, 2023
1 parent dc0adbf commit 4f72b44
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 36 deletions.
36 changes: 2 additions & 34 deletions pkg/runner/simple.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
package runner

import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/url"
"os"
"reflect"
"strings"
"time"
Expand Down Expand Up @@ -202,40 +198,14 @@ func (r *simpleTestCaseRunner) RunTestCase(testcase *testing.TestCase, dataConte
}

var requestBody io.Reader
if testcase.Request.Body != "" {
requestBody = bytes.NewBufferString(testcase.Request.Body)
} else if testcase.Request.BodyFromFile != "" {
var data []byte
if data, err = os.ReadFile(testcase.Request.BodyFromFile); err != nil {
return
}
requestBody = bytes.NewBufferString(string(data))
if requestBody, err = testcase.Request.GetBody(); err != nil {
return
}

if err = testcase.Request.Render(dataContext); err != nil {
return
}

if len(testcase.Request.Form) > 0 {
if testcase.Request.Header[contentType] == "multipart/form-data" {
multiBody := &bytes.Buffer{}
writer := multipart.NewWriter(multiBody)
for key, val := range testcase.Request.Form {
writer.WriteField(key, val)
}

_ = writer.Close()
requestBody = multiBody
testcase.Request.Header[contentType] = writer.FormDataContentType()
} else if testcase.Request.Header[contentType] == "application/x-www-form-urlencoded" {
data := url.Values{}
for key, val := range testcase.Request.Form {
data.Set(key, val)
}
requestBody = strings.NewReader(data.Encode())
}
}

var request *http.Request
if request, err = http.NewRequestWithContext(ctx, testcase.Request.Method, testcase.Request.API, requestBody); err != nil {
return
Expand Down Expand Up @@ -436,5 +406,3 @@ func jsonSchemaValidation(schema string, body []byte) (err error) {
}
return
}

const contentType = "Content-Type"
5 changes: 3 additions & 2 deletions pkg/runner/simple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/h2non/gock"
atest "github.com/linuxsuren/api-testing/pkg/testing"
"github.com/linuxsuren/api-testing/pkg/util"
fakeruntime "github.com/linuxsuren/go-fake-runtime"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -300,7 +301,7 @@ func TestTestCase(t *testing.T) {
API: urlFoo,
Method: http.MethodPost,
Header: map[string]string{
contentType: "multipart/form-data",
util.ContentType: "multipart/form-data",
},
Form: map[string]string{
"key": "value",
Expand All @@ -319,7 +320,7 @@ func TestTestCase(t *testing.T) {
API: urlFoo,
Method: http.MethodPost,
Header: map[string]string{
contentType: "application/x-www-form-urlencoded",
util.ContentType: "application/x-www-form-urlencoded",
},
Form: map[string]string{
"key": "value",
Expand Down
36 changes: 36 additions & 0 deletions pkg/testing/parser.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package testing

import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/url"
"os"
"strings"

"github.com/linuxsuren/api-testing/pkg/render"
"github.com/linuxsuren/api-testing/pkg/util"
"gopkg.in/yaml.v2"
)

Expand Down Expand Up @@ -83,6 +88,37 @@ func (r *Request) Render(ctx interface{}) (err error) {
return
}

// GetBody returns the request body
func (r *Request) GetBody() (reader io.Reader, err error) {
if len(r.Form) > 0 {
if r.Header[util.ContentType] == util.MultiPartFormData {
multiBody := &bytes.Buffer{}
writer := multipart.NewWriter(multiBody)
for key, val := range r.Form {
writer.WriteField(key, val)
}

_ = writer.Close()
reader = multiBody
r.Header[util.ContentType] = writer.FormDataContentType()
} else if r.Header[util.ContentType] == util.Form {
data := url.Values{}
for key, val := range r.Form {
data.Set(key, val)
}
reader = strings.NewReader(data.Encode())
}
} else if r.Body != "" {
reader = bytes.NewBufferString(r.Body)
} else if r.BodyFromFile != "" {
var data []byte
if data, err = os.ReadFile(r.BodyFromFile); err == nil {
reader = bytes.NewBufferString(string(data))
}
}
return
}

// Render renders the response
func (r *Response) Render(ctx interface{}) (err error) {
r.StatusCode = zeroThenDefault(r.StatusCode, http.StatusOK)
Expand Down
61 changes: 61 additions & 0 deletions pkg/testing/parser_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package testing

import (
"io"
"net/http"
"testing"

_ "embed"

"github.com/linuxsuren/api-testing/pkg/util"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -212,5 +214,64 @@ func TestTestCase(t *testing.T) {
}, testCase)
}

func TestGetBody(t *testing.T) {
defaultBody := "fake body"

tests := []struct {
name string
req *Request
expectBody string
containBody string
expectErr bool
}{{
name: "normal body",
req: &Request{Body: defaultBody},
expectBody: defaultBody,
}, {
name: "body from file",
req: &Request{BodyFromFile: "testdata/testcase.yaml"},
expectBody: testCaseContent,
}, {
name: "multipart form data",
req: &Request{
Header: map[string]string{
util.ContentType: util.MultiPartFormData,
},
Form: map[string]string{
"key": "value",
},
},
containBody: "name=\"key\"\r\n\r\nvalue\r\n",
}, {
name: "normal form",
req: &Request{
Header: map[string]string{
util.ContentType: util.Form,
},
Form: map[string]string{
"name": "linuxsuren",
},
},
expectBody: "name=linuxsuren",
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
reader, err := tt.req.GetBody()
if tt.expectErr {
assert.NotNil(t, err)
} else {
assert.NotNil(t, reader)
data, err := io.ReadAll(reader)
assert.Nil(t, err)
if tt.expectBody != "" {
assert.Equal(t, tt.expectBody, string(data))
} else {
assert.Contains(t, string(data), tt.containBody)
}
}
})
}
}

//go:embed testdata/testcase.yaml
var testCaseContent string
7 changes: 7 additions & 0 deletions pkg/util/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ func MakeSureNotNil[T any](inter T) T {
}
return inter
}

// ContentType is the HTTP header key
const (
ContentType = "Content-Type"
MultiPartFormData = "multipart/form-data"
Form = "application/x-www-form-urlencoded"
)

0 comments on commit 4f72b44

Please sign in to comment.