@@ -3,7 +3,7 @@ import fs from "node:fs/promises";
33import os from "node:os" ;
44import path from "node:path" ;
55import type { ProviderPlugin } from "openclaw/plugin-sdk/provider-model-shared" ;
6- import { afterAll , beforeAll , describe , expect , it , vi } from "vitest" ;
6+ import { afterAll , beforeAll , beforeEach , describe , expect , it , vi } from "vitest" ;
77import { createWizardPrompter as buildWizardPrompter } from "../../test/helpers/wizard-prompter.js" ;
88import { DEFAULT_BOOTSTRAP_FILENAME } from "../agents/workspace.js" ;
99import type { PluginCompatibilityNotice } from "../plugins/status.js" ;
@@ -111,7 +111,11 @@ const detectSetupMigrationSources = vi.hoisted(() => vi.fn(async () => []));
111111const listSetupMigrationOptions = vi . hoisted ( ( ) => vi . fn ( async ( ) => [ ] ) ) ;
112112const runSetupMigrationImport = vi . hoisted ( ( ) => vi . fn ( async ( ) => { } ) ) ;
113113
114- const setupChannels = vi . hoisted ( ( ) => vi . fn ( async ( cfg ) => cfg ) ) ;
114+ const setupChannels = vi . hoisted ( ( ) =>
115+ vi . fn (
116+ async ( cfg : unknown , _runtime ?: unknown , _prompter ?: WizardPrompter , _options ?: unknown ) => cfg ,
117+ ) ,
118+ ) ;
115119const setupSkills = vi . hoisted ( ( ) => vi . fn ( async ( cfg ) => cfg ) ) ;
116120
117121function providerPluginStub (
@@ -390,6 +394,61 @@ describe("runSetupWizard", () => {
390394 return dir ;
391395 }
392396
397+ beforeEach ( ( ) => {
398+ vi . clearAllMocks ( ) ;
399+ promptAuthChoiceGrouped . mockReset ( ) ;
400+ promptAuthChoiceGrouped . mockResolvedValue ( "skip" ) ;
401+ applyAuthChoice . mockReset ( ) ;
402+ applyAuthChoice . mockImplementation ( async ( args ) => ( { config : args . config } ) ) ;
403+ setupChannels . mockReset ( ) ;
404+ setupChannels . mockImplementation ( async ( cfg ) => cfg ) ;
405+ setupSkills . mockReset ( ) ;
406+ setupSkills . mockImplementation ( async ( cfg ) => cfg ) ;
407+ configureGatewayForSetup . mockReset ( ) ;
408+ configureGatewayForSetup . mockImplementation ( async ( args ) => ( {
409+ nextConfig : args . nextConfig ,
410+ settings : {
411+ port : args . localPort ?? 18789 ,
412+ bind : "loopback" ,
413+ authMode : "token" ,
414+ gatewayToken : "test-token" ,
415+ tailscaleMode : "off" ,
416+ tailscaleResetOnExit : false ,
417+ } ,
418+ } ) ) ;
419+ readConfigFileSnapshot . mockReset ( ) ;
420+ readConfigFileSnapshot . mockResolvedValue ( {
421+ path : "/tmp/.openclaw/openclaw.json" ,
422+ exists : false ,
423+ raw : null ,
424+ parsed : { } ,
425+ resolved : { } ,
426+ valid : true ,
427+ config : { } ,
428+ issues : [ ] ,
429+ warnings : [ ] ,
430+ legacyIssues : [ ] ,
431+ } ) ;
432+ probeGatewayReachable . mockReset ( ) ;
433+ probeGatewayReachable . mockResolvedValue ( { ok : false } ) ;
434+ resolvePreferredProviderForAuthChoice . mockReset ( ) ;
435+ resolvePreferredProviderForAuthChoice . mockResolvedValue ( "demo-provider" ) ;
436+ resolvePluginProvidersRuntime . mockReset ( ) ;
437+ resolvePluginProvidersRuntime . mockReturnValue ( [ ] ) ;
438+ resolveManifestProviderAuthChoice . mockReset ( ) ;
439+ resolveManifestProviderAuthChoice . mockReturnValue ( undefined ) ;
440+ resolvePluginSetupProvider . mockReset ( ) ;
441+ resolvePluginSetupProvider . mockReturnValue ( undefined ) ;
442+ resolveProviderPluginChoice . mockReset ( ) ;
443+ resolveProviderPluginChoice . mockReturnValue ( null ) ;
444+ promptDefaultModel . mockReset ( ) ;
445+ promptDefaultModel . mockResolvedValue ( { } ) ;
446+ warnIfModelConfigLooksOff . mockReset ( ) ;
447+ warnIfModelConfigLooksOff . mockResolvedValue ( undefined ) ;
448+ buildPluginCompatibilitySnapshotNotices . mockReset ( ) ;
449+ buildPluginCompatibilitySnapshotNotices . mockReturnValue ( [ ] ) ;
450+ } ) ;
451+
393452 it ( "exits successfully after the auto-launched TUI returns" , async ( ) => {
394453 const caseDir = await makeCaseDir ( "tui-success-exit-" ) ;
395454 await fs . writeFile ( path . join ( caseDir , DEFAULT_BOOTSTRAP_FILENAME ) , "" ) ;
@@ -970,22 +1029,24 @@ describe("runSetupWizard", () => {
9701029 const prompter = buildWizardPrompter ( { select } ) ;
9711030 const runtime = createRuntime ( { throwsOnExit : true } ) ;
9721031
973- await runSetupWizard (
974- {
975- acceptRisk : true ,
976- flow : "quickstart" ,
977- mode : "local" ,
978- workspace : workspaceDir ,
979- authChoice : "skip" ,
980- skipProviders : true ,
981- skipSkills : true ,
982- skipSearch : true ,
983- skipHealth : true ,
984- installDaemon : false ,
985- } ,
986- runtime ,
987- prompter ,
988- ) ;
1032+ await expect (
1033+ runSetupWizard (
1034+ {
1035+ acceptRisk : true ,
1036+ flow : "quickstart" ,
1037+ mode : "local" ,
1038+ workspace : workspaceDir ,
1039+ authChoice : "skip" ,
1040+ skipProviders : true ,
1041+ skipSkills : true ,
1042+ skipSearch : true ,
1043+ skipHealth : true ,
1044+ installDaemon : false ,
1045+ } ,
1046+ runtime ,
1047+ prompter ,
1048+ ) ,
1049+ ) . rejects . toThrow ( "exit:0" ) ;
9891050
9901051 expectRecordFields (
9911052 getMockCallArg ( runTui , 0 , 0 , "tui launch" ) ,
@@ -1085,9 +1146,18 @@ describe("runSetupWizard", () => {
10851146 } ) ;
10861147
10871148 it ( "disables back navigation before side-effecting channel setup" , async ( ) => {
1088- setupChannels . mockClear ( ) ;
1089- const disableBackNavigation = vi . fn ( ) ;
1090- const prompter = buildWizardPrompter ( { disableBackNavigation } ) ;
1149+ setupChannels . mockImplementationOnce ( async ( cfg , _runtime , channelPrompter ) => {
1150+ if ( ! channelPrompter ) {
1151+ throw new Error ( "expected channel setup prompter" ) ;
1152+ }
1153+ await channelPrompter . select ( {
1154+ message : "Channel side effect" ,
1155+ options : [ { value : "continue" , label : "Continue" } ] ,
1156+ } ) ;
1157+ return cfg ;
1158+ } ) ;
1159+ const select = vi . fn ( async ( ) => "continue" ) as unknown as WizardPrompter [ "select" ] ;
1160+ const prompter = buildWizardPrompter ( { select } ) ;
10911161 const runtime = createRuntime ( ) ;
10921162
10931163 await runSetupWizard (
@@ -1106,10 +1176,12 @@ describe("runSetupWizard", () => {
11061176 prompter ,
11071177 ) ;
11081178
1109- expect ( disableBackNavigation ) . toHaveBeenCalled ( ) ;
11101179 expect ( setupChannels ) . toHaveBeenCalledOnce ( ) ;
1111- expect ( disableBackNavigation . mock . invocationCallOrder [ 0 ] ) . toBeLessThan (
1112- setupChannels . mock . invocationCallOrder [ 0 ] ?? Number . POSITIVE_INFINITY ,
1180+ expect ( select ) . toHaveBeenCalledWith (
1181+ expect . objectContaining ( {
1182+ message : "Channel side effect" ,
1183+ navigation : { canGoBack : false , canGoForward : false } ,
1184+ } ) ,
11131185 ) ;
11141186 } ) ;
11151187
0 commit comments