@@ -437,6 +437,68 @@ describe('generateBaseConfig', () => {
437437 expect ( config . channels . slack ) . toBeUndefined ( ) ;
438438 } ) ;
439439
440+ // ─── Stream Chat (default channel) ───────────────────────────────────────
441+
442+ it ( 'configures Stream Chat channel and plugin when all three vars are set' , ( ) => {
443+ const { deps } = fakeDeps ( ) ;
444+ const env = {
445+ ...minimalEnv ( ) ,
446+ STREAM_CHAT_API_KEY : 'sc-api-key' ,
447+ STREAM_CHAT_BOT_USER_ID : 'bot-sandbox-abc' ,
448+ STREAM_CHAT_BOT_USER_TOKEN : 'sc-bot-token' ,
449+ } ;
450+ const config = generateBaseConfig ( env , '/tmp/openclaw.json' , deps ) ;
451+
452+ expect ( config . channels . streamchat . apiKey ) . toBe ( 'sc-api-key' ) ;
453+ expect ( config . channels . streamchat . botUserId ) . toBe ( 'bot-sandbox-abc' ) ;
454+ expect ( config . channels . streamchat . botUserToken ) . toBe ( 'sc-bot-token' ) ;
455+ expect ( config . channels . streamchat . botUserName ) . toBe ( 'KiloClaw' ) ;
456+ expect ( config . channels . streamchat . enabled ) . toBe ( true ) ;
457+ expect ( config . plugins . entries . streamchat . enabled ) . toBe ( true ) ;
458+ expect ( config . plugins . load . paths ) . toContain (
459+ '/usr/local/lib/node_modules/@wunderchat/openclaw-channel-streamchat'
460+ ) ;
461+ } ) ;
462+
463+ it ( 'does not configure Stream Chat when any of the three required vars is missing' , ( ) => {
464+ const cases = [
465+ { STREAM_CHAT_API_KEY : 'key' , STREAM_CHAT_BOT_USER_ID : 'bot' } ,
466+ { STREAM_CHAT_API_KEY : 'key' , STREAM_CHAT_BOT_USER_TOKEN : 'token' } ,
467+ { STREAM_CHAT_BOT_USER_ID : 'bot' , STREAM_CHAT_BOT_USER_TOKEN : 'token' } ,
468+ ] ;
469+
470+ for ( const partial of cases ) {
471+ const { deps } = fakeDeps ( ) ;
472+ const env = { ...minimalEnv ( ) , ...partial } ;
473+ const config = generateBaseConfig ( env , '/tmp/openclaw.json' , deps ) ;
474+ expect ( config . channels . streamchat ) . toBeUndefined ( ) ;
475+ }
476+ } ) ;
477+
478+ it ( 'does not duplicate the plugin path on repeated generateBaseConfig calls' , ( ) => {
479+ const existing = JSON . stringify ( {
480+ channels : { streamchat : { apiKey : 'old-key' , enabled : true } } ,
481+ plugins : {
482+ load : {
483+ paths : [ '/usr/local/lib/node_modules/@wunderchat/openclaw-channel-streamchat' ] ,
484+ } ,
485+ entries : { streamchat : { enabled : true } } ,
486+ } ,
487+ } ) ;
488+ const { deps } = fakeDeps ( existing ) ;
489+ const env = {
490+ ...minimalEnv ( ) ,
491+ STREAM_CHAT_API_KEY : 'sc-api-key' ,
492+ STREAM_CHAT_BOT_USER_ID : 'bot-sandbox-abc' ,
493+ STREAM_CHAT_BOT_USER_TOKEN : 'sc-bot-token' ,
494+ } ;
495+ const config = generateBaseConfig ( env , '/tmp/openclaw.json' , deps ) ;
496+
497+ const pluginPath = '/usr/local/lib/node_modules/@wunderchat/openclaw-channel-streamchat' ;
498+ const paths = config . plugins . load . paths as string [ ] ;
499+ expect ( paths . filter ( p => p === pluginPath ) ) . toHaveLength ( 1 ) ;
500+ } ) ;
501+
440502 it ( 'does not set gateway auth when OPENCLAW_GATEWAY_TOKEN is missing' , ( ) => {
441503 const { deps } = fakeDeps ( ) ;
442504 const env = { ...minimalEnv ( ) } ;
0 commit comments