@@ -2314,6 +2314,55 @@ describe("updateNpmInstalledPlugins", () => {
23142314 status : "error" ,
23152315 message :
23162316 "Failed to update openclaw-codex-app-server: npm package not found for openclaw-codex-app-server." ,
2317+ channelFallback : {
2318+ requestedSpec : "openclaw-codex-app-server@beta" ,
2319+ usedSpec : "openclaw-codex-app-server" ,
2320+ requestedLabel : "@beta" ,
2321+ usedLabel : "@latest" ,
2322+ reason : "failed" ,
2323+ message :
2324+ "plugin channel fallback: openclaw-codex-app-server used @latest after @beta failed" ,
2325+ } ,
2326+ } ,
2327+ ] ) ;
2328+ } ) ;
2329+
2330+ it ( "keeps fallback metadata when a dry-run beta fallback also fails" , async ( ) => {
2331+ installPluginFromNpmSpecMock
2332+ . mockResolvedValueOnce ( {
2333+ ok : false ,
2334+ error : "Installed plugin package uses a TypeScript entry without compiled runtime output." ,
2335+ } )
2336+ . mockResolvedValueOnce ( {
2337+ ok : false ,
2338+ code : "npm_package_not_found" ,
2339+ error : "npm package not found" ,
2340+ } ) ;
2341+
2342+ const result = await updateNpmInstalledPlugins ( {
2343+ config : createCodexAppServerInstallConfig ( {
2344+ spec : "openclaw-codex-app-server" ,
2345+ } ) ,
2346+ pluginIds : [ "openclaw-codex-app-server" ] ,
2347+ updateChannel : "beta" ,
2348+ dryRun : true ,
2349+ } ) ;
2350+
2351+ expect ( result . outcomes ) . toEqual ( [
2352+ {
2353+ pluginId : "openclaw-codex-app-server" ,
2354+ status : "error" ,
2355+ message :
2356+ "Failed to check openclaw-codex-app-server: npm package not found for openclaw-codex-app-server." ,
2357+ channelFallback : {
2358+ requestedSpec : "openclaw-codex-app-server@beta" ,
2359+ usedSpec : "openclaw-codex-app-server" ,
2360+ requestedLabel : "@beta" ,
2361+ usedLabel : "@latest" ,
2362+ reason : "failed" ,
2363+ message :
2364+ "plugin channel fallback: openclaw-codex-app-server would use @latest after @beta failed" ,
2365+ } ,
23172366 } ,
23182367 ] ) ;
23192368 } ) ;
0 commit comments