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', '患者管理'); }); }); });