Testing
Per-plugin kernel tests (tests/src/Kernel/Plugin/AiFunctionCall/)
Each plugin has its own kernel test, exercising it in isolation with hand-built context values - including permission checks, error handling, and every documented code path:
- CreateViewTest
- CreateViewDisplayTest
- ListViewTest
- CreateViewHandlerTest
- RemoveViewHandlerTest
- UpdateViewHandlerOptionsTest
- UpdateViewPluginsTest
Integration tests (tests/src/Kernel/Integration/)
These load the real shipped views_agent config entity and drive it through realistic workflows, rather than hand-building context on one plugin at a time:
- ViewsAgentTest: Asserts every tool the agent declares resolves to a real plugin, then drives the full declared tool set (create/configure/list/remove) through one workflow, finishing with a real
Views::preview()execution against real content. - CreateNonAdminViewTest / CreateAdminViewTest: Build a frontpage-style (public, filtered, sorted) and a content-listing-style (admin, unfiltered) view respectively, modeled on core's own
views.view.frontpage.ymlandviews.view.content.yml, directly invoking eachai_agents_views:*plugin. - AgentWrapperViewTest: Drives the
views_agentthrough the agent wrapper's recorded-state replay (AiAgentEntityWrapper::fromArray()+getToolResultsByPluginId(), the same mechanismai_agents's ownAiAgentEntityWrapperTestuses), loading a create-then-update workflow fixture undertests/assets/agent_states/. This does not callexecute()on either replayed tool - see the class doc comment for what it does and doesn't prove. - AgentEchoAiViewTest: Drives the agent's real
determineSolvability()tool-calling loop against theai_testmodule'sechoaiprovider through a scripted create-then-update workflow (create_viewthenupdate_view_plugins), fixtured across three turns undertests/resources/ai_test/requests/chat/. Unlike the replay test above,execute()genuinely runs for both tool calls - this is the one test that proves the full multi-step path a real LLM-driven run would take, end to end.
Each test sets up the required modules and environment, and verifies the plugin's behavior, including permission checks, error handling, and correct output.
Static analysis
A module-local phpstan.neon (level 1 + bleedingEdge.neon) is provided, with a small, scoped ignoreErrors list documenting Drupal-architecture false positives (e.g. plugin create() methods and $modules test properties flagged as dead code by shipmonk/dead-code-detector, since both are read reflectively rather than through a traceable call):
vendor/bin/phpstan analyse --configuration=modules/contrib/ai_agents_views/phpstan.neon