Files
cleveragents-core/features/a2a_facade_wiring.feature
T
HAL9000 901e3e360b fix(a2a): close session_id validation bypass in _handle_session_close
Removed unreachable duplicate code left over after moving session_id validation
to the top of _handle_session_close(). Updated BDD test scenario in
a2a_facade_wiring.feature to cover the no-service + empty session_id path.

PR-CLOSED: #9250
2026-06-17 08:49:34 -04:00

178 lines
8.7 KiB
Gherkin

@a2a
Feature: A2A local facade wiring to live services
As a client of the A2A local facade
I want operations to route to real application services
So that the facade delegates to live implementations
# ---------------------------------------------------------------
# Session wiring
# ---------------------------------------------------------------
Scenario: session.create delegates to SessionService
Given a wired A2aLocalFacade with a mock SessionService
When I dispatch wired operation "session.create" with params {"actor_name": "local/test-actor"}
Then the wired response status should be "ok"
And wired response data key "session_id" equals "MOCK-SESSION-001"
And wired response data key "status" equals "created"
Scenario: session.create with existing session_id is idempotent
Given a wired A2aLocalFacade with a mock SessionService
When I dispatch wired operation "session.create" with params {"session_id": "EXISTING-SESSION-999"}
Then the wired response status should be "ok"
And wired response data key "session_id" equals "EXISTING-SESSION-999"
And wired response data key "status" equals "created"
And the mock SessionService create should not have been called
Scenario: session.close delegates to SessionService
Given a wired A2aLocalFacade with a mock SessionService
When I dispatch wired operation "session.close" with params {"session_id": "MOCK-SESSION-001"}
Then the wired response status should be "ok"
And wired response data key "status" equals "closed"
Scenario: session.close without session_id returns error
Given a wired A2aLocalFacade with a mock SessionService
When I dispatch wired operation "session.close" with params {}
Then the wired response status should be "error"
# ---------------------------------------------------------------
# Validate session_id at entry — no service scenario (PR #9250)
# ---------------------------------------------------------------
Scenario: session.close without session_id and no service returns error
Given a wired A2aLocalFacade with no services
When I dispatch wired operation "session.close" with params {"session_id": ""}
Then the wired response status should be "error"
# ---------------------------------------------------------------
# Plan lifecycle wiring
# ---------------------------------------------------------------
Scenario: plan.create delegates to PlanLifecycleService
Given a wired A2aLocalFacade with a mock PlanLifecycleService
When I dispatch wired operation "plan.create" with params {"action_name": "local/test-action"}
Then the wired response status should be "ok"
And wired response data key "plan_id" equals "MOCK-PLAN-001"
And wired response data key "status" equals "created"
Scenario: plan.create without action_name returns error
Given a wired A2aLocalFacade with a mock PlanLifecycleService
When I dispatch wired operation "plan.create" with params {}
Then the wired response status should be "error"
Scenario: plan.execute delegates to PlanLifecycleService
Given a wired A2aLocalFacade with a mock PlanLifecycleService
When I dispatch wired operation "plan.execute" with params {"plan_id": "MOCK-PLAN-001"}
Then the wired response status should be "ok"
And wired response data key "plan_id" equals "MOCK-PLAN-001"
Scenario: plan.status delegates to PlanLifecycleService
Given a wired A2aLocalFacade with a mock PlanLifecycleService
When I dispatch wired operation "plan.status" with params {"plan_id": "MOCK-PLAN-001"}
Then the wired response status should be "ok"
And wired response data key "plan_id" equals "MOCK-PLAN-001"
And wired response data key "phase" equals "strategize"
Scenario: plan.diff delegates to PlanLifecycleService
Given a wired A2aLocalFacade with a mock PlanLifecycleService
When I dispatch wired operation "plan.diff" with params {"plan_id": "MOCK-PLAN-001"}
Then the wired response status should be "ok"
And wired response data key "plan_id" equals "MOCK-PLAN-001"
Scenario: plan.apply delegates to PlanLifecycleService
Given a wired A2aLocalFacade with a mock PlanLifecycleService
When I dispatch wired operation "plan.apply" with params {"plan_id": "MOCK-PLAN-001"}
Then the wired response status should be "ok"
And wired response data key "plan_id" equals "MOCK-PLAN-001"
# ---------------------------------------------------------------
# Registry wiring
# ---------------------------------------------------------------
Scenario: registry.list_tools delegates to ToolRegistry
Given a wired A2aLocalFacade with a mock ToolRegistry
When I dispatch wired operation "registry.list_tools" with params {}
Then the wired response status should be "ok"
And wired response data should contain tools list with 2 items
Scenario: registry.list_resources delegates to ResourceRegistryService
Given a wired A2aLocalFacade with a mock ResourceRegistryService
When I dispatch wired operation "registry.list_resources" with params {}
Then the wired response status should be "ok"
And wired response data should contain resources list with 1 items
# ---------------------------------------------------------------
# Context stub
# ---------------------------------------------------------------
Scenario: context.get returns stub pending ACMS pipeline
Given a wired A2aLocalFacade with no services
When I dispatch wired operation "context.get" with params {}
Then the wired response status should be "ok"
And wired response data key "stub" equals "True"
# ---------------------------------------------------------------
# Event wiring
# ---------------------------------------------------------------
Scenario: event.subscribe delegates to A2aEventQueue
Given a wired A2aLocalFacade with a mock A2aEventQueue
When I dispatch wired operation "event.subscribe" with params {}
Then the wired response status should be "ok"
And wired response data key "status" equals "subscribed"
And wired response data key "subscription_id" should not be empty
# ---------------------------------------------------------------
# Error mapping
# ---------------------------------------------------------------
Scenario: NOT_FOUND error code for missing resources
Given a wired A2aLocalFacade with a raising SessionService for not-found
When I dispatch wired operation "session.close" with params {"session_id": "nonexistent"}
Then the wired response status should be "error"
And wired response error code should be "NOT_FOUND"
Scenario: VALIDATION_ERROR code for validation failures
Given a wired A2aLocalFacade with a raising service for validation-error
When I dispatch wired operation "plan.create" with params {"action_name": "bad"}
Then the wired response status should be "error"
And wired response error code should be "VALIDATION_ERROR"
Scenario: PLAN_ERROR code for plan failures
Given a wired A2aLocalFacade with a raising service for plan-error
When I dispatch wired operation "plan.execute" with params {"plan_id": "P1"}
Then the wired response status should be "error"
And wired response error code should be "PLAN_ERROR"
Scenario: INVALID_STATE code for business rule violations
Given a wired A2aLocalFacade with a raising service for invalid-state
When I dispatch wired operation "plan.apply" with params {"plan_id": "P1"}
Then the wired response status should be "error"
And wired response error code should be "INVALID_STATE"
# ---------------------------------------------------------------
# Fallback stubs when no service is wired
# ---------------------------------------------------------------
Scenario: session.create stub when no service wired
Given a wired A2aLocalFacade with no services
When I dispatch wired operation "session.create" with params {}
Then the wired response status should be "ok"
And wired response data key "status" equals "created"
Scenario: plan.create stub when no service wired
Given a wired A2aLocalFacade with no services
When I dispatch wired operation "plan.create" with params {}
Then the wired response status should be "ok"
And wired response data key "status" equals "created"
Scenario: registry.list_tools stub when no service wired
Given a wired A2aLocalFacade with no services
When I dispatch wired operation "registry.list_tools" with params {}
Then the wired response status should be "ok"
Scenario: event.subscribe stub when no service wired
Given a wired A2aLocalFacade with no services
When I dispatch wired operation "event.subscribe" with params {}
Then the wired response status should be "ok"
And wired response data key "status" equals "subscribed"