feat: support to return the body string even it is invalid (#453)
Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
This commit is contained in:
parent
98b4dae698
commit
ce5ad55216
|
@ -5,6 +5,10 @@ on:
|
||||||
env:
|
env:
|
||||||
IMG_TOOL: docker
|
IMG_TOOL: docker
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Test:
|
Test:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
|
|
|
@ -5,11 +5,11 @@ on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- feat/mock-timer
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
qodana:
|
qodana:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: github.actor == 'linuxsuren'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -57,10 +57,7 @@ const sendRequest = async () => {
|
||||||
type: 'success'
|
type: 'success'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (e.body !== '') {
|
parseResponseBody(e.body)
|
||||||
testResult.value.bodyObject = JSON.parse(e.body)
|
|
||||||
testResult.value.originBodyObject = JSON.parse(e.body)
|
|
||||||
}
|
|
||||||
|
|
||||||
Cache.SetTestCaseResponseCache(suite + '-' + name, {
|
Cache.SetTestCaseResponseCache(suite + '-' + name, {
|
||||||
body: testResult.value.bodyObject,
|
body: testResult.value.bodyObject,
|
||||||
|
@ -74,11 +71,24 @@ const sendRequest = async () => {
|
||||||
|
|
||||||
requestLoading.value = false
|
requestLoading.value = false
|
||||||
UIAPI.ErrorTip(e)
|
UIAPI.ErrorTip(e)
|
||||||
testResult.value.bodyObject = JSON.parse(e.body)
|
|
||||||
testResult.value.originBodyObject = JSON.parse(e.body)
|
parseResponseBody(e.body)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const parseResponseBody = (body) => {
|
||||||
|
if (body === '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
testResult.value.bodyObject = JSON.parse(body)
|
||||||
|
testResult.value.originBodyObject = JSON.parse(body)
|
||||||
|
} catch {
|
||||||
|
testResult.value.bodyText = body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const responseBodyFilterText = ref('')
|
const responseBodyFilterText = ref('')
|
||||||
function responseBodyFilter() {
|
function responseBodyFilter() {
|
||||||
if (responseBodyFilterText.value === '') {
|
if (responseBodyFilterText.value === '') {
|
||||||
|
@ -803,9 +813,14 @@ const queryHeaderValues = (queryString: string, cb: (arg: any) => void) => {
|
||||||
<Codemirror v-model="testResult.output"/>
|
<Codemirror v-model="testResult.output"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="Body" name="body">
|
<el-tab-pane label="Body" name="body">
|
||||||
|
<div v-if="testResult.bodyObject">
|
||||||
<el-input :prefix-icon="Search" @change="responseBodyFilter" v-model="responseBodyFilterText"
|
<el-input :prefix-icon="Search" @change="responseBodyFilter" v-model="responseBodyFilterText"
|
||||||
clearable label="dddd" placeholder="$.key" />
|
clearable placeholder="$.key" />
|
||||||
<JsonViewer :value="testResult.bodyObject" :expand-depth="5" copyable boxed sort />
|
<JsonViewer :value="testResult.bodyObject" :expand-depth="2" copyable boxed sort />
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<Codemirror v-model="testResult.bodyText"/>
|
||||||
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane name="response-header">
|
<el-tab-pane name="response-header">
|
||||||
<template #label>
|
<template #label>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2023 API Testing Authors.
|
Copyright 2023-2024 API Testing Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -30,12 +30,13 @@ export interface Suite {
|
||||||
export interface TestResult {
|
export interface TestResult {
|
||||||
body: string
|
body: string
|
||||||
bodyObject: {}
|
bodyObject: {}
|
||||||
|
bodyText: string
|
||||||
output: string
|
output: string
|
||||||
error: string
|
error: string
|
||||||
statusCode: number
|
statusCode: number
|
||||||
header: Pair[]
|
header: Pair[]
|
||||||
|
|
||||||
// inner fileds
|
// inner fields
|
||||||
originBodyObject:{}
|
originBodyObject:{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -431,14 +431,13 @@ func (s *server) GetTestCase(ctx context.Context, in *TestCaseIdentity) (reply *
|
||||||
func (s *server) RunTestCase(ctx context.Context, in *TestCaseIdentity) (result *TestCaseResult, err error) {
|
func (s *server) RunTestCase(ctx context.Context, in *TestCaseIdentity) (result *TestCaseResult, err error) {
|
||||||
var targetTestSuite testing.TestSuite
|
var targetTestSuite testing.TestSuite
|
||||||
|
|
||||||
|
result = &TestCaseResult{}
|
||||||
loader := s.getLoader(ctx)
|
loader := s.getLoader(ctx)
|
||||||
defer loader.Close()
|
defer loader.Close()
|
||||||
targetTestSuite, err = loader.GetTestSuite(in.Suite, true)
|
targetTestSuite, err = loader.GetTestSuite(in.Suite, true)
|
||||||
if err != nil {
|
if err != nil || targetTestSuite.Name == "" {
|
||||||
err = nil
|
err = nil
|
||||||
result = &TestCaseResult{
|
result.Error = fmt.Sprintf("not found suite: %s", in.Suite)
|
||||||
Error: fmt.Sprintf("not found suite: %s", in.Suite),
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,9 +452,10 @@ func (s *server) RunTestCase(ctx context.Context, in *TestCaseIdentity) (result
|
||||||
}
|
}
|
||||||
|
|
||||||
var reply *TestResult
|
var reply *TestResult
|
||||||
|
var lastItem *TestCaseResult
|
||||||
if reply, err = s.Run(ctx, task); err == nil && len(reply.TestCaseResult) > 0 {
|
if reply, err = s.Run(ctx, task); err == nil && len(reply.TestCaseResult) > 0 {
|
||||||
lastIndex := len(reply.TestCaseResult) - 1
|
lastIndex := len(reply.TestCaseResult) - 1
|
||||||
lastItem := reply.TestCaseResult[lastIndex]
|
lastItem = reply.TestCaseResult[lastIndex]
|
||||||
|
|
||||||
if len(lastItem.Body) > GrpcMaxRecvMsgSize {
|
if len(lastItem.Body) > GrpcMaxRecvMsgSize {
|
||||||
e := "the HTTP response body exceeded the maximum message size limit received by the gRPC client"
|
e := "the HTTP response body exceeded the maximum message size limit received by the gRPC client"
|
||||||
|
@ -468,23 +468,18 @@ func (s *server) RunTestCase(ctx context.Context, in *TestCaseIdentity) (result
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result = &TestCaseResult{
|
|
||||||
Output: reply.Message,
|
|
||||||
Error: reply.Error,
|
|
||||||
Body: lastItem.Body,
|
|
||||||
Header: lastItem.Header,
|
|
||||||
StatusCode: lastItem.StatusCode,
|
|
||||||
}
|
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
result = &TestCaseResult{
|
result.Error = err.Error()
|
||||||
Error: err.Error(),
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
result = &TestCaseResult{
|
if reply != nil {
|
||||||
Output: reply.Message,
|
result.Output = reply.Message
|
||||||
Error: reply.Error,
|
result.Error = reply.Error
|
||||||
}
|
}
|
||||||
|
if lastItem != nil {
|
||||||
|
result.Body = lastItem.Body
|
||||||
|
result.Header = lastItem.Header
|
||||||
|
result.StatusCode = lastItem.StatusCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
|
@ -31,6 +31,7 @@ import (
|
||||||
|
|
||||||
"github.com/h2non/gock"
|
"github.com/h2non/gock"
|
||||||
atest "github.com/linuxsuren/api-testing/pkg/testing"
|
atest "github.com/linuxsuren/api-testing/pkg/testing"
|
||||||
|
"github.com/linuxsuren/api-testing/pkg/util"
|
||||||
"github.com/linuxsuren/api-testing/sample"
|
"github.com/linuxsuren/api-testing/sample"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
|
@ -127,22 +128,49 @@ func TestRemoteServer(t *testing.T) {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sampleBody = `{"message": "hello"}`
|
||||||
|
|
||||||
func TestRunTestCase(t *testing.T) {
|
func TestRunTestCase(t *testing.T) {
|
||||||
loader := atest.NewFileWriter("")
|
loader := atest.NewFileWriter("")
|
||||||
loader.Put("testdata/simple.yaml")
|
loader.Put("testdata/simple.yaml")
|
||||||
server := NewRemoteServer(loader, nil, nil, nil, "", 1024*1024*4)
|
server := NewRemoteServer(loader, nil, nil, nil, "", 1024*1024*4)
|
||||||
|
|
||||||
|
t.Run("json response", func(t *testing.T) {
|
||||||
defer gock.Clean()
|
defer gock.Clean()
|
||||||
gock.New(urlFoo).Get("/").MatchHeader("key", "value").
|
gock.New(urlFoo).Get("/").MatchHeader("key", "value").
|
||||||
Reply(http.StatusOK).
|
Reply(http.StatusOK).SetHeader(util.ContentType, util.JSON).
|
||||||
BodyString(`{"message": "hello"}`)
|
BodyString(sampleBody)
|
||||||
|
|
||||||
result, err := server.RunTestCase(context.TODO(), &TestCaseIdentity{
|
result, err := server.RunTestCase(context.TODO(), &TestCaseIdentity{
|
||||||
Suite: "simple",
|
Suite: "simple",
|
||||||
Testcase: "get",
|
Testcase: "get",
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, sampleBody, result.Body)
|
||||||
assert.Contains(t, result.Output, "start to run: 'get'\nstart to send request to http://foo\ntest case \"get\", status code: 200\n")
|
assert.Contains(t, result.Output, "start to run: 'get'\nstart to send request to http://foo\ntest case \"get\", status code: 200\n")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("text response", func(t *testing.T) {
|
||||||
|
defer gock.Clean()
|
||||||
|
gock.New(urlFoo).Get("/").MatchHeader("key", "value").
|
||||||
|
Reply(http.StatusOK).SetHeader(util.ContentType, util.Plain).
|
||||||
|
BodyString(sampleBody)
|
||||||
|
|
||||||
|
result, err := server.RunTestCase(context.TODO(), &TestCaseIdentity{
|
||||||
|
Suite: "simple",
|
||||||
|
Testcase: "get",
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, sampleBody, result.Body)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("not suite found", func(t *testing.T) {
|
||||||
|
result, err := server.RunTestCase(context.TODO(), &TestCaseIdentity{
|
||||||
|
Suite: "not-found",
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, result.Error)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFindParentTestCases(t *testing.T) {
|
func TestFindParentTestCases(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue