Skip to content

Commit 0ab99b5

Browse files
committed
Automated test cycle task display tag and automatic expansion configuration items
1 parent 33b036e commit 0ab99b5

File tree

7 files changed

+171
-4
lines changed

7 files changed

+171
-4
lines changed

apistructs/permission.go

+7
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,13 @@ type PermissionList struct {
173173

174174
// 无权限(access=false)时,该字段返回联系人 ID 列表,例如无应用权限时,返回应用管理员列表
175175
ContactsWhenNoPermission []string `json:"contactsWhenNoPermission,omitempty"`
176+
177+
ScopeInfo ScopeInfo `json:"scopeInfo"`
178+
}
179+
180+
type ScopeInfo struct {
181+
ProjectName string `json:"projectName"`
182+
AppName string `json:"appName"`
176183
}
177184

178185
// PermissionListResponse 权限列表响应信息

apistructs/pipeline_task.go

+26
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,32 @@ type PipelineTaskLoop struct {
151151
Strategy *LoopStrategy `json:"strategy,omitempty" yaml:"strategy,omitempty"`
152152
}
153153

154+
func (l *PipelineTaskLoop) IsEmpty() bool {
155+
if l == nil {
156+
return true
157+
}
158+
if l.Break != "" {
159+
return false
160+
}
161+
162+
if l.Strategy != nil {
163+
if l.Strategy.DeclineLimitSec > 0 {
164+
return false
165+
}
166+
if l.Strategy.DeclineRatio > 0 {
167+
return false
168+
}
169+
if l.Strategy.IntervalSec > 0 {
170+
return false
171+
}
172+
if l.Strategy.MaxTimes > 0 {
173+
return false
174+
}
175+
}
176+
177+
return true
178+
}
179+
154180
type PipelineTaskErrResponse struct {
155181
Code string `json:"code"`
156182
Msg string `json:"msg"`

apistructs/pipeline_task_test.go

+72
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,75 @@ func TestConvertErrors(t *testing.T) {
5959
task.Result.ConvertErrors()
6060
assert.Equal(t, fmt.Sprintf("err\nstartTime: %s\nendTime: %s\ncount: %d", start.Format("2006-01-02 15:04:05"), end.Format("2006-01-02 15:04:05"), 2), task.Result.Errors[0].Msg)
6161
}
62+
63+
func TestPipelineTaskLoop_IsEmpty(t *testing.T) {
64+
type fields struct {
65+
Break string
66+
Strategy *LoopStrategy
67+
}
68+
tests := []struct {
69+
name string
70+
fields fields
71+
want bool
72+
}{
73+
{
74+
name: "test_break",
75+
fields: fields{
76+
Break: "test",
77+
},
78+
want: false,
79+
},
80+
{
81+
name: "test_DeclineLimitSec",
82+
fields: fields{
83+
Strategy: &LoopStrategy{
84+
DeclineLimitSec: 1,
85+
},
86+
},
87+
want: false,
88+
},
89+
{
90+
name: "test_DeclineRatio",
91+
fields: fields{
92+
Strategy: &LoopStrategy{
93+
DeclineLimitSec: 1,
94+
},
95+
},
96+
want: false,
97+
},
98+
{
99+
name: "test_IntervalSec",
100+
fields: fields{
101+
Strategy: &LoopStrategy{
102+
DeclineLimitSec: 1,
103+
},
104+
},
105+
want: false,
106+
},
107+
{
108+
name: "test_MaxTimes",
109+
fields: fields{
110+
Strategy: &LoopStrategy{
111+
DeclineLimitSec: 1,
112+
},
113+
},
114+
want: false,
115+
},
116+
{
117+
name: "test_MaxTimes",
118+
fields: fields{},
119+
want: true,
120+
},
121+
}
122+
for _, tt := range tests {
123+
t.Run(tt.name, func(t *testing.T) {
124+
l := &PipelineTaskLoop{
125+
Break: tt.fields.Break,
126+
Strategy: tt.fields.Strategy,
127+
}
128+
if got := l.IsEmpty(); got != tt.want {
129+
t.Errorf("IsEmpty() = %v, want %v", got, tt.want)
130+
}
131+
})
132+
}
133+
}

modules/openapi/component-protocol/scenarios/auto-test-scenes/components/apiEditor/helper.go

+38-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package apiEditor
1616

1717
import (
1818
"encoding/json"
19+
"strings"
1920

2021
"github.com/sirupsen/logrus"
2122

@@ -24,13 +25,13 @@ import (
2425
"github.com/erda-project/erda/pkg/expression"
2526
)
2627

27-
const props1 string = `{
28+
var props1 = `{
2829
"loopFormField":[
2930
{
3031
"component":"formGroup",
3132
"key":"loop",
3233
"componentProps":{
33-
"defaultExpand":false,
34+
"defaultExpand": ` + LoopFormFieldDefaultExpand.string() + `,
3435
"expandable":true,
3536
"title":"循环策略"
3637
},
@@ -335,9 +336,42 @@ const props3 string = `}
335336
//}
336337
const props4 string = `}`
337338

338-
func genProps(input, execute string) interface{} {
339+
type optionKey string
340+
341+
// placeholder for whether the loop strategy is expanded by default
342+
const LoopFormFieldDefaultExpand = optionKey("defaultExpand")
343+
344+
func (opt optionKey) string() string {
345+
return "{{_" + string(opt) + "_}}"
346+
}
347+
348+
type replaceOption struct {
349+
key optionKey
350+
value string
351+
}
352+
353+
var defaultReplaceOptions = []replaceOption{
354+
{
355+
key: LoopFormFieldDefaultExpand,
356+
value: "false",
357+
},
358+
}
359+
360+
func genProps(input, execute string, replaceOpts ...replaceOption) interface{} {
361+
// because props are assembled by splicing json strings,
362+
// dynamic setting values can only be replaced by placeholders.
363+
var propsJson = props1 + input + props2 + input + props3 + execute + props4
364+
365+
for _, opt := range replaceOpts {
366+
propsJson = strings.ReplaceAll(propsJson, opt.key.string(), opt.value)
367+
}
368+
369+
for _, opt := range defaultReplaceOptions {
370+
propsJson = strings.ReplaceAll(propsJson, opt.key.string(), opt.value)
371+
}
372+
339373
var propsI interface{}
340-
if err := json.Unmarshal([]byte(props1+input+props2+input+props3+execute+props4), &propsI); err != nil {
374+
if err := json.Unmarshal([]byte(propsJson), &propsI); err != nil {
341375
logrus.Errorf("init props name=testplan component=formModal propsType=CreateTestPlan err: errMsg: %v", err)
342376
}
343377

modules/openapi/component-protocol/scenarios/auto-test-scenes/components/apiEditor/render.go

+11
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,17 @@ LABEL:
365365
if err := json.Unmarshal([]byte(sceneStep.Value), &apiInfo); err != nil {
366366
return err
367367
}
368+
369+
// replace placeholders in props
370+
var opts []replaceOption
371+
if !apiInfo.Loop.IsEmpty() {
372+
opts = append(opts, replaceOption{
373+
key: LoopFormFieldDefaultExpand,
374+
value: "true",
375+
})
376+
}
377+
c.Props = genProps(string(inputBytes), executeString, opts...)
378+
368379
apiInfo.APIInfo.Name = sceneStep.Name
369380
c.State["data"] = map[string]interface{}{"apiSpec": apiInfo.APIInfo, "apiSpecId": sceneStep.APISpecID, "loop": apiInfo.Loop}
370381
return nil

modules/openapi/component-protocol/scenarios/auto-test-scenes/components/stages/model.go

+6
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,18 @@ type Data struct {
4141
Type string `json:"type"`
4242
}
4343

44+
type Tag struct {
45+
Label string `json:"label"`
46+
Color string `json:"color"`
47+
}
48+
4449
type StageData struct {
4550
Title string `json:"title"`
4651
ID uint64 `json:"id"`
4752
GroupID int64 `json:"groupId"`
4853
Disabled bool `json:"disabled"`
4954
Operations map[string]interface{} `json:"operations"`
55+
Tags []Tag `json:"tags"`
5056
}
5157

5258
type InParams struct {

modules/openapi/component-protocol/scenarios/auto-test-scenes/components/stages/stages.go

+11
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"strconv"
2020

2121
"github.com/erda-project/erda/apistructs"
22+
st "github.com/erda-project/erda/modules/openapi/component-protocol/pkg/autotest/step"
2223
)
2324

2425
type MU struct {
@@ -116,6 +117,16 @@ func RenderStage(groupID uint64, step apistructs.AutoTestSceneStep) (StageData,
116117
o3.Meta.ID = step.ID
117118
o3.CopyText = step.ToJsonCopyText()
118119
pd.Operations["copyAsJson"] = o3
120+
121+
var apiInfo st.APISpec
122+
if err := json.Unmarshal([]byte(step.Value), &apiInfo); err == nil {
123+
if !apiInfo.Loop.IsEmpty() {
124+
pd.Tags = append(pd.Tags, Tag{
125+
Label: "循环步骤",
126+
Color: "blue",
127+
})
128+
}
129+
}
119130
}
120131

121132
os := OperationInfo{

0 commit comments

Comments
 (0)