@@ -7,11 +7,13 @@ import {
77} from "openclaw/plugin-sdk/plugin-test-contracts" ;
88import { afterEach , describe , expect , it } from "vitest" ;
99import {
10+ validatePluginsUiDescriptorsResult ,
1011 validatePluginsUiDescriptorsParams ,
1112 validateSessionsPluginPatchParams ,
1213} from "../../../packages/gateway-protocol/src/index.js" ;
1314import { loadSessionStore , updateSessionStore , type SessionEntry } from "../../config/sessions.js" ;
1415import { APPROVALS_SCOPE , READ_SCOPE , WRITE_SCOPE } from "../../gateway/operator-scopes.js" ;
16+ import { pluginHostHookHandlers } from "../../gateway/server-methods/plugin-host-hooks.js" ;
1517import { buildGatewaySessionRow } from "../../gateway/session-utils.js" ;
1618import { withTempConfig } from "../../gateway/test-temp-config.js" ;
1719import { emitAgentEvent , resetAgentEventsForTest } from "../../infra/agent-events.js" ;
@@ -1892,6 +1894,84 @@ describe("host-hook fixture plugin contract", () => {
18921894 ) . toBe ( false ) ;
18931895 expect ( validatePluginsUiDescriptorsParams ( { } ) ) . toBe ( true ) ;
18941896 expect ( validatePluginsUiDescriptorsParams ( { pluginId : "host-hook-fixture" } ) ) . toBe ( false ) ;
1897+ expect (
1898+ validatePluginsUiDescriptorsResult ( {
1899+ ok : true ,
1900+ descriptors : [
1901+ {
1902+ id : "approval-panel" ,
1903+ pluginId : "host-hook-fixture" ,
1904+ surface : "session" ,
1905+ label : "Approval panel" ,
1906+ } ,
1907+ ] ,
1908+ } ) ,
1909+ ) . toBe ( true ) ;
1910+ expect (
1911+ validatePluginsUiDescriptorsResult ( {
1912+ ok : true ,
1913+ descriptors : [
1914+ {
1915+ id : "approval-panel" ,
1916+ pluginId : "host-hook-fixture" ,
1917+ surface : "session" ,
1918+ label : "Approval panel" ,
1919+ leakedRegistryField : true ,
1920+ } ,
1921+ ] ,
1922+ } ) ,
1923+ ) . toBe ( false ) ;
1924+ } ) ;
1925+
1926+ it ( "projects plugin UI descriptors through the strict gateway result shape" , ( ) => {
1927+ const { config, registry } = createPluginRegistryFixture ( ) ;
1928+ registerTestPlugin ( {
1929+ registry,
1930+ config,
1931+ record : createPluginRecord ( {
1932+ id : "host-hook-fixture" ,
1933+ name : "Host Hook Fixture" ,
1934+ } ) ,
1935+ register ( api ) {
1936+ api . registerControlUiDescriptor ( {
1937+ id : "approval-panel" ,
1938+ surface : "session" ,
1939+ label : "Approval panel" ,
1940+ } ) ;
1941+ } ,
1942+ } ) ;
1943+ const descriptorEntry = registry . registry . controlUiDescriptors ?. [ 0 ] ;
1944+ if ( ! descriptorEntry ) {
1945+ throw new Error ( "expected control UI descriptor registration" ) ;
1946+ }
1947+ Object . assign ( descriptorEntry . descriptor , { leakedRegistryField : true } ) ;
1948+ setActivePluginRegistry ( registry . registry ) ;
1949+
1950+ const calls : Array < [ boolean , unknown , unknown ] > = [ ] ;
1951+ void pluginHostHookHandlers [ "plugins.uiDescriptors" ] ( {
1952+ params : { } ,
1953+ respond : ( ok : boolean , payload : unknown , error : unknown ) => {
1954+ calls . push ( [ ok , payload , error ] ) ;
1955+ } ,
1956+ } as never ) ;
1957+
1958+ expect ( calls ) . toHaveLength ( 1 ) ;
1959+ const [ ok , payload , error ] = calls [ 0 ] ?? [ ] ;
1960+ expect ( ok ) . toBe ( true ) ;
1961+ expect ( error ) . toBeUndefined ( ) ;
1962+ expect ( validatePluginsUiDescriptorsResult ( payload ) ) . toBe ( true ) ;
1963+ expect ( payload ) . toEqual ( {
1964+ ok : true ,
1965+ descriptors : [
1966+ {
1967+ id : "approval-panel" ,
1968+ pluginId : "host-hook-fixture" ,
1969+ pluginName : "Host Hook Fixture" ,
1970+ surface : "session" ,
1971+ label : "Approval panel" ,
1972+ } ,
1973+ ] ,
1974+ } ) ;
18951975 } ) ;
18961976
18971977 it ( "enforces command requiredScopes for gateway clients and command owners" , async ( ) => {
0 commit comments