- Update DeliveryPayload to use structured types for Content and Preferences, enhancing type safety and readability. - Modify tests to reflect changes in payload structure, ensuring proper serialization and deserialization of delivery content. - Implement a new robotHandler for processing delivery events, streamlining the handling of different delivery channels (email, webhook, process). - Remove the deprecated DeliveryCenter, consolidating delivery logic within the new handler for better maintainability. - Enhance error handling and logging during delivery processing to improve observability and debugging capabilities.
148 lines
3.8 KiB
Go
148 lines
3.8 KiB
Go
package events
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
robottypes "github.com/yaoapp/yao/agent/robot/types"
|
|
)
|
|
|
|
// EP1: ExecPayload with all execution statuses
|
|
func TestExecPayloadAllStatuses(t *testing.T) {
|
|
statuses := []string{
|
|
"running", "completed", "failed", "cancelled", "waiting", "confirming",
|
|
}
|
|
|
|
for _, s := range statuses {
|
|
payload := ExecPayload{
|
|
ExecutionID: "exec-ep1",
|
|
MemberID: "member-ep1",
|
|
TeamID: "team-ep1",
|
|
Status: s,
|
|
}
|
|
|
|
data, err := json.Marshal(payload)
|
|
require.NoError(t, err)
|
|
|
|
var parsed ExecPayload
|
|
err = json.Unmarshal(data, &parsed)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, s, parsed.Status, "Status %s should round-trip", s)
|
|
}
|
|
}
|
|
|
|
// EP2: NeedInputPayload with empty question
|
|
func TestNeedInputPayloadEmptyQuestion(t *testing.T) {
|
|
payload := NeedInputPayload{
|
|
ExecutionID: "exec-ep2",
|
|
MemberID: "member-ep2",
|
|
TeamID: "team-ep2",
|
|
TaskID: "task-ep2",
|
|
Question: "",
|
|
}
|
|
|
|
data, err := json.Marshal(payload)
|
|
require.NoError(t, err)
|
|
|
|
var parsed map[string]interface{}
|
|
err = json.Unmarshal(data, &parsed)
|
|
require.NoError(t, err)
|
|
|
|
// Empty string should be present but empty
|
|
q, ok := parsed["question"]
|
|
assert.True(t, ok)
|
|
assert.Equal(t, "", q)
|
|
}
|
|
|
|
// EP3: TaskPayload serializes error correctly
|
|
func TestTaskPayloadErrorSerialization(t *testing.T) {
|
|
payload := TaskPayload{
|
|
ExecutionID: "exec-ep3",
|
|
MemberID: "member-ep3",
|
|
TeamID: "team-ep3",
|
|
TaskID: "task-ep3",
|
|
Error: "context deadline exceeded",
|
|
}
|
|
|
|
data, err := json.Marshal(payload)
|
|
require.NoError(t, err)
|
|
|
|
var parsed map[string]interface{}
|
|
err = json.Unmarshal(data, &parsed)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "context deadline exceeded", parsed["error"])
|
|
}
|
|
|
|
// EP4: DeliveryPayload with nested content
|
|
func TestDeliveryPayloadNestedContent(t *testing.T) {
|
|
payload := DeliveryPayload{
|
|
ExecutionID: "exec-ep4",
|
|
MemberID: "member-ep4",
|
|
TeamID: "team-ep4",
|
|
Content: &robottypes.DeliveryContent{
|
|
Summary: "Daily Summary",
|
|
Body: "Full body with sections: intro, body, conclusion",
|
|
},
|
|
}
|
|
|
|
data, err := json.Marshal(payload)
|
|
require.NoError(t, err)
|
|
|
|
var parsed DeliveryPayload
|
|
err = json.Unmarshal(data, &parsed)
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, parsed.Content)
|
|
assert.Equal(t, "Daily Summary", parsed.Content.Summary)
|
|
assert.Contains(t, parsed.Content.Body, "sections")
|
|
}
|
|
|
|
// EP5: Event constants follow naming convention
|
|
func TestEventConstantNamingConvention(t *testing.T) {
|
|
allEvents := []string{
|
|
TaskNeedInput, TaskFailed, TaskCompleted,
|
|
ExecWaiting, ExecResumed, ExecCompleted, ExecFailed, ExecCancelled,
|
|
Delivery,
|
|
}
|
|
|
|
for _, e := range allEvents {
|
|
assert.Contains(t, e, "robot.", "Event %q should start with 'robot.'", e)
|
|
}
|
|
}
|
|
|
|
// EP6: ExecPayload omits empty ChatID
|
|
func TestExecPayloadOmitsEmptyOptionalFields(t *testing.T) {
|
|
payload := ExecPayload{
|
|
ExecutionID: "exec-ep6",
|
|
MemberID: "member-ep6",
|
|
TeamID: "team-ep6",
|
|
Status: "completed",
|
|
}
|
|
|
|
data, err := json.Marshal(payload)
|
|
require.NoError(t, err)
|
|
|
|
var parsed map[string]interface{}
|
|
err = json.Unmarshal(data, &parsed)
|
|
require.NoError(t, err)
|
|
|
|
_, hasChatID := parsed["chat_id"]
|
|
if hasChatID {
|
|
assert.Equal(t, "", parsed["chat_id"])
|
|
}
|
|
}
|
|
|
|
// EP7: All payloads share common fields (ExecutionID, MemberID, TeamID)
|
|
func TestPayloadCommonFields(t *testing.T) {
|
|
needInput := NeedInputPayload{ExecutionID: "e1", MemberID: "m1", TeamID: "t1"}
|
|
task := TaskPayload{ExecutionID: "e2", MemberID: "m2", TeamID: "t2"}
|
|
exec := ExecPayload{ExecutionID: "e3", MemberID: "m3", TeamID: "t3"}
|
|
delivery := DeliveryPayload{ExecutionID: "e4", MemberID: "m4", TeamID: "t4"}
|
|
|
|
assert.Equal(t, "e1", needInput.ExecutionID)
|
|
assert.Equal(t, "m2", task.MemberID)
|
|
assert.Equal(t, "t3", exec.TeamID)
|
|
assert.Equal(t, "e4", delivery.ExecutionID)
|
|
}
|