Skip to content

Commit

Permalink
fix: discard changes of timezone, locale and dark mode reset initial …
Browse files Browse the repository at this point in the history
…values

refs: SHELL-161 (#346)
  • Loading branch information
CataldoMazzilli authored Oct 23, 2023
1 parent bb1a575 commit 0b1abed
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,33 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';

import { Select, SelectItem, SingleSelectionOnChange, Text } from '@zextras/carbonio-design-system';
import { find } from 'lodash';

import type { AddMod, DarkReaderPropValues, RemoveMod } from '../../../../types';
import { ThemeCallbacksContext } from '../../../boot/theme-provider';
import { DARK_READER_PROP_KEY, SHELL_APP_ID } from '../../../constants';
import {
isDarkReaderPropValues,
useDarkReaderResultValue
} from '../../../dark-mode/use-dark-reader-result-value';
import { getT } from '../../../store/i18n';
import { useReset } from '../../hooks/use-reset';
import { SettingsSectionProps } from '../utils';

type DarkReaderSelectItem = Array<SelectItem & { value: DarkReaderPropValues }>;

interface DarkThemeSettingSectionProps {
interface DarkThemeSettingSectionProps extends SettingsSectionProps {
addMod: AddMod;
removeMod: RemoveMod;
}

const DarkThemeSettingSection = ({
addMod,
removeMod
removeMod,
resetRef
}: DarkThemeSettingSectionProps): React.JSX.Element | null => {
const { setDarkReaderState } = useContext(ThemeCallbacksContext);
const darkReaderResultValue = useDarkReaderResultValue();
const [selection, setSelection] = useState<SelectItem>();

Expand Down Expand Up @@ -58,9 +59,8 @@ const DarkThemeSettingSection = ({
if (item) {
setSelection(item);
}
setDarkReaderState(value);
},
[items, setDarkReaderState]
[items]
);

const onSelectionChange = useCallback<SingleSelectionOnChange>(
Expand All @@ -85,6 +85,14 @@ const DarkThemeSettingSection = ({
}
}, [darkReaderResultValue, items, setSelectNewValue]);

const init = useCallback(() => {
if (darkReaderResultValue) {
setSelectNewValue(darkReaderResultValue);
}
}, [darkReaderResultValue, setSelectNewValue]);

useReset(resetRef, init);

if (!selection) {
return null;
}
Expand Down
102 changes: 102 additions & 0 deletions src/settings/general-settings.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* SPDX-FileCopyrightText: 2023 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import React from 'react';

import 'jest-styled-components';
import { screen, within } from '@testing-library/react';
import { find } from 'lodash';

import {
LocaleDescriptorWithLabels,
localeList,
TimeZoneDescriptor,
timeZoneList
} from './components/utils';
import GeneralSettings from './general-settings';
import { useAccountStore } from '../store/account';
import { useI18nStore } from '../store/i18n';
import { TESTID_SELECTORS } from '../test/constants';
import { setup } from '../test/utils';

describe('General setting', () => {
const { defaultI18n } = useI18nStore.getState();
const timeZoneArray = timeZoneList(defaultI18n.t);
const localeArray = localeList(defaultI18n.t);
test('When timezone is changed, discard button become enabled and when clicked the initial value is restored', async () => {
const zimbraPrefTimeZoneIdValue = 'UTC';

useAccountStore.setState((previousState) => ({
...previousState,
settings: {
...previousState.settings,
prefs: { zimbraPrefTimeZoneId: zimbraPrefTimeZoneIdValue }
}
}));
const { user } = setup(<GeneralSettings />);
const match = find(
timeZoneArray,
(item) => item.value === zimbraPrefTimeZoneIdValue
) as TimeZoneDescriptor;
expect(match).toBeDefined();
expect(screen.getByText(match.label)).toBeVisible();
expect(screen.getByRole('button', { name: /discard changes/i })).toBeDisabled();
await user.click(screen.getByText(match.label));
await user.click(
within(screen.getByTestId(TESTID_SELECTORS.dropdown)).getByText(timeZoneArray[0].label)
);
expect(screen.getByRole('button', { name: /discard changes/i })).toBeEnabled();
await user.click(screen.getByRole('button', { name: /discard changes/i }));
expect(screen.getByText(match.label)).toBeVisible();
expect(screen.getByRole('button', { name: /discard changes/i })).toBeDisabled();
});

test('When locale is changed, discard button become enabled and when clicked the initial value is restored', async () => {
const zimbraPrefLocaleValue = 'en';

useAccountStore.setState((previousState) => ({
...previousState,
settings: {
...previousState.settings,
prefs: { zimbraPrefLocale: zimbraPrefLocaleValue }
}
}));
const { user } = setup(<GeneralSettings />);
const match = find(
localeArray,
(item) => item.value === zimbraPrefLocaleValue
) as LocaleDescriptorWithLabels;
expect(match).toBeDefined();
expect(screen.getByText(match.label)).toBeVisible();
expect(screen.getByRole('button', { name: /discard changes/i })).toBeDisabled();
await user.click(screen.getByText(match.label));
await user.click(
within(screen.getByTestId(TESTID_SELECTORS.dropdown)).getByText(localeArray[0].label)
);
expect(screen.getByRole('button', { name: /discard changes/i })).toBeEnabled();
await user.click(screen.getByRole('button', { name: /discard changes/i }));
expect(screen.getByText(match.label)).toBeVisible();
expect(screen.getByRole('button', { name: /discard changes/i })).toBeDisabled();
});

test('When dark mode is changed, discard button become enabled and when clicked the initial value is restored', async () => {
useAccountStore.setState((previousState) => ({
...previousState,
settings: {
...previousState.settings,
props: [{ name: 'zappDarkreaderMode', zimlet: 'carbonio-shell-ui', _content: 'auto' }]
}
}));
const { user } = setup(<GeneralSettings />);
expect(screen.getByText('Auto')).toBeVisible();
expect(screen.getByRole('button', { name: /discard changes/i })).toBeDisabled();
await user.click(screen.getByText('Auto'));
await user.click(within(screen.getByTestId(TESTID_SELECTORS.dropdown)).getByText(/disabled/i));
expect(screen.getByRole('button', { name: /discard changes/i })).toBeEnabled();
await user.click(screen.getByRole('button', { name: /discard changes/i }));
expect(screen.getByText('Auto')).toBeVisible();
expect(screen.getByRole('button', { name: /discard changes/i })).toBeDisabled();
});
});
13 changes: 11 additions & 2 deletions src/settings/general-settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { SearchSettings } from './components/general-settings/search-settings';
import UserQuota from './components/general-settings/user-quota';
import SettingsHeader, { SettingsHeaderProps } from './components/settings-header';
import { ResetComponentImperativeHandler } from './components/utils';
import LanguageAndTimeZoneSettings from './language-and-timezone-settings';
import { LanguageAndTimeZoneSettings } from './language-and-timezone-settings';
import {
AccountState,
AddMod,
Expand Down Expand Up @@ -215,6 +215,8 @@ const GeneralSettings = (): React.JSX.Element => {
}, [mods, setLocalStorageSettings, createSnackbar, t]);

const scalingSettingSectionRef = useRef<ResetComponentImperativeHandler>(null);
const darkThemeSettingSectionRef = useRef<ResetComponentImperativeHandler>(null);
const languageAndTimeZoneSettingsSectionRef = useRef<ResetComponentImperativeHandler>(null);
const outOfOfficeSettingsSectionRef = useRef<ResetComponentImperativeHandler>(null);
const searchSettingsSectionRef = useRef<ResetComponentImperativeHandler>(null);

Expand All @@ -223,6 +225,8 @@ const GeneralSettings = (): React.JSX.Element => {
if (size(localStorageUnAppliedChanges) > 0) {
scalingSettingSectionRef.current?.reset();
}
darkThemeSettingSectionRef.current?.reset();
languageAndTimeZoneSettingsSectionRef.current?.reset();
outOfOfficeSettingsSectionRef.current?.reset();
searchSettingsSectionRef?.current?.reset();
}, [localStorageUnAppliedChanges]);
Expand Down Expand Up @@ -252,13 +256,18 @@ const GeneralSettings = (): React.JSX.Element => {
addLocalStoreChange={addLocalStoreChange}
cleanLocalStoreChange={cleanLocalStoreChange}
/>
<DarkThemeSettingSection addMod={addMod} removeMod={removeMod} />
<DarkThemeSettingSection
resetRef={darkThemeSettingSectionRef}
addMod={addMod}
removeMod={removeMod}
/>
</AppearanceSettings>
<LanguageAndTimeZoneSettings
settings={userSettings}
addMod={addMod}
open={open}
setOpen={setOpen}
resetRef={languageAndTimeZoneSettingsSectionRef}
/>

<OutOfOfficeSettings
Expand Down
Loading

0 comments on commit 0b1abed

Please sign in to comment.