From 260cf199bbb674176b4544d9a4440450ce886861 Mon Sep 17 00:00:00 2001 From: Rohit <40559587+Rohit3523@users.noreply.github.com> Date: Fri, 8 May 2026 21:54:33 +0530 Subject: [PATCH 1/3] fix --- app/views/UserPreferencesView/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/UserPreferencesView/index.tsx b/app/views/UserPreferencesView/index.tsx index 9baa99cfc8c..8af9e781842 100644 --- a/app/views/UserPreferencesView/index.tsx +++ b/app/views/UserPreferencesView/index.tsx @@ -52,7 +52,7 @@ const UserPreferencesView = ({ navigation }: IUserPreferencesViewProps): JSX.Ele const toggleConvertAsciiToEmoji = async (value: boolean) => { try { - dispatch(setUser({ settings: { ...settings, preferences: { convertAsciiEmoji: value } } } as Partial)); + dispatch(setUser({ settings: { ...settings, preferences: { ...settings?.preferences, convertAsciiEmoji: value } } } as Partial)); await saveUserPreferences({ convertAsciiEmoji: value }); } catch (e) { log(e); @@ -61,7 +61,7 @@ const UserPreferencesView = ({ navigation }: IUserPreferencesViewProps): JSX.Ele const toggleEnableMobileRinging = async (value: boolean) => { try { - dispatch(setUser({ settings: { ...settings, preferences: { enableMobileRinging: value } } } as Partial)); + dispatch(setUser({ settings: { ...settings, preferences: { ...settings?.preferences, enableMobileRinging: value } } } as Partial)); await saveUserPreferences({ enableMobileRinging: value }); } catch (e) { log(e); From fe88807e1fbc86b00769935cd4760e3e8f2f1bc8 Mon Sep 17 00:00:00 2001 From: Rohit3523 Date: Fri, 8 May 2026 16:28:55 +0000 Subject: [PATCH 2/3] chore: format code and fix lint issues --- app/views/UserPreferencesView/index.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/views/UserPreferencesView/index.tsx b/app/views/UserPreferencesView/index.tsx index 8af9e781842..85f80cefbab 100644 --- a/app/views/UserPreferencesView/index.tsx +++ b/app/views/UserPreferencesView/index.tsx @@ -52,7 +52,11 @@ const UserPreferencesView = ({ navigation }: IUserPreferencesViewProps): JSX.Ele const toggleConvertAsciiToEmoji = async (value: boolean) => { try { - dispatch(setUser({ settings: { ...settings, preferences: { ...settings?.preferences, convertAsciiEmoji: value } } } as Partial)); + dispatch( + setUser({ + settings: { ...settings, preferences: { ...settings?.preferences, convertAsciiEmoji: value } } + } as Partial) + ); await saveUserPreferences({ convertAsciiEmoji: value }); } catch (e) { log(e); @@ -61,7 +65,11 @@ const UserPreferencesView = ({ navigation }: IUserPreferencesViewProps): JSX.Ele const toggleEnableMobileRinging = async (value: boolean) => { try { - dispatch(setUser({ settings: { ...settings, preferences: { ...settings?.preferences, enableMobileRinging: value } } } as Partial)); + dispatch( + setUser({ + settings: { ...settings, preferences: { ...settings?.preferences, enableMobileRinging: value } } + } as Partial) + ); await saveUserPreferences({ enableMobileRinging: value }); } catch (e) { log(e); From 4f9260136815bc4635903d4606543d540cb7e92b Mon Sep 17 00:00:00 2001 From: Rohit <40559587+Rohit3523@users.noreply.github.com> Date: Fri, 15 May 2026 00:32:15 +0530 Subject: [PATCH 3/3] added unit test --- .../UserPreferencesView.test.tsx | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 app/views/UserPreferencesView/UserPreferencesView.test.tsx diff --git a/app/views/UserPreferencesView/UserPreferencesView.test.tsx b/app/views/UserPreferencesView/UserPreferencesView.test.tsx new file mode 100644 index 00000000000..27b47ee9ec3 --- /dev/null +++ b/app/views/UserPreferencesView/UserPreferencesView.test.tsx @@ -0,0 +1,117 @@ +import React from 'react'; +import { fireEvent, render, waitFor } from '@testing-library/react-native'; +import { useDispatch } from 'react-redux'; + +import UserPreferencesView from './index'; +import { useAppSelector } from '../../lib/hooks/useAppSelector'; +import { saveUserPreferences } from '../../lib/services/restApi'; + +jest.mock('react-redux', () => ({ + useDispatch: jest.fn() +})); + +jest.mock('../../lib/hooks/useAppSelector', () => ({ + useAppSelector: jest.fn() +})); + +jest.mock('../../lib/services/restApi', () => ({ + saveUserPreferences: jest.fn() +})); + +jest.mock('./ListPicker', () => () => null); + +describe('UserPreferencesView', () => { + const dispatch = jest.fn(); + const navigation = { + setOptions: jest.fn(), + navigate: jest.fn() + }; + + const mockState = ({ + convertAsciiEmoji, + enableMobileRinging + }: { + convertAsciiEmoji: boolean; + enableMobileRinging: boolean; + }) => ({ + login: { + user: { + id: 'user-id', + enableMessageParserEarlyAdoption: false, + alsoSendThreadToChannel: 'default', + settings: { + preferences: { + convertAsciiEmoji, + enableMobileRinging + } + } + } + }, + server: { + version: '6.10.0' + } + }); + + const renderWithPreferences = (preferences: { convertAsciiEmoji: boolean; enableMobileRinging: boolean }) => { + (useAppSelector as jest.Mock).mockImplementation((selector: (state: any) => unknown) => selector(mockState(preferences))); + return render(); + }; + + beforeEach(() => { + jest.clearAllMocks(); + (useDispatch as jest.Mock).mockReturnValue(dispatch); + (saveUserPreferences as jest.Mock).mockResolvedValue(undefined); + }); + + it('keeps enableMobileRinging enabled while enabling convertAsciiEmoji', async () => { + const { getByTestId } = renderWithPreferences({ convertAsciiEmoji: false, enableMobileRinging: true }); + + fireEvent(getByTestId('preferences-view-convert-ascii-to-emoji'), 'valueChange', true); + + const dispatchedUser = dispatch.mock.calls[0][0].user; + expect(dispatchedUser.settings.preferences).toEqual({ + convertAsciiEmoji: true, + enableMobileRinging: true + }); + await waitFor(() => expect(saveUserPreferences).toHaveBeenCalledWith({ convertAsciiEmoji: true })); + }); + + it('keeps enableMobileRinging disabled while disabling convertAsciiEmoji', async () => { + const { getByTestId } = renderWithPreferences({ convertAsciiEmoji: true, enableMobileRinging: false }); + + fireEvent(getByTestId('preferences-view-convert-ascii-to-emoji'), 'valueChange', false); + + const dispatchedUser = dispatch.mock.calls[0][0].user; + expect(dispatchedUser.settings.preferences).toEqual({ + convertAsciiEmoji: false, + enableMobileRinging: false + }); + await waitFor(() => expect(saveUserPreferences).toHaveBeenCalledWith({ convertAsciiEmoji: false })); + }); + + it('keeps convertAsciiEmoji enabled while enabling enableMobileRinging', async () => { + const { getByTestId } = renderWithPreferences({ convertAsciiEmoji: true, enableMobileRinging: false }); + + fireEvent(getByTestId('preferences-view-enable-mobile-ringing'), 'valueChange', true); + + const dispatchedUser = dispatch.mock.calls[0][0].user; + expect(dispatchedUser.settings.preferences).toEqual({ + convertAsciiEmoji: true, + enableMobileRinging: true + }); + await waitFor(() => expect(saveUserPreferences).toHaveBeenCalledWith({ enableMobileRinging: true })); + }); + + it('keeps convertAsciiEmoji disabled while disabling enableMobileRinging', async () => { + const { getByTestId } = renderWithPreferences({ convertAsciiEmoji: false, enableMobileRinging: true }); + + fireEvent(getByTestId('preferences-view-enable-mobile-ringing'), 'valueChange', false); + + const dispatchedUser = dispatch.mock.calls[0][0].user; + expect(dispatchedUser.settings.preferences).toEqual({ + convertAsciiEmoji: false, + enableMobileRinging: false + }); + await waitFor(() => expect(saveUserPreferences).toHaveBeenCalledWith({ enableMobileRinging: false })); + }); +});