definitions/apiconfig/util_test.go

170 lines
4.1 KiB
Go

package apiconfig
import (
"encoding/json"
"git.servflow.io/servflow/definitions/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"testing"
)
func TestProtoConfigToAPIConfig(t *testing.T) {
tests := []struct {
name string
input []*proto.WorkflowConfig
validate func(t *testing.T, result []*APIConfig)
}{
{
name: "empty input slice",
input: []*proto.WorkflowConfig{},
validate: func(t *testing.T, result []*APIConfig) {
assert.Empty(t, result)
},
},
{
name: "nil config should be skipped",
input: []*proto.WorkflowConfig{
nil,
},
validate: func(t *testing.T, result []*APIConfig) {
assert.Empty(t, result)
},
},
{
name: "inactive config should be skipped",
input: []*proto.WorkflowConfig{
{
Id: "test-id",
Status: proto.Status_INACTIVE,
},
},
validate: func(t *testing.T, result []*APIConfig) {
assert.Empty(t, result)
},
},
{
name: "empty ID should be skipped",
input: []*proto.WorkflowConfig{
{
Status: proto.Status_ACTIVE,
},
},
validate: func(t *testing.T, result []*APIConfig) {
assert.Empty(t, result)
},
},
{
name: "valid config should be converted",
input: []*proto.WorkflowConfig{
{
Id: "test-id",
Status: proto.Status_ACTIVE,
ListenPath: "/test",
Method: "POST",
Request: &proto.Request{
Next: "next-action",
ListenPath: "/test",
Method: "GET",
},
Actions: map[string]*proto.Action{
"action1": {
Type: "http",
Config: json.RawMessage(`{"url": "http://example.com"}`),
Next: "action2",
Fail: "error",
},
},
Mcp: &proto.MCPConfig{
Enabled: true,
Name: "test-tool",
Args: map[string]*proto.MCPArgConfig{
"arg1": {
Name: "arg1",
Type: "string",
},
},
Description: "test description",
Start: "start",
Result: "result",
},
Conditionals: map[string]*proto.Conditional{
"cond1": {
ValidPath: "valid",
InvalidPath: "invalid",
Expression: "response.code == 200",
},
},
Responses: map[string]*proto.Response{
"success": {
Code: 200,
Type: "json",
Template: []byte(`{"status": "ok"}`),
},
},
},
},
validate: func(t *testing.T, result []*APIConfig) {
require.Len(t, result, 1)
cfg := result[0]
// Verify basic fields
assert.Equal(t, "test-id", cfg.ID)
assert.Equal(t, "/test", cfg.ListenPath)
assert.Equal(t, "POST", cfg.Method)
// Verify request config
assert.Equal(t, "next-action", cfg.Request.Next)
// Verify actions
require.Contains(t, cfg.Actions, "action1")
action := cfg.Actions["action1"]
assert.Equal(t, "http", action.Type)
assert.JSONEq(t, `{"url": "http://example.com"}`, string(action.Config))
assert.Equal(t, "action2", action.Next)
assert.Equal(t, "error", action.Fail)
// Verify conditionals
require.Contains(t, cfg.Conditionals, "cond1")
cond := cfg.Conditionals["cond1"]
assert.Equal(t, "valid", cond.ValidPath)
assert.Equal(t, "invalid", cond.InvalidPath)
assert.Equal(t, "response.code == 200", cond.Expression)
// Verify responses
require.Contains(t, cfg.Responses, "success")
resp := cfg.Responses["success"]
assert.Equal(t, 200, resp.Code)
assert.Equal(t, "json", resp.Type)
assert.Equal(t, `{"status": "ok"}`, resp.Template)
assert.Equal(t, MCPToolConfig{
Enabled: true,
Name: "test-tool",
Args: map[string]ArgType{
"arg1": {
Name: "arg1",
Type: "string",
},
},
Description: "test description",
Start: "start",
Result: "result",
}, cfg.McpTool)
assert.Equal(t, HttpConfig{
Next: "next-action",
ListenPath: "/test",
Method: "GET",
}, cfg.HttpConfig)
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ProtoConfigToAPIConfig(tt.input)
tt.validate(t, result)
})
}
}