- 模块一: 出海案例作品集、博客动态发布、人名发音语音条、RTL阿语多语言切换 - 模块二: AI顾问人设配置、行业术语库润色、RAG切片沙盒调试、流式会话与意向留资卡片 - 模块三: 全球访客雷达大屏、多维加权意向算分、外部CRM对接推送、团队公海池流转 - 模块四: 移动端NFC安全挂失、NFC动态路由规则配置、动态防伪验签、展会制卡Zip批量导出 - 模块五: 组织架构与名片分配、移动端个人中心设置、离职交接与历史线索迁移、安全审计日志 - 模块六: Stripe国际信用卡订阅Webhook、独立二级域名与SSL检测、坐席配额预警、多币种发票 - 模块七: 纸质名片OCR解析入库、国际商务日程RFC 5545 ICS日历、微官网离线SWR预加载、展会实时排行榜大屏 - 模块八: 全球出海SEO OpenGraph元标签注入与社交爬虫探测、30点端到端全链路业务流集成测试套件
128 行
4.0 KiB
TypeScript
128 行
4.0 KiB
TypeScript
import {
|
|
parseAcceptLanguage,
|
|
parseGeoLocale,
|
|
resolveSuggestedLocale,
|
|
} from '../../src/comm/i18n/geo';
|
|
|
|
describe('T18: Geo / 浏览器语言自动建议', () => {
|
|
describe('parseAcceptLanguage', () => {
|
|
it('应将 zh* 映射为 zh-CN', () => {
|
|
expect(parseAcceptLanguage('zh-CN,zh;q=0.9,en;q=0.8')).toBe('zh-CN');
|
|
expect(parseAcceptLanguage('zh')).toBe('zh-CN');
|
|
expect(parseAcceptLanguage('zh-TW')).toBe('zh-CN');
|
|
expect(parseAcceptLanguage('zh-Hans-CN')).toBe('zh-CN');
|
|
});
|
|
|
|
it('应将 ar* 映射为 ar-SA', () => {
|
|
expect(parseAcceptLanguage('ar-SA,ar;q=0.8')).toBe('ar-SA');
|
|
expect(parseAcceptLanguage('ar')).toBe('ar-SA');
|
|
expect(parseAcceptLanguage('ar-EG')).toBe('ar-SA');
|
|
});
|
|
|
|
it('应将 en* 映射为 en-US', () => {
|
|
expect(parseAcceptLanguage('en-US,en;q=0.9')).toBe('en-US');
|
|
expect(parseAcceptLanguage('en')).toBe('en-US');
|
|
expect(parseAcceptLanguage('en-GB')).toBe('en-US');
|
|
});
|
|
|
|
it('未识别语言应回退 en-US', () => {
|
|
expect(parseAcceptLanguage('fr-FR,fr;q=0.9')).toBe('en-US');
|
|
expect(parseAcceptLanguage('ja,en;q=0.1')).toBe('en-US');
|
|
expect(parseAcceptLanguage('')).toBe('en-US');
|
|
expect(parseAcceptLanguage(undefined)).toBe('en-US');
|
|
});
|
|
|
|
it('应按 q 值选择首选语言', () => {
|
|
expect(parseAcceptLanguage('en;q=0.4,zh-CN;q=0.9')).toBe('zh-CN');
|
|
expect(parseAcceptLanguage('ar;q=0.2,en-US;q=0.8')).toBe('en-US');
|
|
});
|
|
});
|
|
|
|
describe('parseGeoLocale', () => {
|
|
it('应将 CN/TW/HK 映射为 zh-CN', () => {
|
|
expect(parseGeoLocale({ 'cf-ipcountry': 'CN' })).toBe('zh-CN');
|
|
expect(parseGeoLocale({ 'x-country': 'TW' })).toBe('zh-CN');
|
|
expect(parseGeoLocale({ 'CF-IPCountry': 'hk' })).toBe('zh-CN');
|
|
});
|
|
|
|
it('应将 SA/AE/EG 映射为 ar-SA', () => {
|
|
expect(parseGeoLocale({ 'cf-ipcountry': 'SA' })).toBe('ar-SA');
|
|
expect(parseGeoLocale({ 'x-country': 'AE' })).toBe('ar-SA');
|
|
expect(parseGeoLocale({ 'X-Country': 'eg' })).toBe('ar-SA');
|
|
});
|
|
|
|
it('其余国家应回退 en-US', () => {
|
|
expect(parseGeoLocale({ 'cf-ipcountry': 'US' })).toBe('en-US');
|
|
expect(parseGeoLocale({ 'x-country': 'JP' })).toBe('en-US');
|
|
expect(parseGeoLocale({})).toBe('en-US');
|
|
expect(parseGeoLocale(undefined)).toBe('en-US');
|
|
});
|
|
|
|
it('应优先使用 cf-ipcountry 再回退 x-country', () => {
|
|
expect(
|
|
parseGeoLocale({
|
|
'cf-ipcountry': 'SA',
|
|
'x-country': 'CN',
|
|
})
|
|
).toBe('ar-SA');
|
|
expect(parseGeoLocale({ 'x-country': 'CN' })).toBe('zh-CN');
|
|
});
|
|
});
|
|
|
|
describe('resolveSuggestedLocale 优先级', () => {
|
|
it('query.lang 应优先于 Accept-Language 与 geo country', () => {
|
|
expect(
|
|
resolveSuggestedLocale({
|
|
lang: 'ar',
|
|
headers: {
|
|
'accept-language': 'zh-CN,zh;q=0.9',
|
|
'cf-ipcountry': 'US',
|
|
},
|
|
})
|
|
).toBe('ar-SA');
|
|
expect(
|
|
resolveSuggestedLocale({
|
|
lang: 'zh-TW',
|
|
headers: {
|
|
'accept-language': 'en-US',
|
|
'x-country': 'SA',
|
|
},
|
|
})
|
|
).toBe('zh-CN');
|
|
});
|
|
|
|
it('无 query.lang 时应采用 Accept-Language', () => {
|
|
expect(
|
|
resolveSuggestedLocale({
|
|
headers: {
|
|
'accept-language': 'ar-EG,ar;q=0.8',
|
|
'cf-ipcountry': 'US',
|
|
},
|
|
})
|
|
).toBe('ar-SA');
|
|
});
|
|
|
|
it('无 query.lang 与 Accept-Language 时应采用 geo country', () => {
|
|
expect(
|
|
resolveSuggestedLocale({
|
|
headers: {
|
|
'cf-ipcountry': 'HK',
|
|
},
|
|
})
|
|
).toBe('zh-CN');
|
|
expect(
|
|
resolveSuggestedLocale({
|
|
headers: {
|
|
'x-country': 'EG',
|
|
},
|
|
})
|
|
).toBe('ar-SA');
|
|
});
|
|
|
|
it('全无信号时应回退 en-US', () => {
|
|
expect(resolveSuggestedLocale({})).toBe('en-US');
|
|
expect(resolveSuggestedLocale({ lang: ' ', headers: {} })).toBe('en-US');
|
|
});
|
|
});
|
|
});
|