XuqmGroup-RNSDK/packages/common/tests/metro.test.cjs

117 行
4.7 KiB
JavaScript

const assert = require('node:assert/strict')
const fs = require('node:fs')
const os = require('node:os')
const path = require('node:path')
const test = require('node:test')
const { withXuqmConfig } = require('../metro')
const CONFIG_VECTOR =
'XUQM-CONFIG-V2.xuqm-config-dev-2026-07.AAECAwQFBgcICQoLDA0ODw.EBESExQVFhcYGRob.MYRqE2BtQG0PvSnG3TLrr4PXd10C1cHhNA2iJLfy60XmQ5ixQBTCpn4e2g2YN0QQbZY0LVnou1rGONIzMrT7VidOMi_lHSfUf2BXnqlCIRm4yKcYCvALvrIF-Llv2xQWla0BTpKNq2Yuejpsw0oGTZGjNkvmlbBu8JJHAckHi-wP1sAgZuKVjjtJnjc7venWzaa75KwsqOYiNOkhIjWqTLNMG1siCMbX96d2A15KJYRUpwd-rBSpgjmOFLdH6DDaj2ZqCqQg6NRJprjsEorrCAnDjRjwoMKqHiIwHErfihw3v0AO19MJUzCeYzCzU2WfFw.Z-NMbyec47P4K_lfx3l7s3jZJVpd7ru8ySj2eBvXfteU4tVBoJ_3N7IRPMeiv1lUxMchsvNg8okxYpcBs4_2CQ'
test('withXuqmConfig schedules automatic initialization before the app entry', () => {
const projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'xuqm-metro-'))
const configDir = path.join(projectRoot, 'src/assets/config')
const existingPrelude = path.join(projectRoot, 'existing-prelude.js')
try {
fs.mkdirSync(configDir, { recursive: true })
fs.writeFileSync(path.join(configDir, 'app.xuqmconfig'), CONFIG_VECTOR, 'utf8')
const config = withXuqmConfig({
projectRoot,
resolver: {},
serializer: {
getModulesRunBeforeMainModule: () => [existingPrelude],
},
})
const preludeModules = config.serializer.getModulesRunBeforeMainModule('index.js')
assert.equal(preludeModules[0], existingPrelude)
2026-07-17 14:14:19 +08:00
assert.match(preludeModules[1], /packages[\\/]common[\\/]src[\\/]internal\.ts$/)
const virtualModule = config.resolver.resolveRequest(
{ resolveRequest: () => assert.fail('fallback resolver should not run') },
'@xuqm/rn-common/auto-init-config',
'android',
)
assert.equal(virtualModule.type, 'sourceFile')
const generatedSource = fs.readFileSync(virtualModule.filePath, 'utf8')
assert.match(generatedSource, /RESOLVED_CONFIG/)
assert.match(generatedSource, /"appKey":"test-app"/)
assert.equal(generatedSource.includes('XUQM-CONFIG-V2'), false)
} finally {
fs.rmSync(projectRoot, { recursive: true, force: true })
}
})
test('withXuqmConfig rejects legacy V1 files with a migration instruction', () => {
const projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'xuqm-metro-'))
const configDir = path.join(projectRoot, 'src/assets/config')
try {
fs.mkdirSync(configDir, { recursive: true })
fs.writeFileSync(
path.join(configDir, 'config.xuqmconfig'),
'XUQM-CONFIG-V1.invalid.invalid.invalid',
'utf8',
)
assert.throws(
() => withXuqmConfig({ projectRoot }),
/仅支持 XUQM-CONFIG-V2;请从租户平台重新下载配置文件/,
)
} finally {
fs.rmSync(projectRoot, { recursive: true, force: true })
}
})
test('withXuqmConfig rejects a modified V2 signature before decrypting content', () => {
const projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'xuqm-metro-'))
const configDir = path.join(projectRoot, 'src/assets/config')
try {
fs.mkdirSync(configDir, { recursive: true })
const parts = CONFIG_VECTOR.split('.')
parts[5] = `${parts[5][0] === 'A' ? 'B' : 'A'}${parts[5].slice(1)}`
const tampered = parts.join('.')
fs.writeFileSync(path.join(configDir, 'config.xuqmconfig'), tampered, 'utf8')
assert.throws(() => withXuqmConfig({ projectRoot }), /配置文件签名验证失败/)
assert.equal(
fs.existsSync(path.join(projectRoot, 'android/app/src/main/assets/config/config.xuqmconfig')),
false,
)
} finally {
fs.rmSync(projectRoot, { recursive: true, force: true })
}
})
test('withXuqmConfig leaves common-only hosts unchanged without a config file', () => {
const projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'xuqm-metro-'))
const original = {
projectRoot,
serializer: {
getModulesRunBeforeMainModule: () => ['existing-prelude.js'],
},
}
try {
assert.equal(withXuqmConfig(original), original)
} finally {
fs.rmSync(projectRoot, { recursive: true, force: true })
}
})
test('withXuqmConfig rejects ambiguous config directories instead of choosing a file', () => {
const projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'xuqm-metro-'))
const configDir = path.join(projectRoot, 'src/assets/config')
try {
fs.mkdirSync(configDir, { recursive: true })
fs.writeFileSync(path.join(configDir, 'app.xuqmconfig'), CONFIG_VECTOR, 'utf8')
fs.writeFileSync(path.join(configDir, 'tenant.xuqmconfig'), CONFIG_VECTOR, 'utf8')
assert.throws(
() => withXuqmConfig({ projectRoot }),
/只能存在一个 \.xuqmconfig 文件,当前发现 2 个/,
)
} finally {
fs.rmSync(projectRoot, { recursive: true, force: true })
}
})