import { mockI18nInvalidFormat, mockI18nEmptyData, mockAllRequiredAPIs } from '../../support/mock/handlers/i18n';
import LoginPage from '../../support/pageObjects/LoginPage';
describe('多语言资源格式异常测试', () => {
const loginPage = new LoginPage();
beforeEach(() => {
cy.clearAllSessionStorage();
cy.clearAllLocalStorage();
// Mock所有必要的API,避免影响页面加载
mockAllRequiredAPIs();
});
it('API返回非JSON格式数据时正确处理', () => {
mockI18nInvalidFormat('zh');
cy.window().then((win) => {
Object.defineProperty(win.navigator, 'language', {
value: 'zh-CN',
writable: false
});
});
loginPage.visit();
cy.wait('@getI18nZHInvalidFormat');
// 验证错误提示显示
cy.contains('多语言资源加载失败').should('be.visible');
cy.contains('重新加载').should('be.visible');
// 验证Redux状态反映错误
cy.window().its('store').invoke('getState').then((state) => {
expect(state.i18n.loading).to.be.false;
expect(state.i18n.error).to.not.be.null;
expect(state.i18n.messages).to.deep.equal({});
});
});
it('API返回空对象时正确处理', () => {
mockI18nEmptyData('en');
cy.window().then((win) => {
Object.defineProperty(win.navigator, 'language', {
value: 'en-US',
writable: false
});
});
loginPage.visit();
cy.wait('@getI18nENEmptyData');
// 空数据应该被正常处理,不显示错误
cy.contains('多语言资源加载失败').should('not.exist');
// 验证Redux状态
cy.window().its('store').invoke('getState').then((state) => {
expect(state.i18n.loading).to.be.false;
expect(state.i18n.error).to.be.null;
expect(state.i18n.currentLocale).to.equal('en');
expect(state.i18n.messages).to.deep.equal({});
});
});
it('API返回null数据时正确处理', () => {
cy.intercept('GET', '/dr/api/v1/pub/trans/zh/zh.js', (req) => {
req.reply({
statusCode: 200,
body: null
});
}).as('getI18nZHNull');
cy.window().then((win) => {
Object.defineProperty(win.navigator, 'language', {
value: 'zh-CN',
writable: false
});
});
loginPage.visit();
cy.wait('@getI18nZHNull');
// 验证错误处理
cy.contains('多语言资源加载失败').should('be.visible');
// 验证Redux状态
cy.window().its('store').invoke('getState').then((state) => {
expect(state.i18n.loading).to.be.false;
expect(state.i18n.error).to.not.be.null;
});
});
it('API返回数组格式数据时正确处理', () => {
cy.intercept('GET', '/dr/api/v1/pub/trans/en/en.js', (req) => {
req.reply({
statusCode: 200,
body: ['invalid', 'array', 'format']
});
}).as('getI18nENArray');
cy.window().then((win) => {
Object.defineProperty(win.navigator, 'language', {
value: 'en-US',
writable: false
});
});
loginPage.visit();
cy.wait('@getI18nENArray');
// 数组格式应该被当作错误处理
cy.contains('多语言资源加载失败').should('be.visible');
// 验证Redux状态
cy.window().its('store').invoke('getState').then((state) => {
expect(state.i18n.loading).to.be.false;
expect(state.i18n.error).to.not.be.null;
});
});
it('API返回部分缺失字段的数据时正确处理', () => {
cy.intercept('GET', '/dr/api/v1/pub/trans/zh/zh.js', (req) => {
req.reply({
statusCode: 200,
body: {
// 只有部分字段
greeting: '你好',
// 缺少其他必要字段
}
});
}).as('getI18nZHPartial');
cy.window().then((win) => {
Object.defineProperty(win.navigator, 'language', {
value: 'zh-CN',
writable: false
});
});
loginPage.visit();
cy.wait('@getI18nZHPartial');
// 部分数据应该被正常处理
cy.contains('多语言资源加载失败').should('not.exist');
// 验证Redux状态包含部分数据
cy.window().its('store').invoke('getState').then((state) => {
expect(state.i18n.loading).to.be.false;
expect(state.i18n.error).to.be.null;
expect(state.i18n.currentLocale).to.equal('zh');
expect(state.i18n.messages).to.have.property('greeting', '你好');
expect(state.i18n.messages).to.not.have.property('patient');
});
});
it('API返回包含特殊字符的数据时正确处理', () => {
cy.intercept('GET', '/dr/api/v1/pub/trans/en/en.js', (req) => {
req.reply({
statusCode: 200,
body: {
'special.key': 'Value with special chars: @#$%^&*()',
'unicode.key': '测试 Unicode 字符 🚀 ✅ ❌',
'html.key': '',
'json.key': '{"nested": "json"}',
'empty.key': '',
'space.key': ' ',
'newline.key': 'Line 1\nLine 2\nLine 3'
}
});
}).as('getI18nENSpecial');
cy.window().then((win) => {
Object.defineProperty(win.navigator, 'language', {
value: 'en-US',
writable: false
});
});
loginPage.visit();
cy.wait('@getI18nENSpecial');
// 特殊字符数据应该被正常处理
cy.contains('多语言资源加载失败').should('not.exist');
// 验证Redux状态包含特殊字符数据
cy.window().its('store').invoke('getState').then((state) => {
expect(state.i18n.loading).to.be.false;
expect(state.i18n.error).to.be.null;
expect(state.i18n.currentLocale).to.equal('en');
expect(state.i18n.messages).to.have.property('special.key', 'Value with special chars: @#$%^&*()');
expect(state.i18n.messages).to.have.property('unicode.key', '测试 Unicode 字符 🚀 ✅ ❌');
expect(state.i18n.messages).to.have.property('html.key', '');
expect(state.i18n.messages).to.have.property('empty.key', '');
});
});
it('API返回超大数据时正确处理', () => {
// 生成大量数据
const largeData = {};
for (let i = 0; i < 1000; i++) {
largeData[`key_${i}`] = `Value ${i} - ${'x'.repeat(100)}`;
}
cy.intercept('GET', '/dr/api/v1/pub/trans/zh/zh.js', (req) => {
req.reply({
statusCode: 200,
body: largeData
});
}).as('getI18nZHLarge');
cy.window().then((win) => {
Object.defineProperty(win.navigator, 'language', {
value: 'zh-CN',
writable: false
});
});
loginPage.visit();
cy.wait('@getI18nZHLarge');
// 大数据应该被正常处理
cy.contains('多语言资源加载失败').should('not.exist');
// 验证Redux状态包含大量数据
cy.window().its('store').invoke('getState').then((state) => {
expect(state.i18n.loading).to.be.false;
expect(state.i18n.error).to.be.null;
expect(state.i18n.currentLocale).to.equal('zh');
expect(Object.keys(state.i18n.messages)).to.have.length(1000);
expect(state.i18n.messages).to.have.property('key_0', 'Value 0 - ' + 'x'.repeat(100));
expect(state.i18n.messages).to.have.property('key_999', 'Value 999 - ' + 'x'.repeat(100));
});
});
it('验证格式异常后的重新加载功能', () => {
// 首先返回无效格式
mockI18nInvalidFormat('zh');
cy.window().then((win) => {
Object.defineProperty(win.navigator, 'language', {
value: 'zh-CN',
writable: false
});
});
loginPage.visit();
cy.wait('@getI18nZHInvalidFormat');
// 验证错误显示
cy.contains('多语言资源加载失败').should('be.visible');
cy.contains('重新加载').should('be.visible');
// 设置正确的mock用于重新加载
cy.intercept('GET', '/dr/api/v1/pub/trans/zh/zh.js', (req) => {
req.reply({
statusCode: 200,
body: {
greeting: '你好,世界!',
patient: '患者管理'
}
});
}).as('getI18nZHFixed');
// 点击重新加载
cy.contains('重新加载').click();
cy.wait('@getI18nZHFixed');
// 验证成功加载
cy.contains('多语言资源加载失败').should('not.exist');
cy.get('body').should('contain', '患者管理');
// 验证Redux状态恢复正常
cy.window().its('store').invoke('getState').then((state) => {
expect(state.i18n.loading).to.be.false;
expect(state.i18n.error).to.be.null;
expect(state.i18n.currentLocale).to.equal('zh');
expect(state.i18n.messages).to.have.property('patient', '患者管理');
});
});
});