Skip to content

Commit

Permalink
Migrate hooks and notification actions to typescript (mattermost#28858)
Browse files Browse the repository at this point in the history
* Migrate hooks and notification actions to typescript

* Remove missing files

* Fix hook types

* Fix tests
  • Loading branch information
larkox authored Oct 28, 2024
1 parent f9bd093 commit dd51962
Show file tree
Hide file tree
Showing 20 changed files with 586 additions and 430 deletions.
2 changes: 1 addition & 1 deletion webapp/channels/src/actions/global_actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ export async function getTeamRedirectChannelIfIsAccesible(user: UserProfile, tea
channel = dmList.find((directChannel) => directChannel.name === channelName);
}

let channelMember: ChannelMembership | null | undefined;
let channelMember: ChannelMembership | undefined;
if (channel) {
channelMember = getMyChannelMember(state, channel.id);
}
Expand Down
10 changes: 5 additions & 5 deletions webapp/channels/src/actions/hooks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ describe('runDesktopNotificationHooks', () => {

const result = await store.dispatch(runDesktopNotificationHooks(post, msgProps, channel, teamId, args));

expect(result.args).toEqual(args);
expect(result.data).toEqual(args);
});

test('should pass the args through every hook', async () => {
Expand Down Expand Up @@ -557,7 +557,7 @@ describe('runDesktopNotificationHooks', () => {

const result = await store.dispatch(runDesktopNotificationHooks(post, msgProps, channel, teamId, args));

expect(result.args).toEqual(args);
expect(result.data).toEqual(args);
expect(hook1).toHaveBeenCalledWith(post, msgProps, channel, teamId, args);
expect(hook2).toHaveBeenCalledWith(post, msgProps, channel, teamId, args);
expect(hook3).toHaveBeenCalledWith(post, msgProps, channel, teamId, args);
Expand Down Expand Up @@ -668,7 +668,7 @@ describe('runDesktopNotificationHooks', () => {

const result = await store.dispatch(runDesktopNotificationHooks(post, msgProps, channel, teamId, args));

expect(result.args).toEqual(args);
expect(result.data).toEqual(args);
expect(hook1).toHaveBeenCalledWith(post, msgProps, channel, teamId, args);
expect(hook2).toHaveBeenCalledWith(post, msgProps, channel, teamId, args);
expect(hook3).toHaveBeenCalledWith(post, msgProps, channel, teamId, args);
Expand Down Expand Up @@ -717,7 +717,7 @@ describe('runDesktopNotificationHooks', () => {

const result = await store.dispatch(runDesktopNotificationHooks(post, msgProps, channel, teamId, args));

expect(result.args).toEqual({...args, title: 'Notification titleabc', notify: true});
expect(result.data).toEqual({...args, title: 'Notification titleabc', notify: true});
expect(hook1).toHaveBeenCalledWith(post, msgProps, channel, teamId, args);
expect(hook2).toHaveBeenCalledWith(post, msgProps, channel, teamId, {...args, title: 'Notification titlea'});
expect(hook3).toHaveBeenCalledWith(post, msgProps, channel, teamId, {...args, title: 'Notification titleab', notify: false});
Expand Down Expand Up @@ -760,7 +760,7 @@ describe('runDesktopNotificationHooks', () => {

const result = await store.dispatch(runDesktopNotificationHooks(post, msgProps, channel, teamId, args));

expect(result.args).toEqual({...args, title: 'Notification title async'});
expect(result.data).toEqual({...args, title: 'Notification title async'});
expect(hook).toHaveBeenCalledWith(post, msgProps, channel, teamId, args);
});
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import type {Channel} from '@mattermost/types/channels';
import type {CommandArgs} from '@mattermost/types/integrations';
import type {Post} from '@mattermost/types/posts';

import type {ActionFuncAsync} from 'mattermost-redux/types/actions';

import type {GlobalState} from 'types/store';
import type {DesktopNotificationArgs} from 'types/store/plugins';

import type {NewPostMessageProps} from './new_post';

/**
* @param {Post} originalPost
* @returns {ActionFuncAsync<Post>}
*/
export function runMessageWillBePostedHooks(originalPost) {
export function runMessageWillBePostedHooks(originalPost: Post): ActionFuncAsync<Post, GlobalState> {
return async (dispatch, getState) => {
const hooks = getState().plugins.components.MessageWillBePosted;
if (!hooks || hooks.length === 0) {
Expand All @@ -15,10 +26,10 @@ export function runMessageWillBePostedHooks(originalPost) {
let post = originalPost;

for (const hook of hooks) {
const result = await hook.hook(post); // eslint-disable-line no-await-in-loop
const result = await hook.hook?.(post); // eslint-disable-line no-await-in-loop

if (result) {
if (result.error) {
if ('error' in result) {
return {
error: result.error,
};
Expand All @@ -32,7 +43,7 @@ export function runMessageWillBePostedHooks(originalPost) {
};
}

export function runSlashCommandWillBePostedHooks(originalMessage, originalArgs) {
export function runSlashCommandWillBePostedHooks(originalMessage: string, originalArgs: CommandArgs): ActionFuncAsync<{message: string; args: CommandArgs}, GlobalState> {
return async (dispatch, getState) => {
const hooks = getState().plugins.components.SlashCommandWillBePosted;
if (!hooks || hooks.length === 0) {
Expand All @@ -43,10 +54,10 @@ export function runSlashCommandWillBePostedHooks(originalMessage, originalArgs)
let args = originalArgs;

for (const hook of hooks) {
const result = await hook.hook(message, args); // eslint-disable-line no-await-in-loop
const result = await hook.hook?.(message, args); // eslint-disable-line no-await-in-loop

if (result) {
if (result.error) {
if ('error' in result) {
return {
error: result.error,
};
Expand All @@ -67,7 +78,7 @@ export function runSlashCommandWillBePostedHooks(originalMessage, originalArgs)
};
}

export function runMessageWillBeUpdatedHooks(newPost, oldPost) {
export function runMessageWillBeUpdatedHooks(newPost: Partial<Post>, oldPost: Post): ActionFuncAsync<Partial<Post>, GlobalState> {
return async (dispatch, getState) => {
const hooks = getState().plugins.components.MessageWillBeUpdated;
if (!hooks || hooks.length === 0) {
Expand All @@ -77,10 +88,10 @@ export function runMessageWillBeUpdatedHooks(newPost, oldPost) {
let post = newPost;

for (const hook of hooks) {
const result = await hook.hook(post, oldPost); // eslint-disable-line no-await-in-loop
const result = await hook.hook?.(post, oldPost); // eslint-disable-line no-await-in-loop

if (result) {
if (result.error) {
if ('error' in result) {
return {
error: result.error,
};
Expand All @@ -94,11 +105,11 @@ export function runMessageWillBeUpdatedHooks(newPost, oldPost) {
};
}

export function runDesktopNotificationHooks(post, msgProps, channel, teamId, args) {
export function runDesktopNotificationHooks(post: Post, msgProps: NewPostMessageProps, channel: Channel, teamId: string, args: DesktopNotificationArgs): ActionFuncAsync<DesktopNotificationArgs, GlobalState> {
return async (dispatch, getState) => {
const hooks = getState().plugins.components.DesktopNotificationHooks;
if (!hooks || hooks.length === 0) {
return {args};
return {data: args};
}

let nextArgs = args;
Expand All @@ -118,6 +129,6 @@ export function runDesktopNotificationHooks(post, msgProps, channel, teamId, arg
}
}

return {args: nextArgs};
return {data: nextArgs};
};
}
15 changes: 14 additions & 1 deletion webapp/channels/src/actions/new_post.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ describe('actions/new_post', () => {
},
users: {
currentUserId: 'current_user_id',
profiles: {
current_user_id: {},
},
},
general: {
license: {IsLicensed: 'false'},
Expand All @@ -96,7 +99,17 @@ describe('actions/new_post', () => {
test('completePostReceive', async () => {
const testStore = mockStore(initialState);
const newPost = {id: 'new_post_id', channel_id: 'current_channel_id', message: 'new message', type: Constants.PostTypes.ADD_TO_CHANNEL, user_id: 'some_user_id', create_at: POST_CREATED_TIME, props: {addedUserId: 'other_user_id'}} as unknown as Post;
const websocketProps = {team_id: 'team_id', mentions: ['current_user_id'], should_ack: false};
const websocketProps: NewPostActions.NewPostMessageProps = {
team_id: 'team_id',
mentions: JSON.stringify(['current_user_id']),
should_ack: false,
channel_display_name: '',
channel_name: '',
channel_type: 'P',
post: JSON.stringify(newPost),
sender_name: '',
set_online: false,
};

await testStore.dispatch(NewPostActions.completePostReceive(newPost, websocketProps));
expect(testStore.getActions()).toEqual([
Expand Down
18 changes: 14 additions & 4 deletions webapp/channels/src/actions/new_post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import type {AnyAction} from 'redux';
import {batchActions} from 'redux-batched-actions';

import type {ChannelType} from '@mattermost/types/channels';
import type {Post} from '@mattermost/types/posts';

import {
Expand All @@ -24,7 +25,7 @@ import {
shouldIgnorePost,
} from 'mattermost-redux/utils/post_utils';

import {sendDesktopNotification} from 'actions/notification_actions.jsx';
import {sendDesktopNotification} from 'actions/notification_actions';
import {updateThreadLastOpened} from 'actions/views/threads';
import {isThreadOpen, makeGetThreadLastViewedAt} from 'selectors/views/threads';

Expand All @@ -34,9 +35,18 @@ import {ActionTypes} from 'utils/constants';
import type {GlobalState} from 'types/store';

export type NewPostMessageProps = {
mentions: string[];
channel_type: ChannelType;
channel_display_name: string;
channel_name: string;
sender_name: string;
set_online: boolean;
mentions?: string;
followers?: string;
team_id: string;
should_ack: boolean;
otherFile?: 'true';
image?: 'true';
post: string;
}

export function completePostReceive(post: Post, websocketMessageProps: NewPostMessageProps, fetchedChannelMember?: boolean): ActionFuncAsync<boolean, GlobalState> {
Expand Down Expand Up @@ -85,7 +95,7 @@ export function completePostReceive(post: Post, websocketMessageProps: NewPostMe
dispatch(setThreadRead(post));
}

const {status, reason, data} = await dispatch(sendDesktopNotification(post, websocketMessageProps));
const {status, reason, data} = (await dispatch(sendDesktopNotification(post, websocketMessageProps))).data!;

// Only ACK for posts that require it
if (websocketMessageProps.should_ack) {
Expand Down Expand Up @@ -137,7 +147,7 @@ export function setChannelReadAndViewed(dispatch: DispatchFunc, getState: GetSta
return actionsToMarkChannelAsRead(getState, post.channel_id);
}

return actionsToMarkChannelAsUnread(getState, websocketMessageProps.team_id, post.channel_id, websocketMessageProps.mentions, fetchedChannelMember, post.root_id === '', post?.metadata?.priority?.priority);
return actionsToMarkChannelAsUnread(getState, websocketMessageProps.team_id, post.channel_id, websocketMessageProps.mentions || '', fetchedChannelMember, post.root_id === '', post?.metadata?.priority?.priority);
}

export function setThreadRead(post: Post): ActionFunc<boolean, GlobalState> {
Expand Down
Loading

0 comments on commit dd51962

Please sign in to comment.