yao/agent/robot/events/event_push_test.go
Max 5f5bcba2b2 Refactor delivery event handling and payload structure for improved clarity and functionality
- 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.
2026-02-27 18:19:57 +08:00

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)
}