[MM-14058] Add support for i18n (#2190)

* Add language files

* Add react-intl, mmjstool, setup for adding translations

* Translated main module

* Translations for renderer

* A few minor fixes

* More fixes

* Add CI, add missing menu translations, other cleanup

* Added setting to manually select the language of the app

* Force English for E2e

* Unit tests

* Fix mmjstool

* Move set language to before update menu

* PR feedback
This commit is contained in:
Devin Binnie
2022-07-14 11:04:18 -04:00
committed by GitHub
parent 22c97591d5
commit 59e4e7e516
92 changed files with 3554 additions and 2375 deletions

View File

@@ -3,6 +3,7 @@
'use strict';
import {localizeMessage} from 'main/i18nManager';
import WindowManager from 'main/windows/windowManager';
import {createTemplate} from './app';
@@ -14,6 +15,10 @@ jest.mock('electron', () => ({
},
}));
jest.mock('main/i18nManager', () => ({
localizeMessage: jest.fn(),
}));
jest.mock('main/windows/windowManager', () => ({
getCurrentTeamName: jest.fn(),
}));
@@ -97,6 +102,12 @@ describe('main/menus/app', () => {
});
it('should include About <appname> in menu on mac', () => {
localizeMessage.mockImplementation((id) => {
if (id === 'main.menus.app.file.about') {
return 'About AppName';
}
return id;
});
const menu = createTemplate(config);
const appNameMenu = menu.find((item) => item.label === '&AppName');
const menuItem = appNameMenu.submenu.find((item) => item.label === 'About AppName');
@@ -105,23 +116,45 @@ describe('main/menus/app', () => {
});
it('should contain hide options', () => {
localizeMessage.mockImplementation((id) => {
if (id === 'main.menus.app.file') {
return '&AppName';
}
return id;
});
const menu = createTemplate(config);
const appNameMenu = menu.find((item) => item.label === '&AppName');
expect(appNameMenu.submenu).toContainEqual({role: 'hide'});
expect(appNameMenu.submenu).toContainEqual({role: 'unhide'});
expect(appNameMenu.submenu).toContainEqual({role: 'hideOthers'});
expect(appNameMenu.submenu).toContainEqual(expect.objectContaining({role: 'hide'}));
expect(appNameMenu.submenu).toContainEqual(expect.objectContaining({role: 'unhide'}));
expect(appNameMenu.submenu).toContainEqual(expect.objectContaining({role: 'hideOthers'}));
});
it('should contain zoom and front options in Window', () => {
localizeMessage.mockImplementation((id) => {
if (id === 'main.menus.app.window') {
return '&Window';
}
return id;
});
const menu = createTemplate(config);
const windowMenu = menu.find((item) => item.label === '&Window');
expect(windowMenu.role).toBe('windowMenu');
expect(windowMenu.submenu).toContainEqual({role: 'zoom'});
expect(windowMenu.submenu).toContainEqual({role: 'front'});
expect(windowMenu.submenu).toContainEqual(expect.objectContaining({role: 'zoom'}));
expect(windowMenu.submenu).toContainEqual(expect.objectContaining({role: 'front'}));
});
});
it('should show `Sign in to Another Server` if `enableServerManagement` is true', () => {
localizeMessage.mockImplementation((id) => {
switch (id) {
case 'main.menus.app.file':
return '&File';
case 'main.menus.app.file.signInToAnotherServer':
return 'Sign in to Another Server';
default:
return id;
}
});
const menu = createTemplate(config);
const fileMenu = menu.find((item) => item.label === '&AppName' || item.label === '&File');
const signInOption = fileMenu.submenu.find((item) => item.label === 'Sign in to Another Server');
@@ -129,6 +162,16 @@ describe('main/menus/app', () => {
});
it('should not show `Sign in to Another Server` if `enableServerManagement` is false', () => {
localizeMessage.mockImplementation((id) => {
switch (id) {
case 'main.menus.app.file':
return '&File';
case 'main.menus.app.file.signInToAnotherServer':
return 'Sign in to Another Server';
default:
return '';
}
});
const modifiedConfig = {
...config,
enableServerManagement: false,
@@ -140,6 +183,12 @@ describe('main/menus/app', () => {
});
it('should show the first 9 servers (using order) in the Window menu', () => {
localizeMessage.mockImplementation((id) => {
if (id === 'main.menus.app.window') {
return '&Window';
}
return id;
});
const modifiedConfig = {
data: {
...config.data,
@@ -174,6 +223,15 @@ describe('main/menus/app', () => {
});
it('should show the first 9 tabs (using order) in the Window menu', () => {
localizeMessage.mockImplementation((id) => {
if (id === 'main.menus.app.window') {
return '&Window';
}
if (id.startsWith('common.tabs')) {
return id.replace('common.tabs.', '');
}
return id;
});
WindowManager.getCurrentTeamName.mockImplementation(() => config.data.teams[0].name);
const modifiedConfig = {