Files
kandev/apps/backend/internal/integration/orchestrator_basic_test.go
T
João Salavisa ba32a44cb4 refactor(backend): drop legacy orchestrator WS handlers superseded by session.launch (#803)
* refactor(backend): drop legacy orchestrator WS handlers superseded by session.launch

The orchestrator exposed six WS handlers (orchestrator.start, orchestrator.trigger,
orchestrator.prompt, orchestrator.complete, task.session.resume, task.session.prepare)
that all delegated to the unified LaunchSession or are no longer reachable from any
client. Drop the handlers, their DTOs, and the dead action constants
(orchestrator.pause, orchestrator.resume) that were never registered. Migrate the
remaining integration tests to the unified session.launch action.

* refactor(backend): drop orphan DTO request types and fix stale doc reference

Address PR review feedback: the DTO types TaskSessionStatusRequest, StopTaskRequest,
and PermissionRespondRequest had no consumers (each was shadowed by an inline
private ws*Request type in the handler). AGENTS.md still referenced the removed
task.start action; switch it to session.launch.

---------

Co-authored-by: Kandev Agent <agent@kandev.dev>
2026-05-05 08:29:46 +01:00

175 lines
5.3 KiB
Go

// Package integration provides end-to-end integration tests for the Kandev backend.
package integration
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/kandev/kandev/internal/task/models"
ws "github.com/kandev/kandev/pkg/websocket"
)
func TestOrchestratorStatus(t *testing.T) {
ts := NewOrchestratorTestServer(t)
defer ts.Close()
client := NewOrchestratorWSClient(t, ts.Server.URL)
defer client.Close()
resp, err := client.SendRequest("status-1", ws.ActionOrchestratorStatus, map[string]interface{}{})
require.NoError(t, err)
assert.Equal(t, ws.MessageTypeResponse, resp.Type)
var payload map[string]interface{}
require.NoError(t, resp.ParsePayload(&payload))
assert.True(t, payload["running"].(bool))
assert.Equal(t, float64(0), payload["active_agents"])
assert.Equal(t, float64(0), payload["queued_tasks"])
}
func TestOrchestratorQueue(t *testing.T) {
ts := NewOrchestratorTestServer(t)
defer ts.Close()
client := NewOrchestratorWSClient(t, ts.Server.URL)
defer client.Close()
resp, err := client.SendRequest("queue-1", ws.ActionOrchestratorQueue, map[string]interface{}{})
require.NoError(t, err)
assert.Equal(t, ws.MessageTypeResponse, resp.Type)
var payload map[string]interface{}
require.NoError(t, resp.ParsePayload(&payload))
assert.Equal(t, float64(0), payload["total"])
tasks := payload["tasks"].([]interface{})
assert.Len(t, tasks, 0)
}
func TestOrchestratorStartTask(t *testing.T) {
ts := NewOrchestratorTestServer(t)
defer ts.Close()
// Create a task with agent_profile_id
taskID := ts.CreateTestTask(t, "test-profile-id", 2)
client := NewOrchestratorWSClient(t, ts.Server.URL)
defer client.Close()
// Subscribe to task notifications
subResp, err := client.SendRequest("sub-1", ws.ActionTaskSubscribe, map[string]string{"task_id": taskID})
require.NoError(t, err)
assert.Equal(t, ws.MessageTypeResponse, subResp.Type)
// Start task execution
resp, err := client.SendRequest("start-1", ws.ActionSessionLaunch, map[string]interface{}{
"task_id": taskID,
"agent_profile_id": "test-profile-id",
})
require.NoError(t, err)
assert.Equal(t, ws.MessageTypeResponse, resp.Type)
var payload map[string]interface{}
require.NoError(t, resp.ParsePayload(&payload))
assert.True(t, payload["success"].(bool))
assert.Equal(t, taskID, payload["task_id"])
assert.NotEmpty(t, payload["agent_execution_id"])
sessionID, _ := payload["session_id"].(string)
require.NotEmpty(t, sessionID)
_, err = client.SendRequest("session-sub-1", ws.ActionSessionSubscribe, map[string]string{"session_id": sessionID})
require.NoError(t, err)
// Give the agent time to process
time.Sleep(500 * time.Millisecond)
// Check status shows active agent
statusResp, err := client.SendRequest("status-2", ws.ActionOrchestratorStatus, map[string]interface{}{})
require.NoError(t, err)
var statusPayload map[string]interface{}
require.NoError(t, statusResp.ParsePayload(&statusPayload))
assert.GreaterOrEqual(t, statusPayload["active_agents"].(float64), float64(0))
}
func TestOrchestratorStartTaskWithAgentTypeOverride(t *testing.T) {
ts := NewOrchestratorTestServer(t)
defer ts.Close()
taskID := ts.CreateTestTask(t, "augment-agent", 1)
client := NewOrchestratorWSClient(t, ts.Server.URL)
defer client.Close()
// Start with different agent profile
resp, err := client.SendRequest("start-1", ws.ActionSessionLaunch, map[string]interface{}{
"task_id": taskID,
"agent_profile_id": "override-profile-id",
"priority": 3,
})
require.NoError(t, err)
var payload map[string]interface{}
require.NoError(t, resp.ParsePayload(&payload))
assert.True(t, payload["success"].(bool))
}
func TestOrchestratorStopTask(t *testing.T) {
ts := NewOrchestratorTestServer(t)
defer ts.Close()
taskID := ts.CreateTestTask(t, "augment-agent", 2)
client := NewOrchestratorWSClient(t, ts.Server.URL)
defer client.Close()
// Start task
startResp, err := client.SendRequest("start-1", ws.ActionSessionLaunch, map[string]interface{}{
"task_id": taskID,
"agent_profile_id": "augment-agent",
})
require.NoError(t, err)
var startPayload map[string]interface{}
require.NoError(t, startResp.ParsePayload(&startPayload))
require.True(t, startPayload["success"].(bool))
sessionID, _ := startPayload["session_id"].(string)
require.NotEmpty(t, sessionID)
_, err = client.SendRequest("session-sub-1", ws.ActionSessionSubscribe, map[string]string{"session_id": sessionID})
require.NoError(t, err)
// Wait for the session to become active before stopping
deadline := time.Now().Add(5 * time.Second)
for time.Now().Before(deadline) {
session, sErr := ts.TaskRepo.GetTaskSession(context.Background(), sessionID)
if sErr == nil && session.State == models.TaskSessionStateRunning {
break
}
time.Sleep(50 * time.Millisecond)
}
// Stop task
stopResp, err := client.SendRequest("stop-1", ws.ActionOrchestratorStop, map[string]interface{}{
"task_id": taskID,
"reason": "test stop",
"force": false,
})
require.NoError(t, err)
var stopPayload map[string]interface{}
require.NoError(t, stopResp.ParsePayload(&stopPayload))
success, ok := stopPayload["success"].(bool)
assert.True(t, ok, "expected 'success' key in stop response, got: %v", stopPayload)
assert.True(t, success)
}