import assert from 'node:assert/strict'; import test from 'node:test'; import { bootstrapPortalAuthServices } from './portal-auth-services-bootstrap.mjs'; function createSetup(overrides = {}) { const calls = []; const pool = { id: 'pool' }; const planCatalogService = { getPlan(planType) { calls.push(['get-plan', planType]); return { planType }; }, }; const userAuth = { id: 'user-auth' }; const sessionAccess = { enabled: true, id: 'session-access', }; const wechatPayClient = { enabled: true, apiVersion: 'v3', }; const wechatOAuthService = { enabled: true }; const rechargeService = { id: 'recharge' }; let subscriptionOptions; let userAuthOptions; let sessionAccessOptions; let oauthArgs; let rechargeArgs; let userDataSpaceOptions; const options = { pool, h5Root: '/app', usersRoot: '/users', env: { H5_SIGNUP_BALANCE_CENTS: '750', }, mindSearchConfigService: { getEffectiveConfig() { calls.push(['mind-search-config']); return { enabled: true }; }, }, logger: { log(message) { calls.push(['log', message]); }, }, async ensurePlanCatalogSchemaFn(receivedPool) { assert.equal(receivedPool, pool); calls.push(['plan-schema']); }, createPlanCatalogServiceFn(receivedPool) { assert.equal(receivedPool, pool); calls.push(['plan-service']); return planCatalogService; }, createSubscriptionServiceFn( receivedPool, receivedOptions, ) { assert.equal(receivedPool, pool); calls.push(['subscription-service']); subscriptionOptions = receivedOptions; return { id: 'subscription' }; }, createUserAuthFn(receivedPool, receivedOptions) { assert.equal(receivedPool, pool); calls.push(['user-auth']); userAuthOptions = receivedOptions; return userAuth; }, createUserDataSpaceServiceFn(receivedOptions) { userDataSpaceOptions = receivedOptions; return { ensureReady() { calls.push(['user-space-ready']); return { ready: true }; }, }; }, createSessionAccessFn(receivedOptions) { calls.push(['session-access']); sessionAccessOptions = receivedOptions; return sessionAccess; }, isSessionBrokerEnabledFn() { return true; }, isSessionBrokerMetricsEnabledFn() { return false; }, resolveNormalizedRouterDecisionModeFn(receivedEnv) { assert.equal(receivedEnv, options.env); return 'off'; }, isSessionStreamReplayEnabledFn() { return false; }, loadWechatPayConfigFn() { calls.push(['pay-config']); return { merchantId: 'merchant' }; }, createWechatPayClientFn(config) { calls.push(['pay-client', config]); return wechatPayClient; }, loadWechatOAuthConfigFn() { calls.push(['oauth-config']); return { appId: 'app-id' }; }, createWechatOAuthServiceFn(...args) { calls.push(['oauth-service']); oauthArgs = args; return wechatOAuthService; }, createRechargeServiceFn(...args) { calls.push(['recharge-service']); rechargeArgs = args; return rechargeService; }, ...overrides, }; return { calls, options, pool, planCatalogService, userAuth, sessionAccess, wechatPayClient, wechatOAuthService, rechargeService, getCaptured() { return { subscriptionOptions, userAuthOptions, sessionAccessOptions, oauthArgs, rechargeArgs, userDataSpaceOptions, }; }, }; } test('requires the auth service bootstrap inputs', async () => { await assert.rejects( bootstrapPortalAuthServices(), /requires pool, roots, and MindSearch config/, ); }); test('preserves subscription, auth, and user-space wiring', async () => { const setup = createSetup(); const result = await bootstrapPortalAuthServices( setup.options, ); let captured = setup.getCaptured(); assert.deepEqual( setup.calls.slice(0, 4).map(([name]) => name), [ 'plan-schema', 'plan-service', 'subscription-service', 'user-auth', ], ); assert.equal( result.subscriptionService._planCatalogService, setup.planCatalogService, ); assert.deepEqual( await captured.subscriptionOptions.getPlanAsync( 'pro', ), { planType: 'pro' }, ); assert.equal(captured.userAuthOptions.usersRoot, '/users'); assert.equal(captured.userAuthOptions.h5Root, '/app'); assert.equal( captured.userAuthOptions.defaultSignupBalanceCents, 750, ); assert.equal( captured.userAuthOptions.subscriptionService, result.subscriptionService, ); assert.deepEqual( captured.userAuthOptions.getMindSearchConfig(), { enabled: true }, ); assert.deepEqual( await captured.userAuthOptions.provisionUserDataSpace({ userId: 'user-1', workspaceRoot: '/workspace/user-1', }), { ready: true }, ); captured = setup.getCaptured(); assert.deepEqual(captured.userDataSpaceOptions, { workspaceRoot: '/workspace/user-1', userId: 'user-1', query: setup.pool, }); assert.deepEqual(captured.sessionAccessOptions, { userAuth: setup.userAuth, enabled: true, }); }); test('reports every enabled H5 session flag', async () => { const setup = createSetup({ env: { MEMIND_SSE_EVENT_TAXONOMY: ' TRUE ', MEMIND_RUN_STREAM_REPLAY: 'yes', MEMIND_H5_HTML_FINISH_GUARD: 'on', }, isSessionBrokerMetricsEnabledFn: () => true, resolveNormalizedRouterDecisionModeFn: () => 'shadow', isSessionStreamReplayEnabledFn: () => true, }); const result = await bootstrapPortalAuthServices( setup.options, ); assert.deepEqual(result.h5SessionFlags, [ 'MEMIND_SESSION_BROKER_ENABLED', 'MEMIND_SESSION_BROKER_METRICS', 'MEMIND_ROUTER_NORMALIZED_DECISION=shadow', 'MEMIND_SESSION_STREAM_REPLAY', 'MEMIND_SSE_EVENT_TAXONOMY', 'MEMIND_RUN_STREAM_REPLAY', 'MEMIND_H5_HTML_FINISH_GUARD', ]); assert.ok( setup.calls.some( ([kind, message]) => kind === 'log' && message === `[Portal] H5 session flags: ${result.h5SessionFlags.join(', ')}`, ), ); }); test('preserves WeChat and recharge service wiring and logs', async () => { const setup = createSetup(); const result = await bootstrapPortalAuthServices( setup.options, ); const captured = setup.getCaptured(); assert.deepEqual(captured.oauthArgs, [ setup.pool, { appId: 'app-id' }, { userAuth: setup.userAuth }, ]); assert.deepEqual(captured.rechargeArgs, [ setup.pool, { userAuth: setup.userAuth, wechatPay: setup.wechatPayClient, }, ]); assert.equal( result.wechatOAuthService, setup.wechatOAuthService, ); assert.equal(result.rechargeService, setup.rechargeService); assert.ok( setup.calls.some( ([kind, message]) => kind === 'log' && message === 'WeChat Pay recharge enabled (v3)', ), ); assert.ok( setup.calls.some( ([kind, message]) => kind === 'log' && message === 'WeChat OAuth login enabled', ), ); }); test('keeps disabled integrations quiet and uses the balance default', async () => { const setup = createSetup({ env: {}, createSessionAccessFn: () => ({ enabled: false }), isSessionBrokerEnabledFn: () => false, createWechatPayClientFn: () => ({ enabled: false }), createWechatOAuthServiceFn: () => ({ enabled: false, }), }); const result = await bootstrapPortalAuthServices( setup.options, ); const captured = setup.getCaptured(); assert.equal( captured.userAuthOptions.defaultSignupBalanceCents, 500, ); assert.deepEqual(result.h5SessionFlags, []); assert.deepEqual( setup.calls.filter(([kind]) => kind === 'log'), [], ); } );