@@ -4,28 +4,61 @@ import (
44 "encoding/json"
55 "testing"
66
7+ "github.com/go-playground/validator/v10"
78 "github.com/langgenius/dify-plugin-daemon/pkg/entities/model_entities"
9+ "github.com/langgenius/dify-plugin-daemon/pkg/utils/parser"
810 "github.com/langgenius/dify-plugin-daemon/pkg/validators"
911)
1012
13+ func TestRequestStartPollingDoesNotRequireSuspensionFields (t * testing.T ) {
14+ payload := []byte (`{
15+ "provider": "volcengine",
16+ "model": "doubao-seedance-2-0-260128",
17+ "model_type": "llm",
18+ "credentials": {"ark_api_key": "test"}
19+ }` )
20+
21+ var request RequestStartPolling
22+ if err := json .Unmarshal (payload , & request ); err != nil {
23+ t .Fatalf ("unmarshal request: %v" , err )
24+ }
25+
26+ if err := validators .GlobalEntitiesValidator .Struct (request ); err != nil {
27+ t .Fatalf ("validate request: %v" , err )
28+ }
29+ }
30+
1131func TestRequestCheckPollingRequiresPluginState (t * testing.T ) {
1232 payload := []byte (`{
1333 "provider": "volcengine",
1434 "model": "doubao-seedance-2-0-260128",
1535 "model_type": "llm",
16- "credentials": {"ark_api_key": "test"},
17- "workflow_run_id": "wr-1",
18- "node_id": "llm-1"
36+ "credentials": {"ark_api_key": "test"}
1937 }` )
2038
2139 var request RequestCheckPolling
2240 if err := json .Unmarshal (payload , & request ); err != nil {
2341 t .Fatalf ("unmarshal request: %v" , err )
2442 }
2543
26- if err := validators .GlobalEntitiesValidator .Struct (request ); err == nil {
27- t .Fatal ("expected missing plugin_state validation error" )
44+ if err := validators .GlobalEntitiesValidator .Struct (request ); err != nil {
45+ validationErrors , ok := err .(validator.ValidationErrors )
46+ if ! ok {
47+ t .Fatalf ("unexpected validation error type: %T: %v" , err , err )
48+ }
49+ if len (validationErrors ) != 1 {
50+ t .Fatalf ("expected 1 validation error, got %d: %v" , len (validationErrors ), validationErrors )
51+ }
52+ validationError := validationErrors [0 ]
53+ if validationError .Field () != "PluginState" {
54+ t .Fatalf ("unexpected field: %s" , validationError .Field ())
55+ }
56+ if validationError .Tag () != "required" {
57+ t .Fatalf ("unexpected tag: %s" , validationError .Tag ())
58+ }
59+ return
2860 }
61+ t .Fatal ("expected missing plugin_state validation error" )
2962}
3063
3164func TestRequestCheckPollingRejectsEmptyPluginState (t * testing.T ) {
@@ -34,8 +67,6 @@ func TestRequestCheckPollingRejectsEmptyPluginState(t *testing.T) {
3467 "model": "doubao-seedance-2-0-260128",
3568 "model_type": "llm",
3669 "credentials": {"ark_api_key": "test"},
37- "workflow_run_id": "wr-1",
38- "node_id": "llm-1",
3970 "plugin_state": {}
4071 }` )
4172
@@ -44,9 +75,24 @@ func TestRequestCheckPollingRejectsEmptyPluginState(t *testing.T) {
4475 t .Fatalf ("unmarshal request: %v" , err )
4576 }
4677
47- if err := validators .GlobalEntitiesValidator .Struct (request ); err == nil {
48- t .Fatal ("expected empty plugin_state validation error" )
78+ if err := validators .GlobalEntitiesValidator .Struct (request ); err != nil {
79+ validationErrors , ok := err .(validator.ValidationErrors )
80+ if ! ok {
81+ t .Fatalf ("unexpected validation error type: %T: %v" , err , err )
82+ }
83+ if len (validationErrors ) != 1 {
84+ t .Fatalf ("expected 1 validation error, got %d: %v" , len (validationErrors ), validationErrors )
85+ }
86+ validationError := validationErrors [0 ]
87+ if validationError .Field () != "PluginState" {
88+ t .Fatalf ("unexpected field: %s" , validationError .Field ())
89+ }
90+ if validationError .Tag () != "min" {
91+ t .Fatalf ("unexpected tag: %s" , validationError .Tag ())
92+ }
93+ return
4994 }
95+ t .Fatal ("expected empty plugin_state validation error" )
5096}
5197
5298func TestRequestCheckPollingAcceptsPluginState (t * testing.T ) {
@@ -55,8 +101,6 @@ func TestRequestCheckPollingAcceptsPluginState(t *testing.T) {
55101 "model": "doubao-seedance-2-0-260128",
56102 "model_type": "llm",
57103 "credentials": {"ark_api_key": "test"},
58- "workflow_run_id": "wr-1",
59- "node_id": "llm-1",
60104 "plugin_state": {"task_id": "task-1"}
61105 }` )
62106
@@ -75,3 +119,84 @@ func TestRequestCheckPollingAcceptsPluginState(t *testing.T) {
75119 t .Fatalf ("unexpected plugin_state: %#v" , request .PluginState )
76120 }
77121}
122+
123+ func TestPollingRequestMapExcludesSuspensionFields (t * testing.T ) {
124+ startPolling := RequestStartPolling {
125+ RequestInvokeLLM : RequestInvokeLLM {
126+ BaseRequestInvokeModel : BaseRequestInvokeModel {
127+ Provider : "volcengine" ,
128+ Model : "doubao-seedance-2-0-260128" ,
129+ },
130+ Credentials : Credentials {
131+ Credentials : map [string ]any {"ark_api_key" : "test" },
132+ },
133+ InvokeLLMSchema : InvokeLLMSchema {
134+ Stream : true ,
135+ },
136+ ModelType : model_entities .MODEL_TYPE_LLM ,
137+ },
138+ }
139+
140+ assertPollingRequestMapShape (t , parser .StructToMap (startPolling ), false )
141+
142+ checkPolling := RequestCheckPolling {
143+ BaseRequestInvokeModel : BaseRequestInvokeModel {
144+ Provider : "volcengine" ,
145+ Model : "doubao-seedance-2-0-260128" ,
146+ },
147+ Credentials : Credentials {
148+ Credentials : map [string ]any {"ark_api_key" : "test" },
149+ },
150+ ModelType : model_entities .MODEL_TYPE_LLM ,
151+ PluginState : map [string ]any {"task_id" : "task-1" },
152+ }
153+
154+ assertPollingRequestMapShape (t , parser .StructToMap (checkPolling ), true )
155+ }
156+
157+ func assertPollingRequestMapShape (t * testing.T , result map [string ]any , expectPluginState bool ) {
158+ t .Helper ()
159+
160+ if _ , ok := result ["workflow_run_id" ]; ok {
161+ t .Fatal ("workflow_run_id should not be present in polling request map" )
162+ }
163+ if _ , ok := result ["node_id" ]; ok {
164+ t .Fatal ("node_id should not be present in polling request map" )
165+ }
166+
167+ if result ["provider" ] != "volcengine" {
168+ t .Fatalf ("provider should be volcengine, got %#v" , result ["provider" ])
169+ }
170+ if result ["model" ] != "doubao-seedance-2-0-260128" {
171+ t .Fatalf ("model should be present, got %#v" , result ["model" ])
172+ }
173+ if result ["model_type" ] != model_entities .MODEL_TYPE_LLM {
174+ t .Fatalf ("model_type should be llm, got %#v" , result ["model_type" ])
175+ }
176+
177+ credentials , ok := result ["credentials" ].(map [string ]any )
178+ if ! ok {
179+ t .Fatalf ("credentials should be a map, got %T" , result ["credentials" ])
180+ }
181+ if credentials ["ark_api_key" ] != "test" {
182+ t .Fatalf ("credentials should contain ark_api_key, got %#v" , credentials )
183+ }
184+
185+ if expectPluginState {
186+ pluginState , ok := result ["plugin_state" ].(map [string ]any )
187+ if ! ok {
188+ t .Fatalf ("plugin_state should be a map, got %T" , result ["plugin_state" ])
189+ }
190+ if pluginState ["task_id" ] != "task-1" {
191+ t .Fatalf ("plugin_state should contain task_id, got %#v" , pluginState )
192+ }
193+ return
194+ }
195+
196+ if _ , ok := result ["plugin_state" ]; ok {
197+ t .Fatal ("plugin_state should not be present in start polling request map" )
198+ }
199+ if stream , ok := result ["stream" ].(bool ); ! ok || ! stream {
200+ t .Fatalf ("stream should be true, got %#v" , result ["stream" ])
201+ }
202+ }
0 commit comments