123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- 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': '<script>alert("test")</script>',
- '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', '<script>alert("test")</script>');
- 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', '患者管理');
- });
- });
- });
|