@@ -1238,4 +1238,128 @@ describe("agentic.SessionManager", function()
12381238 assert .spy (write_message_spy ).was .called (0 )
12391239 end )
12401240 end )
1241+
1242+ describe (" new_session: on_create_session_response hook" , function ()
1243+ local Config = require (" agentic.config" )
1244+ --- @type TestStub
1245+ local schedule_stub
1246+
1247+ before_each (function ()
1248+ schedule_stub = spy .stub (vim , " schedule" )
1249+ schedule_stub :invokes (function (fn )
1250+ fn ()
1251+ end )
1252+ end )
1253+
1254+ --- Build a session mock with just enough surface for the error path.
1255+ --- new_session calls self:_cancel_session and self:_build_handlers
1256+ --- before agent:create_session. Both are stubbed to no-ops so the
1257+ --- test focuses on the hook invocation. The error path returns
1258+ --- immediately after the hook, so success-path collaborators are
1259+ --- not needed.
1260+ --- @return agentic.SessionManager
1261+ local function make_session ()
1262+ return {
1263+ tab_page_id = 99 ,
1264+ session_id = nil ,
1265+ status_animation = {
1266+ start = function () end ,
1267+ stop = function () end ,
1268+ },
1269+ _cancel_session = function () end ,
1270+ _build_handlers = function ()
1271+ return {}
1272+ end ,
1273+ new_session = SessionManager .new_session ,
1274+ agent = {
1275+ provider_config = { name = " Test" },
1276+ },
1277+ } --[[ @as agentic.SessionManager]]
1278+ end
1279+
1280+ --- Stub agent:create_session to fire its callback synchronously
1281+ --- with the given response/err pair.
1282+ --- @param session agentic.SessionManager
1283+ --- @param response agentic.acp.SessionCreationResponse | nil
1284+ --- @param err agentic.acp.ACPError | nil
1285+ local function fake_create_session (session , response , err )
1286+ session .agent .create_session = function (_self , _handlers , callback )
1287+ callback (response , err )
1288+ end
1289+ end
1290+
1291+ after_each (function ()
1292+ schedule_stub :revert ()
1293+ Config .hooks = Config .hooks or {}
1294+ Config .hooks .on_create_session_response = nil
1295+ end )
1296+
1297+ it (" fires on error with err set and response nil" , function ()
1298+ local hook_spy = spy .new (function () end )
1299+ Config .hooks = Config .hooks or {}
1300+ Config .hooks .on_create_session_response = function (data )
1301+ hook_spy (data )
1302+ end
1303+
1304+ local session = make_session ()
1305+ local err = { code = - 32000 , message = " boom" }
1306+ fake_create_session (
1307+ session ,
1308+ nil ,
1309+ err --[[ @as agentic.acp.ACPError]]
1310+ )
1311+
1312+ SessionManager .new_session (session )
1313+
1314+ assert .spy (hook_spy ).was .called (1 )
1315+ local data = hook_spy .calls [1 ][1 ]
1316+ assert .is_nil (data .session_id )
1317+ assert .equal (99 , data .tab_page_id )
1318+ assert .is_nil (data .response )
1319+ assert .equal (err , data .err )
1320+ assert .is_nil (session .session_id )
1321+ end )
1322+
1323+ it (" does not fire when no hook is configured" , function ()
1324+ Config .hooks = Config .hooks or {}
1325+ Config .hooks .on_create_session_response = nil
1326+
1327+ local session = make_session ()
1328+ fake_create_session (session , nil , {
1329+ code = - 32000 ,
1330+ message = " boom" ,
1331+ } --[[ @as agentic.acp.ACPError]] )
1332+
1333+ assert .has_no_errors (function ()
1334+ SessionManager .new_session (session )
1335+ end )
1336+ end )
1337+
1338+ it (" fires before the early return on error" , function ()
1339+ -- Verifies the contract: hook receives err, then session_id is
1340+ -- cleared. If the hook fired AFTER the early return, it would
1341+ -- never run on the error path.
1342+ local hook_call_order = {}
1343+ Config .hooks = Config .hooks or {}
1344+ Config .hooks .on_create_session_response = function (data )
1345+ table.insert (hook_call_order , {
1346+ err = data .err ,
1347+ session_id_at_fire = data .session_id ,
1348+ })
1349+ end
1350+
1351+ local session = make_session ()
1352+ session .session_id = " stale-id"
1353+ fake_create_session (session , nil , {
1354+ code = - 32000 ,
1355+ message = " boom" ,
1356+ } --[[ @as agentic.acp.ACPError]] )
1357+
1358+ SessionManager .new_session (session )
1359+
1360+ assert .equal (1 , # hook_call_order )
1361+ assert .is_not_nil (hook_call_order [1 ].err )
1362+ assert .is_nil (session .session_id )
1363+ end )
1364+ end )
12411365end )
0 commit comments