Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions server/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ PLUGIN_PACKAGES += mattermost-plugin-jira-v4.8.0
PLUGIN_PACKAGES += mattermost-plugin-playbooks-v2.11.1
PLUGIN_PACKAGES += mattermost-plugin-servicenow-v2.4.0
PLUGIN_PACKAGES += mattermost-plugin-zoom-v1.13.0
PLUGIN_PACKAGES += mattermost-plugin-agents-v2.6.0
PLUGIN_PACKAGES += mattermost-plugin-agents-v2.6.1
PLUGIN_PACKAGES += mattermost-plugin-boards-v9.4.0
PLUGIN_PACKAGES += mattermost-plugin-user-survey-v1.1.1
PLUGIN_PACKAGES += mattermost-plugin-mscalendar-v1.7.0
Expand All @@ -178,7 +178,7 @@ PLUGIN_PACKAGES += mattermost-plugin-dataminr-v2.0.0
# the way we pre-package FIPS and non-FIPS plugins.
ifeq ($(FIPS_ENABLED),true)
PLUGIN_PACKAGES = mattermost-plugin-playbooks-v2.11.1%2B329b65c-fips
PLUGIN_PACKAGES += mattermost-plugin-agents-v2.6.0%2B7824854-fips
PLUGIN_PACKAGES += mattermost-plugin-agents-v2.6.1%2B0b1b771-fips
PLUGIN_PACKAGES += mattermost-plugin-boards-v9.4.0%2B4b7dd4b-fips
endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,49 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
expect(screen.getByPlaceholderText('Write to Other Channel')).toHaveValue('a different draft');
});

it('should mount and send when rootId is omitted, as plugins may do via window.Components', async () => {
// Plugins reach AdvancedTextEditor through the untyped window.Components bridge, so
// TypeScript cannot enforce the required rootId prop. An undefined rootId used to
// mismatch the draft's '' on every render pass, throwing React error #301 on mount
// and, once mounted, leaving the post-submit draft reset silently dropped.
const message = 'a message sent from a composer without a rootId';

renderWithContext(
<AdvancedTextEditor
{...baseProps}
rootId={undefined as unknown as string}
/>,
mergeObjects(initialState, {
entities: {
roles: {
roles: {
user_roles: {permissions: [Permissions.CREATE_POST]},
},
},
},
}),
);

const textbox = screen.getByTestId('post_textbox');

// SuggestionBox listens to onInput, not onChange.
fireEvent.input(textbox, {target: {value: message}});
expect(textbox).toHaveValue(message);

await act(async () => {
fireEvent.click(screen.getByTestId('SendMessageButton'));
});

expect(mockedOnSubmit).toHaveBeenCalledWith(
channelId,
'',
expect.objectContaining({message, channelId, rootId: ''}),
expect.anything(),
undefined,
);
expect(textbox).toHaveValue('');
});

it('should submit a destination-owned draft while the textbox still holds the previous channel value', async () => {
const sourceDraft = 'stale draft from the source channel';
const destinationMessage = 'new message composed for the destination channel';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,19 @@ export type Props = {
const AdvancedTextEditor = ({
location,
channelId,
rootId,
rootId: rootIdProp,
postId,
isThreadView = false,
placeholder,
isInEditMode = false,
afterSubmit,
storageKey,
}: Props) => {
// rootId is typed as required, but plugins reach this component through the untyped
// window.Components bridge and may omit it. Every draft carries '' rather than undefined
// for a non-thread composer, so an undefined prop desyncs the id comparisons below.
const rootId = rootIdProp ?? '';

const {formatMessage} = useIntl();

const dispatch = useDispatch();
Expand Down
Loading