Skip to content

Commit 570ed90

Browse files
[MM-62176] fix ordering after edit (#8719) (#8723)
* check render order (cherry picked from commit 427d61e) Co-authored-by: Guillermo Vayá <[email protected]>
1 parent 5fdf6ec commit 570ed90

File tree

2 files changed

+115
-2
lines changed

2 files changed

+115
-2
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2+
// See LICENSE.txt for license information.
3+
import {act} from '@testing-library/react-hooks';
4+
import {fireEvent, waitFor} from '@testing-library/react-native';
5+
import React from 'react';
6+
7+
import AvailableScreens from '@constants/screens';
8+
import {renderWithIntlAndTheme} from '@test/intl-test-helper';
9+
10+
import EditProfile from './edit_profile';
11+
12+
import type {UserModel} from '@database/models/server';
13+
14+
jest.mock('@components/compass_icon', () => {
15+
function CompassIcon() {
16+
return null;
17+
}
18+
CompassIcon.getImageSourceSync = jest.fn().mockReturnValue({});
19+
return {
20+
__esModule: true,
21+
default: CompassIcon,
22+
};
23+
});
24+
25+
jest.mock('@context/server', () => ({
26+
useServerUrl: jest.fn().mockReturnValue('http://localhost:8065'),
27+
}));
28+
29+
jest.mock('@actions/remote/user', () => ({
30+
fetchCustomAttributes: jest.fn().mockResolvedValue({
31+
attributes: {
32+
attr1: {
33+
id: 'attr1',
34+
name: 'Custom Attribute 1',
35+
value: 'original value 1',
36+
sort_order: 1,
37+
},
38+
attr3: {
39+
id: 'attr3',
40+
name: 'Custom Attribute 3',
41+
value: 'original value 3',
42+
sort_order: 3,
43+
},
44+
attr2: {
45+
id: 'attr2',
46+
name: 'Custom Attribute 2',
47+
value: 'original value 2',
48+
sort_order: 2,
49+
},
50+
},
51+
error: undefined,
52+
}),
53+
updateCustomAttributes: jest.fn().mockResolvedValue({}),
54+
updateMe: jest.fn().mockResolvedValue({}),
55+
uploadUserProfileImage: jest.fn().mockResolvedValue({}),
56+
setDefaultProfileImage: jest.fn().mockResolvedValue({}),
57+
buildProfileImageUrlFromUser: jest.fn().mockReturnValue('http://example.com/profile.jpg'),
58+
}));
59+
60+
describe('EditProfile', () => {
61+
const mockCurrentUser = {
62+
id: 'user1',
63+
64+
firstName: 'John',
65+
lastName: 'Doe',
66+
nickname: 'Johnny',
67+
position: 'Developer',
68+
username: 'johndoe',
69+
} as UserModel;
70+
71+
beforeEach(() => {
72+
jest.clearAllMocks();
73+
});
74+
75+
it('should update custom attribute value while preserving name and sort order', async () => {
76+
const {findAllByTestId} = renderWithIntlAndTheme(
77+
<EditProfile
78+
componentId={AvailableScreens.EDIT_PROFILE}
79+
currentUser={mockCurrentUser}
80+
isModal={false}
81+
isTablet={false}
82+
lockedFirstName={false}
83+
lockedLastName={false}
84+
lockedNickname={false}
85+
lockedPosition={false}
86+
lockedPicture={false}
87+
enableCustomAttributes={true}
88+
/>,
89+
);
90+
91+
await waitFor(() => {
92+
const {fetchCustomAttributes} = require('@actions/remote/user');
93+
expect(fetchCustomAttributes).toHaveBeenCalledWith('http://localhost:8065', 'user1');
94+
});
95+
96+
const customAttributeItems = await findAllByTestId(new RegExp('^edit_profile_form.customAttributes.attr[0-9]+.input$'));
97+
expect(customAttributeItems.length).toBe(3);
98+
99+
expect(customAttributeItems[0].props.value).toBe('original value 1');
100+
expect(customAttributeItems[1].props.value).toBe('original value 2');
101+
expect(customAttributeItems[2].props.value).toBe('original value 3');
102+
103+
await act(async () => {
104+
fireEvent.changeText(customAttributeItems[1], 'new value');
105+
});
106+
107+
const newCustomAttributeItems = await findAllByTestId(new RegExp('^edit_profile_form.customAttributes.attr[0-9]+.input$'));
108+
expect(newCustomAttributeItems.length).toBe(3);
109+
expect(newCustomAttributeItems[0].props.value).toBe('original value 1');
110+
expect(newCustomAttributeItems[1].props.value).toBe('new value');
111+
expect(newCustomAttributeItems[2].props.value).toBe('original value 3');
112+
});
113+
});

app/screens/edit_profile/edit_profile.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ const EditProfile = ({
127127
}
128128
const {error: fetchError, attributes} = await fetchCustomAttributes(serverUrl, currentUser.id);
129129
if (!fetchError && attributes) {
130-
setUserInfo((prev) => ({...prev, customAttributes: attributes} as UserInfo));
130+
setUserInfo((prev: UserInfo) => ({...prev, customAttributes: attributes} as UserInfo));
131131
}
132132
};
133133

@@ -200,7 +200,7 @@ const EditProfile = ({
200200
const update = {...userInfo};
201201
if (fieldKey.startsWith(CUSTOM_ATTRS_PREFIX_NAME)) {
202202
const attrKey = fieldKey.slice(CUSTOM_ATTRS_PREFIX_NAME.length);
203-
update.customAttributes = {...update.customAttributes, [attrKey]: {id: attrKey, name: userInfo.customAttributes[attrKey].name, value}};
203+
update.customAttributes = {...update.customAttributes, [attrKey]: {id: attrKey, name: userInfo.customAttributes[attrKey].name, value, sort_order: userInfo.customAttributes[attrKey].sort_order}};
204204
} else {
205205
switch (fieldKey) {
206206
// typescript doesn't like to do update[fieldkey] as it might containg a customAttribute case

0 commit comments

Comments
 (0)