-
Notifications
You must be signed in to change notification settings - Fork 303
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: evgeniy/92724/language settings improvements #8176
Changes from 106 commits
5242db6
ffeeb19
ff4b10c
4ae4d10
df0c7fc
228311e
16604ee
b0da01a
f1a6457
43769d9
f9cc1ef
d7ccb1d
1dd5a15
3fc2275
599947d
eece872
47248a5
fda654b
f24ddf0
c85f08a
17a2eea
78f44aa
a1fffd5
c3c60e9
bc05d93
0e8f1ac
3f35548
f776de6
3ffbc18
b82865f
9224b24
34697ac
02ab4c2
9e5b301
44278eb
12b40a6
fc1fb05
135609b
05d4ec0
55e3cdf
c5e5891
9a201a4
baabdf7
e89eb92
e6f5a62
e5ffced
51a8b62
b6601b8
104b761
736c9a7
a87b127
ddb6fcf
2622b42
d42f376
f85a888
1a8fc83
201ee04
0d2b954
794a1de
44218ec
d82d363
4c6515d
1f77c90
7de08a6
3a90d8f
ebeb1fd
b3a8916
39010d3
52e0f85
a7e3a39
70ce7dc
3b22b1d
89c1102
a7dbe08
8dee5c9
a5d332b
e040848
04d0364
af89cf9
2757de7
192513d
df3c3aa
15df534
9be963e
08d49d5
7bd78a7
01557c7
58d9947
02f34f1
28e6b24
d27b49c
2edc963
fd69ce7
7b3950a
305998b
a5ac6aa
d0c1ce1
901e88f
be34e3a
d3d8ed2
f3a175c
080505c
e88e1a1
4eb91b4
8f8d5e4
2e48362
4ddceac
2625ce4
bbcd91c
72d8dde
d1d9444
543d5dd
ba6d487
2c2c51f
9903ad0
60819f4
8ecc541
df80ad5
625f38f
16ca4d6
a480137
d355840
f31859a
9c1070b
cd9c87c
e8c2898
343b91c
5e2beb8
d1e1889
e9ea5f9
6518515
2e5c710
911c54a
d6decc2
5d95d8f
f798c1c
70b74c5
266361a
d498ee1
32188d5
02b56be
aa7bf7f
02b1e32
b247774
127a787
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import React from 'react'; | ||
import { screen, render } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
import { isMobile, routes } from '@deriv/shared'; | ||
import LanguageSettings from '../language-settings'; | ||
import { mockStore, StoreProvider } from '@deriv/stores'; | ||
|
||
jest.mock('@deriv/shared', () => ({ | ||
...jest.requireActual('@deriv/shared'), | ||
isMobile: jest.fn(() => false), | ||
})); | ||
|
||
jest.mock('@deriv/translations', () => ({ | ||
...jest.requireActual('@deriv/translations'), | ||
getAllowedLanguages: jest.fn(() => ({ lang_1: 'Test Lang 1', lang_2: 'Test Lang 2' })), | ||
})); | ||
|
||
jest.mock('@deriv/components', () => ({ | ||
...jest.requireActual('@deriv/components'), | ||
Icon: jest.fn(() => <div>Flag Icon</div>), | ||
})); | ||
|
||
jest.mock('react-i18next', () => ({ | ||
...jest.requireActual('react-i18next'), | ||
useTranslation: jest.fn(() => ({ i18n: { changeLanguage: jest.fn() } })), | ||
})); | ||
|
||
jest.mock('react-router-dom', () => ({ | ||
...jest.requireActual('react-router-dom'), | ||
Redirect: jest.fn(() => <div>Redirect</div>), | ||
})); | ||
|
||
describe('LanguageSettings', () => { | ||
const mockRootStore = mockStore({ | ||
common: { | ||
current_language: 'lang_1', | ||
}, | ||
}); | ||
|
||
const renderLanguageSettings = () => { | ||
render(<LanguageSettings />, { | ||
wrapper: ({ children }) => <StoreProvider store={mockRootStore}>{children}</StoreProvider>, | ||
}); | ||
}; | ||
|
||
it('should render LanguageSettings', () => { | ||
renderLanguageSettings(); | ||
|
||
expect(screen.getByText('Select Language')).toBeInTheDocument(); | ||
|
||
const flags_icons = screen.getAllByText('Flag Icon'); | ||
const lang_1 = screen.getByText('Test Lang 1'); | ||
const lang_2 = screen.getByText('Test Lang 2'); | ||
|
||
expect(flags_icons.length).toBe(2); | ||
expect(lang_1).toBeInTheDocument(); | ||
expect(/(active)/i.test(lang_1.className)).toBeTruthy(); | ||
expect(lang_2).toBeInTheDocument(); | ||
expect(/(active)/i.test(lang_2.className)).toBeFalsy(); | ||
}); | ||
|
||
it('should trigger language change', () => { | ||
renderLanguageSettings(); | ||
|
||
const lang_2 = screen.getByText('Test Lang 2'); | ||
userEvent.click(lang_2); | ||
|
||
expect(mockRootStore.common.changeSelectedLanguage).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should redirect for mobile', () => { | ||
(isMobile as jest.Mock).mockReturnValue(true); | ||
Object.defineProperty(window, 'location', { | ||
configurable: true, | ||
value: { pathname: routes.languages }, | ||
}); | ||
|
||
renderLanguageSettings(); | ||
|
||
expect(screen.queryByText('Select Language')).not.toBeInTheDocument(); | ||
expect(screen.getByText('Redirect')).toBeInTheDocument(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import MenuTitle from './menu-title'; | ||
import MobileLanguageMenu from './mobile-language-menu'; | ||
|
||
export { MenuTitle, MobileLanguageMenu }; |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,39 @@ | ||||||||||
import React from 'react'; | ||||||||||
import { observer, useStore } from '@deriv/stores'; | ||||||||||
import { Icon, Text } from '@deriv/components'; | ||||||||||
import { localize, Localize } from '@deriv/translations'; | ||||||||||
|
||||||||||
const MenuTitle = observer(() => { | ||||||||||
const { common, ui } = useStore(); | ||||||||||
const { current_language } = common; | ||||||||||
const { is_mobile_language_menu_open, setMobileLanguageMenuOpen } = ui; | ||||||||||
return ( | ||||||||||
<React.Fragment> | ||||||||||
<div>{localize('Menu')}</div> | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use Localize component instead of localize function inside your component! ( this is really important, our components need to be attached to react life cycle, so basically using
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @niloofar-deriv What's the reason behind it? 🤔 Do they behave differently? 🤔 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Michio suggested this when we were refactoring the deriv.com's translations There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @niloofar-deriv The script for extracting strings in deriv-com is different 👀 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But the rules of React are the same 👀 Anyways we can ignore this comment 🙏 |
||||||||||
<div | ||||||||||
className='settings-language__language-button_wrapper' | ||||||||||
onClick={() => { | ||||||||||
if (!is_mobile_language_menu_open) { | ||||||||||
setMobileLanguageMenuOpen(true); | ||||||||||
} | ||||||||||
}} | ||||||||||
> | ||||||||||
{!is_mobile_language_menu_open && ( | ||||||||||
<React.Fragment> | ||||||||||
<Icon | ||||||||||
icon={`IcFlag${current_language.replace('_', '-')}`} | ||||||||||
data_testid='dt_icon' | ||||||||||
className='ic-settings-language__icon' | ||||||||||
size={22} | ||||||||||
/> | ||||||||||
<Text weight='bold' size='xxs'> | ||||||||||
<Localize i18n_default_text={current_language} /> | ||||||||||
</Text> | ||||||||||
</React.Fragment> | ||||||||||
)} | ||||||||||
</div> | ||||||||||
</React.Fragment> | ||||||||||
); | ||||||||||
}); | ||||||||||
|
||||||||||
export default MenuTitle; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import classNames from 'classnames'; | ||
import React from 'react'; | ||
import { MobileDrawer } from '@deriv/components'; | ||
import { observer, useStore } from '@deriv/stores'; | ||
import { getAllowedLanguages, localize } from '@deriv/translations'; | ||
import { LanguageLink } from 'App/Components/Routes'; | ||
|
||
type TMobileLanguageMenu = { | ||
expandSubMenu: (prop: boolean) => void; | ||
toggleDrawer: () => void; | ||
}; | ||
|
||
const MobileLanguageMenu = observer(({ expandSubMenu, toggleDrawer }: TMobileLanguageMenu) => { | ||
const { common, ui } = useStore(); | ||
const { is_language_changing } = common; | ||
const { is_mobile_language_menu_open, setMobileLanguageMenuOpen } = ui; | ||
return ( | ||
<MobileDrawer.SubMenu | ||
is_expanded={is_mobile_language_menu_open} | ||
has_subheader | ||
submenu_title={localize('Language')} | ||
onToggle={is_expanded => { | ||
expandSubMenu(is_expanded); | ||
setMobileLanguageMenuOpen(false); | ||
}} | ||
submenu_toggle_class='dc-mobile-drawer__submenu-toggle--hidden' | ||
> | ||
<div | ||
className={classNames('settings-language__language-container', { | ||
'settings-language__language-container--disabled': is_language_changing, | ||
})} | ||
> | ||
{Object.keys(getAllowedLanguages()).map(lang => ( | ||
<LanguageLink | ||
key={lang} | ||
icon_classname='settings-language__language-flag' | ||
is_clickable | ||
lang={lang} | ||
toggleModal={() => { | ||
toggleDrawer(); | ||
setMobileLanguageMenuOpen(false); | ||
}} | ||
/> | ||
))} | ||
</div> | ||
</MobileDrawer.SubMenu> | ||
); | ||
}); | ||
|
||
export default MobileLanguageMenu; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mock hell 😂