[MM-64358] Don't send custom profile info if the feature is not enabled (#8904)
* don't send custom profile info if the feature is not enabled * add tests * missing changes * missing check --------- Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
parent
cdd91dbbb8
commit
efeabb48a2
2 changed files with 219 additions and 4 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {act} from '@testing-library/react-hooks';
|
||||
import {fireEvent} from '@testing-library/react-native';
|
||||
import {fireEvent, screen, waitFor} from '@testing-library/react-native';
|
||||
import React from 'react';
|
||||
|
||||
import AvailableScreens from '@constants/screens';
|
||||
|
|
@ -67,9 +67,19 @@ jest.mock('@context/server', () => ({
|
|||
// Mock for custom profile attributes API
|
||||
const mockFetchCustomProfileAttributes = jest.fn();
|
||||
|
||||
// Add mock for updateCustomProfileAttributes to track calls
|
||||
const mockUpdateCustomProfileAttributes = jest.fn();
|
||||
|
||||
// Mock logError function
|
||||
const mockLogError = jest.fn();
|
||||
|
||||
jest.mock('@actions/remote/custom_profile', () => ({
|
||||
fetchCustomProfileAttributes: (...args: any[]) => mockFetchCustomProfileAttributes(...args),
|
||||
updateCustomProfileAttributes: jest.fn().mockResolvedValue({success: true, error: undefined}),
|
||||
updateCustomProfileAttributes: (...args: any[]) => mockUpdateCustomProfileAttributes(...args),
|
||||
}));
|
||||
|
||||
jest.mock('@utils/log', () => ({
|
||||
logError: (...args: any[]) => mockLogError(...args),
|
||||
}));
|
||||
|
||||
jest.mock('@actions/remote/user', () => ({
|
||||
|
|
@ -155,6 +165,12 @@ describe('EditProfile', () => {
|
|||
attributes: serverAttributesSet,
|
||||
error: undefined,
|
||||
}));
|
||||
|
||||
// Reset updateCustomProfileAttributes mock
|
||||
mockUpdateCustomProfileAttributes.mockResolvedValue({success: true, error: undefined});
|
||||
|
||||
// Reset logError mock
|
||||
mockLogError.mockClear();
|
||||
});
|
||||
|
||||
it('should update custom attribute value while preserving name and sort order', async () => {
|
||||
|
|
@ -388,4 +404,201 @@ describe('EditProfile', () => {
|
|||
const newAttributeItem = await findAllByTestId('edit_profile_form.customAttributes.attr4.input');
|
||||
expect(newAttributeItem[0].props.value).toBe('new db value');
|
||||
});
|
||||
|
||||
describe('Submission Logic', () => {
|
||||
it('should update custom attributes when enableCustomAttributes is true and customAttributes exist', async () => {
|
||||
renderWithIntlAndTheme(
|
||||
<EditProfile
|
||||
componentId={AvailableScreens.EDIT_PROFILE}
|
||||
currentUser={mockCurrentUser}
|
||||
isModal={false}
|
||||
isTablet={true}
|
||||
lockedFirstName={false}
|
||||
lockedLastName={false}
|
||||
lockedNickname={false}
|
||||
lockedPosition={false}
|
||||
lockedPicture={false}
|
||||
enableCustomAttributes={true}
|
||||
userCustomAttributes={[]}
|
||||
customFields={[]}
|
||||
customAttributesSet={serverAttributesSet}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Wait for component to load and custom attributes to be fetched
|
||||
await waitFor(async() => {
|
||||
const customAttributeItems = await screen.findAllByTestId(new RegExp('^edit_profile_form.customAttributes.attr[0-9]+.input$'));
|
||||
expect(customAttributeItems.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
// Modify a field to trigger the hasUpdateUserInfo flag
|
||||
await act(async () => {
|
||||
const customAttributeItems = await screen.findAllByTestId(new RegExp('^edit_profile_form.customAttributes.attr[0-9]+.input$'));
|
||||
fireEvent.changeText(customAttributeItems[0], 'modified value');
|
||||
});
|
||||
|
||||
// Trigger form submission
|
||||
const saveButton = screen.getByTestId('edit_profile.save.button');
|
||||
await act(async () => {
|
||||
fireEvent.press(saveButton);
|
||||
});
|
||||
|
||||
// Verify that updateCustomProfileAttributes was called
|
||||
expect(mockUpdateCustomProfileAttributes).toHaveBeenCalledWith(
|
||||
'http://localhost:8065',
|
||||
'user1',
|
||||
expect.objectContaining({
|
||||
attr1: expect.objectContaining({
|
||||
value: 'modified value',
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should not update custom attributes when enableCustomAttributes is false', async () => {
|
||||
const {getByTestId} = renderWithIntlAndTheme(
|
||||
<EditProfile
|
||||
componentId={AvailableScreens.EDIT_PROFILE}
|
||||
currentUser={mockCurrentUser}
|
||||
isModal={false}
|
||||
isTablet={true}
|
||||
lockedFirstName={false}
|
||||
lockedLastName={false}
|
||||
lockedNickname={false}
|
||||
lockedPosition={false}
|
||||
lockedPicture={false}
|
||||
enableCustomAttributes={false}
|
||||
userCustomAttributes={[]}
|
||||
customFields={[]}
|
||||
customAttributesSet={serverAttributesSet}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Wait for component to load
|
||||
await act(async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
});
|
||||
|
||||
// Modify a standard field to trigger the hasUpdateUserInfo flag
|
||||
const firstNameField = getByTestId('edit_profile_form.firstName.input');
|
||||
await act(async () => {
|
||||
fireEvent.changeText(firstNameField, 'Modified John');
|
||||
});
|
||||
|
||||
// Trigger form submission
|
||||
const saveButton = getByTestId('edit_profile.save.button');
|
||||
await act(async () => {
|
||||
fireEvent.press(saveButton);
|
||||
});
|
||||
|
||||
// Verify that updateCustomProfileAttributes was NOT called
|
||||
expect(mockUpdateCustomProfileAttributes).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call updateCustomProfileAttributes with empty object when customAttributes is empty', async () => {
|
||||
// Mock server fetch to return empty attributes for this test
|
||||
mockFetchCustomProfileAttributes.mockResolvedValue({
|
||||
attributes: {},
|
||||
error: undefined,
|
||||
});
|
||||
|
||||
const {getByTestId} = renderWithIntlAndTheme(
|
||||
<EditProfile
|
||||
componentId={AvailableScreens.EDIT_PROFILE}
|
||||
currentUser={mockCurrentUser}
|
||||
isModal={false}
|
||||
isTablet={true}
|
||||
lockedFirstName={false}
|
||||
lockedLastName={false}
|
||||
lockedNickname={false}
|
||||
lockedPosition={false}
|
||||
lockedPicture={false}
|
||||
enableCustomAttributes={true}
|
||||
userCustomAttributes={[]}
|
||||
customFields={[]}
|
||||
customAttributesSet={{}}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Wait for component to load
|
||||
await act(async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
});
|
||||
|
||||
// Modify a standard field to trigger the hasUpdateUserInfo flag
|
||||
const firstNameField = getByTestId('edit_profile_form.firstName.input');
|
||||
await act(async () => {
|
||||
fireEvent.changeText(firstNameField, 'Modified John');
|
||||
});
|
||||
|
||||
// Trigger form submission
|
||||
const saveButton = getByTestId('edit_profile.save.button');
|
||||
await act(async () => {
|
||||
fireEvent.press(saveButton);
|
||||
});
|
||||
|
||||
// Verify that updateCustomProfileAttributes was called with empty object
|
||||
expect(mockUpdateCustomProfileAttributes).toHaveBeenCalledWith(
|
||||
'http://localhost:8065',
|
||||
'user1',
|
||||
{},
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle custom attributes update error gracefully', async () => {
|
||||
// Mock updateCustomProfileAttributes to return an error
|
||||
mockUpdateCustomProfileAttributes.mockResolvedValue({
|
||||
success: false,
|
||||
error: new Error('Failed to update custom attributes'),
|
||||
});
|
||||
|
||||
renderWithIntlAndTheme(
|
||||
<EditProfile
|
||||
componentId={AvailableScreens.EDIT_PROFILE}
|
||||
currentUser={mockCurrentUser}
|
||||
isModal={false}
|
||||
isTablet={true}
|
||||
lockedFirstName={false}
|
||||
lockedLastName={false}
|
||||
lockedNickname={false}
|
||||
lockedPosition={false}
|
||||
lockedPicture={false}
|
||||
enableCustomAttributes={true}
|
||||
userCustomAttributes={[]}
|
||||
customFields={[]}
|
||||
customAttributesSet={serverAttributesSet}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Wait for component to load and custom attributes to be fetched
|
||||
await act(async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
});
|
||||
|
||||
// Modify a custom attribute to trigger the hasUpdateUserInfo flag
|
||||
const customAttributeItems = await screen.findAllByTestId(new RegExp('^edit_profile_form.customAttributes.attr[0-9]+.input$'));
|
||||
await act(async () => {
|
||||
fireEvent.changeText(customAttributeItems[0], 'modified value that will error');
|
||||
});
|
||||
|
||||
// Trigger form submission
|
||||
const saveButton = screen.getByTestId('edit_profile.save.button');
|
||||
await act(async () => {
|
||||
fireEvent.press(saveButton);
|
||||
});
|
||||
|
||||
// Verify that updateCustomProfileAttributes was called
|
||||
expect(mockUpdateCustomProfileAttributes).toHaveBeenCalled();
|
||||
|
||||
// Verify error handling - check that error is logged
|
||||
await waitFor(() => {
|
||||
expect(mockLogError).toHaveBeenCalledWith(
|
||||
'Error updating custom attributes',
|
||||
expect.objectContaining({
|
||||
message: 'Failed to update custom attributes',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
|
|||
import useNavButtonPressed from '@hooks/navigation_button_pressed';
|
||||
import SecurityManager from '@managers/security_manager';
|
||||
import {dismissModal, popTopScreen, setButtons} from '@screens/navigation';
|
||||
import {logError} from '@utils/log';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
|
||||
import ProfileForm, {CUSTOM_ATTRS_PREFIX} from './components/form';
|
||||
|
|
@ -186,10 +187,11 @@ const EditProfile = ({
|
|||
}
|
||||
|
||||
// Update custom attributes if changed
|
||||
if (userInfo.customAttributes) {
|
||||
if (userInfo.customAttributes && enableCustomAttributes) {
|
||||
const {error: attrError} = await updateCustomProfileAttributes(serverUrl, currentUser.id, userInfo.customAttributes);
|
||||
if (attrError) {
|
||||
resetScreen(attrError);
|
||||
logError('Error updating custom attributes', attrError);
|
||||
resetScreenForProfileError(attrError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue