Skip to content

Commit 317c4d6

Browse files
committed
feat: support to upload random image files
1 parent eff5292 commit 317c4d6

File tree

14 files changed

+212
-70
lines changed

14 files changed

+212
-70
lines changed

cmd/extension.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func createExtensionCommand(ociDownloader downloader.PlatformAwareOCIDownloader)
5656
flags.StringVarP(&opt.os, "os", "", runtime.GOOS, "The OS")
5757
flags.StringVarP(&opt.arch, "arch", "", runtime.GOARCH, "The architecture")
5858
flags.DurationVarP(&opt.timeout, "timeout", "", time.Minute, "The timeout of downloading")
59-
flags.StringVarP(&opt.imagePrefix, "image-prefix", "", "linuxsuren", "The prefix for the image address")
59+
flags.StringVarP(&opt.imagePrefix, "image-prefix", "", "linuxsuren", "The prefix for the image address")
6060
return
6161
}
6262

console/atest-ui/src/views/TestCase.vue

Lines changed: 80 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -867,44 +867,53 @@ Magic.Keys(() => {
867867
<el-button type="primary" v-if="!isHistoryTestCase && Cache.GetCurrentStore().kind.name == 'atest-store-orm'" @click="openHistoryDialog">{{ t('button.viewHistory') }}</el-button>
868868
<span v-if="isHistoryTestCase" style="margin-left: 15px;">{{ t('tip.runningAt') }}{{ HistoryTestCaseCreateTime }}</span>
869869
</div>
870-
<div style="display: flex;">
871-
<el-select
872-
v-if="props.kindName !== 'tRPC' && props.kindName !== 'gRPC'"
873-
v-model="testCaseWithSuite.data.request.method"
874-
class="m-2"
875-
placeholder="Method"
876-
size="default"
877-
test-id="case-editor-method"
878-
:disabled="isHistoryTestCase"
879-
>
880-
<el-option
881-
v-for="item in options"
882-
:key="item.value"
883-
:label="item.key"
884-
:value="item.value"
885-
/>
886-
</el-select>
887-
<el-autocomplete
888-
v-model="testCaseWithSuite.data.request.api"
889-
:fetch-suggestions="querySuggestedAPIs"
890-
placeholder="API Address"
891-
style="width: 50%; margin-left: 5px; margin-right: 5px; flex-grow: 1;"
892-
:readonly="isHistoryTestCase"
893-
>
894-
<template #default="{ item }">
895-
<div class="value">{{ item.request.method }}</div>
896-
<span class="link">{{ item.request.api }}</span>
897-
</template>
898-
</el-autocomplete>
899-
900-
<el-dropdown split-button type="primary" @click="sendRequest" v-loading="requestLoading" v-if="!isHistoryTestCase">
901-
{{ t('button.send') }}
902-
<template #dropdown>
903-
<el-dropdown-menu>
904-
<el-dropdown-item @click="openParameterDialog">{{ t('button.sendWithParam') }}</el-dropdown-item>
905-
</el-dropdown-menu>
906-
</template>
907-
</el-dropdown>
870+
<div>
871+
<el-row>
872+
<el-col :span="3">
873+
<el-select
874+
v-if="props.kindName !== 'tRPC' && props.kindName !== 'gRPC'"
875+
v-model="testCaseWithSuite.data.request.method"
876+
class="m-2"
877+
placeholder="Method"
878+
size="default"
879+
test-id="case-editor-method"
880+
:disabled="isHistoryTestCase"
881+
>
882+
<el-option
883+
v-for="item in options"
884+
:key="item.value"
885+
:label="item.key"
886+
:value="item.value"
887+
/>
888+
</el-select>
889+
</el-col>
890+
<el-col :span="18">
891+
<el-autocomplete
892+
v-model="testCaseWithSuite.data.request.api"
893+
style="width: 100%"
894+
:fetch-suggestions="querySuggestedAPIs"
895+
placeholder="API Address"
896+
:readonly="isHistoryTestCase">
897+
<template #default="{ item }">
898+
<div class="value">{{ item.request.method }}</div>
899+
<span class="link">{{ item.request.api }}</span>
900+
</template>
901+
</el-autocomplete>
902+
</el-col>
903+
<el-col :span="3">
904+
<el-dropdown split-button type="primary"
905+
@click="sendRequest"
906+
v-loading="requestLoading"
907+
v-if="!isHistoryTestCase">
908+
{{ t('button.send') }}
909+
<template #dropdown>
910+
<el-dropdown-menu>
911+
<el-dropdown-item @click="openParameterDialog">{{ t('button.sendWithParam') }}</el-dropdown-item>
912+
</el-dropdown-menu>
913+
</template>
914+
</el-dropdown>
915+
</el-col>
916+
</el-row>
908917
</div>
909918
</el-header>
910919

@@ -1013,7 +1022,12 @@ Magic.Keys(() => {
10131022

10141023
<div style="flex-grow: 1;">
10151024
<div v-if="bodyType === 6">
1016-
Filename: <el-input v-model="testCaseWithSuite.data.request.filepath" placeholder="file=sample.txt" />
1025+
<el-row>
1026+
<el-col :span="4">Filename:</el-col>
1027+
<el-col :span="20">
1028+
<el-input v-model="testCaseWithSuite.data.request.filepath" placeholder="file=sample.txt" />
1029+
</el-col>
1030+
</el-row>
10171031
</div>
10181032
<Codemirror v-if="bodyType === 3 || bodyType === 5 || bodyType === 6"
10191033
@blur="jsonFormat(-1)"
@@ -1040,27 +1054,34 @@ Magic.Keys(() => {
10401054
</el-tab-pane>
10411055

10421056
<el-tab-pane label="Expected" name="expected" v-if="props.kindName !== 'tRPC' && props.kindName !== 'gRPC'">
1043-
<el-row :gutter="20">
1044-
<span
1045-
class="ml-3 w-50 text-gray-600 inline-flex items-center"
1046-
style="margin-left: 15px; margin-right: 15px"
1047-
>Status Code:</span
1048-
>
1049-
<el-input
1050-
v-model="testCaseWithSuite.data.response.statusCode"
1051-
class="w-50 m-2"
1052-
placeholder="Please input"
1053-
style="width: 200px"
1054-
:readonly="isHistoryTestCase"
1055-
/>
1057+
<el-row>
1058+
<el-col :span="4">
1059+
Status Code:
1060+
</el-col>
1061+
<el-col :span="20">
1062+
<el-input
1063+
v-model="testCaseWithSuite.data.response.statusCode"
1064+
class="w-50 m-2"
1065+
placeholder="Please input"
1066+
:readonly="isHistoryTestCase">
1067+
<template #append>
1068+
{{ t('httpCode.' + testCaseWithSuite.data.response.statusCode) }}
1069+
</template>
1070+
</el-input>
1071+
</el-col>
1072+
</el-row>
1073+
<el-row>
1074+
<el-col :span="4">Body:</el-col>
1075+
<el-col :span="20">
1076+
<el-input
1077+
v-model="testCaseWithSuite.data.response.body"
1078+
:autosize="{ minRows: 4, maxRows: 8 }"
1079+
type="textarea"
1080+
placeholder="Expected Body"
1081+
:readonly="isHistoryTestCase"
1082+
/>
1083+
</el-col>
10561084
</el-row>
1057-
<el-input
1058-
v-model="testCaseWithSuite.data.response.body"
1059-
:autosize="{ minRows: 4, maxRows: 8 }"
1060-
type="textarea"
1061-
placeholder="Expected Body"
1062-
:readonly="isHistoryTestCase"
1063-
/>
10641085
</el-tab-pane>
10651086

10661087
<el-tab-pane label="Expected Headers" name="expected-headers" v-if="props.kindName !== 'tRPC' && props.kindName !== 'gRPC'">

pkg/generator/curl_generator_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func TestCurlGenerator(t *testing.T) {
6464
API: fooForTest,
6565
Header: map[string]string{
6666
util.ContentType: util.Plain,
67-
"Connection": "keep-alive",
67+
"Connection": "keep-alive",
6868
},
6969
},
7070
},

pkg/render/image.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
Copyright 2024 API Testing Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language 24 permissions and
14+
limitations under the License.
15+
*/
16+
package render
17+
18+
import (
19+
"bytes"
20+
"encoding/base64"
21+
"fmt"
22+
"image"
23+
"image/color"
24+
"image/png"
25+
"math"
26+
"math/rand"
27+
"time"
28+
29+
"github.com/linuxsuren/api-testing/pkg/util"
30+
)
31+
32+
func generateRandomImage(width, height int) (data string, err error) {
33+
img := image.NewRGBA(image.Rect(0, 0, width, height))
34+
blockSize := int(math.Max(float64(width), float64(height)) / 4)
35+
rand.Seed(time.Now().UnixNano())
36+
37+
for y := 0; y < height; y += blockSize {
38+
for x := 0; x < width; x += blockSize {
39+
r := uint8(rand.Intn(255))
40+
g := uint8(rand.Intn(255))
41+
b := uint8(rand.Intn(255))
42+
col := color.RGBA{R: r, G: g, B: b, A: 255}
43+
44+
for iy := y; iy < y+blockSize && iy < height; iy++ {
45+
for ix := x; ix < x+blockSize && ix < width; ix++ {
46+
img.Set(ix, iy, col)
47+
}
48+
}
49+
}
50+
}
51+
52+
buf := new(bytes.Buffer)
53+
if err = png.Encode(buf, img); err == nil {
54+
data = fmt.Sprintf("%s%s", util.ImageBase64Prefix, base64.StdEncoding.EncodeToString(buf.Bytes()))
55+
}
56+
return
57+
}

pkg/render/pdf.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
Copyright 2024 API Testing Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language 24 permissions and
14+
limitations under the License.
15+
*/
16+
package render
17+
18+
func generateRandomPdf() (data []byte, err error) {
19+
return
20+
}

pkg/render/template.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ import (
2525
"encoding/hex"
2626
"encoding/json"
2727
"fmt"
28-
"html/template"
2928
"io"
3029
mathrand "math/rand"
3130
"strings"
31+
"text/template"
3232

3333
"crypto/rsa"
3434
"crypto/x509"
@@ -92,6 +92,8 @@ func FuncMap() template.FuncMap {
9292
funcs[item.FuncName] = item.Func
9393
}
9494
funcs["rasEncryptWithPublicKey"] = rasEncryptWithPublicKey
95+
funcs["randImage"] = generateRandomImage
96+
funcs["randPdf"] = generateRandomPdf
9597
return funcs
9698
}
9799

pkg/server/convert.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ package server
1818
import (
1919
"strings"
2020

21-
"google.golang.org/protobuf/types/known/timestamppb"
2221
"github.com/linuxsuren/api-testing/pkg/testing"
2322
"github.com/linuxsuren/api-testing/pkg/util"
23+
"google.golang.org/protobuf/types/known/timestamppb"
2424
)
2525

2626
// ToGRPCStore convert the normal store to GRPC store

pkg/testing/case.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@ limitations under the License.
1616
package testing
1717

1818
import (
19+
"encoding/base64"
1920
"encoding/json"
21+
"log"
2022
"sort"
23+
"strings"
2124
"time"
2225

26+
"github.com/linuxsuren/api-testing/pkg/util"
2327
"gopkg.in/yaml.v3"
2428
)
2529

@@ -175,6 +179,23 @@ func (e RequestBody) String() string {
175179
return e.Value
176180
}
177181

182+
func (e RequestBody) IsEmpty() bool {
183+
return e.Value == ""
184+
}
185+
186+
func (e RequestBody) Bytes() []byte {
187+
if strings.HasPrefix(e.Value, util.ImageBase64Prefix) {
188+
rawStr := strings.TrimPrefix(e.Value, util.ImageBase64Prefix)
189+
if data, err := base64.StdEncoding.DecodeString(rawStr); err == nil {
190+
return data
191+
} else {
192+
log.Printf("Error decoding: %v", err)
193+
return nil
194+
}
195+
}
196+
return []byte(e.Value)
197+
}
198+
178199
type GraphQLRequestBody struct {
179200
Query string `yaml:"query" json:"query"`
180201
OperationName string `yaml:"operationName" json:"operationName"`

pkg/testing/case_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,5 @@ func TestSortedKeysStringMap(t *testing.T) {
8383
assert.Equal(t, "e", obj.GetValue("e"))
8484
assert.Equal(t, "f", obj.GetValue("f"))
8585
assert.Equal(t, "f", obj.GetVerifier("f").Value)
86-
assert.Empty(t,obj.GetValue("not-found"))
86+
assert.Empty(t, obj.GetValue("not-found"))
8787
}

pkg/testing/loader_file.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ func (l *fileLoader) DeleteTestCase(suiteName, testcase string) (err error) {
429429
return
430430
}
431431

432-
func (l *fileLoader) CreateHistoryTestCase(testcaseResult TestCaseResult, suiteName *TestSuite, historyHeader map[string]string ) (err error) { // always be okay
432+
func (l *fileLoader) CreateHistoryTestCase(testcaseResult TestCaseResult, suiteName *TestSuite, historyHeader map[string]string) (err error) { // always be okay
433433
return
434434
}
435435

0 commit comments

Comments
 (0)