From b04a57eb0974389df62aadeaf7f0a4e2ea1ce0bd Mon Sep 17 00:00:00 2001 From: buyuxiang <347586493@qq.com> Date: Tue, 1 Mar 2022 18:05:13 +0800 Subject: [PATCH] fix: change Validators type, check json body format --- convert.go | 13 +++++++------ internal/har2case/core.go | 2 +- internal/har2case/core_test.go | 7 ++++--- models.go | 23 +++++++++++------------ response.go | 8 ++++++-- runner.go | 9 +++++++++ step_test.go | 4 ++-- 7 files changed, 40 insertions(+), 26 deletions(-) diff --git a/convert.go b/convert.go index 2efc28c3..6800d3fd 100644 --- a/convert.go +++ b/convert.go @@ -67,9 +67,10 @@ func convertCompatTestCase(tc *TCase) (err error) { } }() for _, step := range tc.TestSteps { - // 1. deal with body compatible with HttpRunner + // 1. deal with request body compatible with HttpRunner if step.Request != nil && step.Request.Body == nil { if step.Request.Json != nil { + step.Request.Headers["Content-Type"] = "application/json; charset=utf-8" step.Request.Body = step.Request.Json } else if step.Request.Data != nil { step.Request.Body = step.Request.Data @@ -77,9 +78,9 @@ func convertCompatTestCase(tc *TCase) (err error) { } // 2. deal with validators compatible with HttpRunner - for _, iValidator := range step.ValidatorsCompat { - validatorMap, ok := iValidator.(map[string]interface{}) - if !ok || len(validatorMap) == 0 { + for i, iValidator := range step.Validators { + validatorMap := iValidator.(map[string]interface{}) + if len(validatorMap) == 0 { // pass invalid or empty validator continue } @@ -94,7 +95,7 @@ func convertCompatTestCase(tc *TCase) (err error) { validator.Message = msg.(string) } convertCompatHeader(&validator) - step.Validators = append(step.Validators, validator) + step.Validators[i] = validator } else if len(validatorMap) == 1 { // HttpRunner validator format for assertMethod, iValidatorContent := range validatorMap { @@ -104,7 +105,7 @@ func convertCompatTestCase(tc *TCase) (err error) { validator.Expect = checkAndExpect[1] } convertCompatHeader(&validator) - step.Validators = append(step.Validators, validator) + step.Validators[i] = validator } else { log.Error().Msgf("[convert compat testcase] unexpected validator format: %v", validatorMap) } diff --git a/internal/har2case/core.go b/internal/har2case/core.go index ed2ce221..b22ba0a0 100644 --- a/internal/har2case/core.go +++ b/internal/har2case/core.go @@ -145,7 +145,7 @@ func (h *har) prepareTestStep(entry *Entry) (*hrp.TStep, error) { step := &tStep{ TStep: hrp.TStep{ Request: &hrp.Request{}, - Validators: make([]hrp.Validator, 0), + Validators: make([]interface{}, 0), }, } if err := step.makeRequestMethod(entry); err != nil { diff --git a/internal/har2case/core_test.go b/internal/har2case/core_test.go index 96b0c232..9060893f 100644 --- a/internal/har2case/core_test.go +++ b/internal/har2case/core_test.go @@ -1,6 +1,7 @@ package har2case import ( + "github.com/httprunner/hrp" "testing" "github.com/stretchr/testify/assert" @@ -98,13 +99,13 @@ func TestMakeTestCase(t *testing.T) { } // make validators - if !assert.Equal(t, "status_code", tCase.TestSteps[0].Validators[0].Check) { + if validator, ok := tCase.TestSteps[0].Validators[0].(hrp.Validator); !ok || !assert.Equal(t, "status_code", validator.Check) { t.Fail() } - if !assert.Equal(t, "headers.\"Content-Type\"", tCase.TestSteps[0].Validators[1].Check) { + if validator, ok := tCase.TestSteps[0].Validators[1].(hrp.Validator); !ok || !assert.Equal(t, "headers.\"Content-Type\"", validator.Check) { t.Fail() } - if !assert.Equal(t, "body.url", tCase.TestSteps[0].Validators[2].Check) { + if validator, ok := tCase.TestSteps[0].Validators[2].(hrp.Validator); !ok || !assert.Equal(t, "body.url", validator.Check) { t.Fail() } } diff --git a/models.go b/models.go index 050e2600..9b524c1e 100644 --- a/models.go +++ b/models.go @@ -115,18 +115,17 @@ type Validator struct { // TStep represents teststep data structure. // Each step maybe two different type: make one HTTP request or reference another testcase. type TStep struct { - Name string `json:"name" yaml:"name"` // required - Request *Request `json:"request,omitempty" yaml:"request,omitempty"` - TestCase *TestCase `json:"testcase,omitempty" yaml:"testcase,omitempty"` - Transaction *Transaction `json:"transaction,omitempty" yaml:"transaction,omitempty"` - Rendezvous *Rendezvous `json:"rendezvous,omitempty" yaml:"rendezvous,omitempty"` - Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"` - SetupHooks []string `json:"setup_hooks,omitempty" yaml:"setup_hooks,omitempty"` - TeardownHooks []string `json:"teardown_hooks,omitempty" yaml:"teardown_hooks,omitempty"` - Extract map[string]string `json:"extract,omitempty" yaml:"extract,omitempty"` - ValidatorsCompat []interface{} `json:"validate,omitempty" yaml:"validate,omitempty"` - Export []string `json:"export,omitempty" yaml:"export,omitempty"` - Validators []Validator + Name string `json:"name" yaml:"name"` // required + Request *Request `json:"request,omitempty" yaml:"request,omitempty"` + TestCase *TestCase `json:"testcase,omitempty" yaml:"testcase,omitempty"` + Transaction *Transaction `json:"transaction,omitempty" yaml:"transaction,omitempty"` + Rendezvous *Rendezvous `json:"rendezvous,omitempty" yaml:"rendezvous,omitempty"` + Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"` + SetupHooks []string `json:"setup_hooks,omitempty" yaml:"setup_hooks,omitempty"` + TeardownHooks []string `json:"teardown_hooks,omitempty" yaml:"teardown_hooks,omitempty"` + Extract map[string]string `json:"extract,omitempty" yaml:"extract,omitempty"` + Validators []interface{} `json:"validate,omitempty" yaml:"validate,omitempty"` + Export []string `json:"export,omitempty" yaml:"export,omitempty"` } type stepType string diff --git a/response.go b/response.go index e4eecd8d..1085c382 100644 --- a/response.go +++ b/response.go @@ -114,8 +114,12 @@ func (v *responseObject) Extract(extractors map[string]string) map[string]interf return extractMapping } -func (v *responseObject) Validate(validators []Validator, variablesMapping map[string]interface{}) (err error) { - for _, validator := range validators { +func (v *responseObject) Validate(iValidators []interface{}, variablesMapping map[string]interface{}) (err error) { + for _, iValidator := range iValidators { + validator, ok := iValidator.(Validator) + if !ok { + return errors.New("validator type error") + } // parse check value checkItem := validator.Check var checkValue interface{} diff --git a/runner.go b/runner.go index 7dd0178b..75a15ee5 100644 --- a/runner.go +++ b/runner.go @@ -703,6 +703,15 @@ func (r *caseRunner) runStepRequest(step *TStep) (stepResult *stepData, err erro if err != nil { return stepResult, err } + // check request body format if Content-Type specified as application/json + if strings.HasPrefix(req.Header.Get("Content-Type"), "application/json") { + switch data.(type) { + case bool, float64, string, map[string]interface{}, []interface{}, nil: + break + default: + return stepResult, errors.Errorf("request body type inconsistent with Content-Type: %v", req.Header.Get("Content-Type")) + } + } requestMap["body"] = data var dataBytes []byte switch vv := data.(type) { diff --git a/step_test.go b/step_test.go index f180983f..1610cd29 100644 --- a/step_test.go +++ b/step_test.go @@ -42,7 +42,7 @@ func TestRunRequestGetToStruct(t *testing.T) { if tStep.Request.Cookies["user"] != "debugtalk" { t.Fatalf("tStep.Request.Cookies mismatch") } - if tStep.Validators[0].Check != "status_code" || tStep.Validators[0].Expect != 200 { + if validator, ok := tStep.Validators[0].(Validator); !ok || validator.Check != "status_code" || validator.Expect != 200 { t.Fatalf("tStep.Validators mismatch") } } @@ -67,7 +67,7 @@ func TestRunRequestPostDataToStruct(t *testing.T) { if tStep.Request.Body != "a=1&b=2" { t.Fatalf("tStep.Request.Data mismatch") } - if tStep.Validators[0].Check != "status_code" || tStep.Validators[0].Expect != 200 { + if validator, ok := tStep.Validators[0].(Validator); !ok || validator.Check != "status_code" || validator.Expect != 200 { t.Fatalf("tStep.Validators mismatch") } }