import assert from 'node:assert/strict'; import { buildApp } from '../dist/app.js'; import { AmbiguousAppTenantError, PlatformConfigRepository } from '../dist/tenancy/platform-config-repository.js'; const calls = []; const repository = new PlatformConfigRepository({ async execute(sql, params) { calls.push([sql, params]); return [[{ appId: 'wx-test-app', tenantId: 7, tenantCode: 'tenant-seven', tenantName: 'Tenant Seven', brandName: 'Seven棋牌', logoUrl: 'https://api.txyundm.cn/uploads/tenant-7/logo.png', themeColor: '#1677ff', servicePhone: '4000000000', franchisePhone: '', shareTitle: 'Seven棋牌', shareImageUrl: '', defaultStoreId: 9 }], []]; } }); const bootstrap = await repository.resolveBootstrap('wx-test-app', '7'); assert.equal(bootstrap.tenantId, '7'); assert.equal(bootstrap.defaultStoreId, '9'); assert.equal(bootstrap.brand.name, 'Seven棋牌'); assert.match(calls[0][0], /tc\.tenant_id = ta\.tenant_id/); assert.match(calls[0][0], /AND ta\.tenant_id = \?/); assert.deepEqual(calls[0][1], ['wx-test-app', '7']); const ambiguousRepository = new PlatformConfigRepository({ async execute() { return [[ { tenantId: 1 }, { tenantId: 2 } ], []]; } }); await assert.rejects( () => ambiguousRepository.resolveBootstrap('wx-multi-app'), AmbiguousAppTenantError ); const app = await buildApp({ platformConfigRepository: { async resolveBootstrap(appId, tenantId) { assert.equal(appId, 'wx-test-app'); assert.equal(tenantId, '7'); return bootstrap; } } }); const response = await app.inject({ method: 'GET', url: '/app-api/bootstrap', headers: { 'x-wechat-appid': 'wx-test-app', 'tenant-id': '7', 'x-trace-id': 'm02a-test' } }); assert.equal(response.statusCode, 200); assert.equal(response.json().data.tenantId, '7'); assert.equal(response.headers['x-trace-id'], 'm02a-test'); await app.close(); const missingContextApp = await buildApp({ platformConfigRepository: { async resolveBootstrap() { throw new Error('must not be called'); } } }); const invalidResponse = await missingContextApp.inject({ method: 'GET', url: '/app-api/bootstrap' }); assert.equal(invalidResponse.statusCode, 400); assert.equal(invalidResponse.json().code, 'INVALID_APP_CONTEXT'); await missingContextApp.close(); console.log('PASS: M02-A app and tenant bootstrap enforces explicit bindings.');