Chore: Migrate redux module createDiscussion to typescript (#3604)

* chore: migrate createDiscussion to ts and add tests

* chore: add TActionCreateDiscussion to TApplicationActions

* fix types

* update types

* fix types

Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
Gleidson Daniel Silva 2022-02-02 15:51:18 -03:00 committed by GitHub
parent 6fa35cd748
commit d7c32b71c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 108 additions and 53 deletions

View File

@ -1,22 +0,0 @@
import * as types from './actionsTypes';
export function createDiscussionRequest(data) {
return {
type: types.CREATE_DISCUSSION.REQUEST,
data
};
}
export function createDiscussionSuccess(data) {
return {
type: types.CREATE_DISCUSSION.SUCCESS,
data
};
}
export function createDiscussionFailure(err) {
return {
type: types.CREATE_DISCUSSION.FAILURE,
err
};
}

View File

@ -0,0 +1,38 @@
import { Action } from 'redux';
import { CREATE_DISCUSSION } from './actionsTypes';
interface ICreateDiscussionRequest extends Action {
data: any;
}
interface ICreateDiscussionSuccess extends Action {
data: any;
}
interface ICreateDiscussionFailure extends Action {
err: any;
}
export type TActionCreateDiscussion = ICreateDiscussionRequest & ICreateDiscussionSuccess & ICreateDiscussionFailure;
export function createDiscussionRequest(data: any): ICreateDiscussionRequest {
return {
type: CREATE_DISCUSSION.REQUEST,
data
};
}
export function createDiscussionSuccess(data: any): ICreateDiscussionSuccess {
return {
type: CREATE_DISCUSSION.SUCCESS,
data
};
}
export function createDiscussionFailure(err: any): ICreateDiscussionFailure {
return {
type: CREATE_DISCUSSION.FAILURE,
err
};
}

View File

@ -2,6 +2,7 @@
import { TActionActiveUsers } from '../../actions/activeUsers'; import { TActionActiveUsers } from '../../actions/activeUsers';
import { TActionApp } from '../../actions/app'; import { TActionApp } from '../../actions/app';
import { TActionCreateChannel } from '../../actions/createChannel'; import { TActionCreateChannel } from '../../actions/createChannel';
import { TActionCreateDiscussion } from '../../actions/createDiscussion';
import { TActionCustomEmojis } from '../../actions/customEmojis'; import { TActionCustomEmojis } from '../../actions/customEmojis';
import { TActionEncryption } from '../../actions/encryption'; import { TActionEncryption } from '../../actions/encryption';
import { TActionInviteLinks } from '../../actions/inviteLinks'; import { TActionInviteLinks } from '../../actions/inviteLinks';
@ -17,6 +18,7 @@ import { IActiveUsers } from '../../reducers/activeUsers';
import { IApp } from '../../reducers/app'; import { IApp } from '../../reducers/app';
import { IConnect } from '../../reducers/connect'; import { IConnect } from '../../reducers/connect';
import { ICreateChannel } from '../../reducers/createChannel'; import { ICreateChannel } from '../../reducers/createChannel';
import { ICreateDiscussion } from '../../reducers/createDiscussion';
import { IEncryption } from '../../reducers/encryption'; import { IEncryption } from '../../reducers/encryption';
import { IInviteLinks } from '../../reducers/inviteLinks'; import { IInviteLinks } from '../../reducers/inviteLinks';
import { IRoles } from '../../reducers/roles'; import { IRoles } from '../../reducers/roles';
@ -41,7 +43,7 @@ export interface IApplicationState {
activeUsers: IActiveUsers; activeUsers: IActiveUsers;
usersTyping: any; usersTyping: any;
inviteLinks: IInviteLinks; inviteLinks: IInviteLinks;
createDiscussion: any; createDiscussion: ICreateDiscussion;
inquiry: any; inquiry: any;
enterpriseModules: any; enterpriseModules: any;
encryption: IEncryption; encryption: IEncryption;
@ -58,6 +60,7 @@ export type TApplicationActions = TActionActiveUsers &
TActionEncryption & TActionEncryption &
TActionSortPreferences & TActionSortPreferences &
TActionUserTyping & TActionUserTyping &
TActionCreateDiscussion&
TActionCreateChannel & TActionCreateChannel &
TActionsShare & TActionsShare &
TActionServer & TActionServer &

View File

@ -0,0 +1,33 @@
import { createDiscussionRequest, createDiscussionSuccess, createDiscussionFailure } from '../actions/createDiscussion';
import { initialState } from './createDiscussion';
import { mockedStore } from './mockedStore';
describe('test reducer', () => {
it('should return initial state', () => {
const { createDiscussion } = mockedStore.getState();
expect(createDiscussion).toEqual(initialState);
});
it('should return correct createDiscussion state after dispatch createDiscussionRequest action', () => {
mockedStore.dispatch(createDiscussionRequest({}));
const { createDiscussion } = mockedStore.getState();
expect(createDiscussion).toEqual({ isFetching: true, failure: false, error: {}, result: {} });
});
it('should return correct createDiscussion state after dispatch createDiscussionSuccess action', () => {
mockedStore.dispatch(createDiscussionSuccess({ data: true }));
const { createDiscussion } = mockedStore.getState();
expect(createDiscussion).toEqual({ isFetching: false, failure: false, result: { data: true }, error: {} });
});
it('should return correct createDiscussion state after dispatch createDiscussionFailure action', () => {
mockedStore.dispatch(createDiscussionFailure({ err: true }));
const { createDiscussion } = mockedStore.getState();
expect(createDiscussion).toEqual({
isFetching: false,
failure: true,
result: { data: true },
error: { err: true }
});
});
});

View File

@ -1,13 +1,21 @@
import { TApplicationActions } from '../definitions';
import { CREATE_DISCUSSION } from '../actions/actionsTypes'; import { CREATE_DISCUSSION } from '../actions/actionsTypes';
const initialState = { export interface ICreateDiscussion {
isFetching: boolean;
failure: boolean;
result: Record<string, any>;
error: Record<string, any>;
}
export const initialState: ICreateDiscussion = {
isFetching: false, isFetching: false,
failure: false, failure: false,
result: {}, result: {},
error: {} error: {}
}; };
export default function (state = initialState, action) { export default function (state = initialState, action: TApplicationActions): ICreateDiscussion {
switch (action.type) { switch (action.type) {
case CREATE_DISCUSSION.REQUEST: case CREATE_DISCUSSION.REQUEST:
return { return {

View File

@ -24,7 +24,8 @@ import { E2E_ROOM_TYPES } from '../../lib/encryption/constants';
import styles from './styles'; import styles from './styles';
import SelectUsers from './SelectUsers'; import SelectUsers from './SelectUsers';
import SelectChannel from './SelectChannel'; import SelectChannel from './SelectChannel';
import { ICreateChannelViewProps } from './interfaces'; import { ICreateChannelViewProps, IResult, IError } from './interfaces';
import { IApplicationState } from '../../definitions';
class CreateChannelView extends React.Component<ICreateChannelViewProps, any> { class CreateChannelView extends React.Component<ICreateChannelViewProps, any> {
private channel: any; private channel: any;
@ -102,7 +103,7 @@ class CreateChannelView extends React.Component<ICreateChannelViewProps, any> {
users, users,
encrypted encrypted
} = this.state; } = this.state;
const { create } = this.props; const { dispatch } = this.props;
const params: any = { const params: any = {
prid: prid || rid, prid: prid || rid,
@ -115,7 +116,7 @@ class CreateChannelView extends React.Component<ICreateChannelViewProps, any> {
params.encrypted = encrypted ?? false; params.encrypted = encrypted ?? false;
} }
create(params); dispatch(createDiscussionRequest(params));
}; };
valid = () => { valid = () => {
@ -203,21 +204,17 @@ class CreateChannelView extends React.Component<ICreateChannelViewProps, any> {
} }
} }
const mapStateToProps = (state: any) => ({ const mapStateToProps = (state: IApplicationState) => ({
user: getUserSelector(state), user: getUserSelector(state),
server: state.server.server, server: state.server.server,
error: state.createDiscussion.error, error: state.createDiscussion.error as IError,
failure: state.createDiscussion.failure, failure: state.createDiscussion.failure,
loading: state.createDiscussion.isFetching, loading: state.createDiscussion.isFetching,
result: state.createDiscussion.result, result: state.createDiscussion.result as IResult,
blockUnauthenticatedAccess: state.settings.Accounts_AvatarBlockUnauthenticatedAccess ?? true, blockUnauthenticatedAccess: !!state.settings.Accounts_AvatarBlockUnauthenticatedAccess ?? true,
serverVersion: state.server.version, serverVersion: state.server.version as string,
isMasterDetail: state.app.isMasterDetail, isMasterDetail: state.app.isMasterDetail,
encryptionEnabled: state.encryption.enabled encryptionEnabled: state.encryption.enabled
}); });
const mapDispatchToProps = (dispatch: any) => ({ export default connect(mapStateToProps)(withTheme(CreateChannelView));
create: (data: any) => dispatch(createDiscussionRequest(data))
});
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(CreateChannelView));

View File

@ -1,12 +1,17 @@
import { RouteProp } from '@react-navigation/core';
import { StackNavigationProp } from '@react-navigation/stack';
import { NewMessageStackParamList } from '../../stacks/types'; import { NewMessageStackParamList } from '../../stacks/types';
import { SubscriptionType } from '../../definitions/ISubscription'; import { SubscriptionType } from '../../definitions/ISubscription';
import { IBaseScreen } from '../../definitions';
export interface ICreateChannelViewProps { export interface IResult {
navigation: StackNavigationProp<NewMessageStackParamList, 'CreateDiscussionView'>; rid: string;
route: RouteProp<NewMessageStackParamList, 'CreateDiscussionView'>; t: SubscriptionType;
prid: string;
}
export interface IError {
reason: string;
}
export interface ICreateChannelViewProps extends IBaseScreen<NewMessageStackParamList, 'CreateDiscussionView'> {
server: string; server: string;
user: { user: {
id: string; id: string;
@ -14,16 +19,9 @@ export interface ICreateChannelViewProps {
}; };
create: Function; create: Function;
loading: boolean; loading: boolean;
result: { result: IResult;
rid: string;
t: SubscriptionType;
prid: string;
};
failure: boolean; failure: boolean;
error: { error: IError;
reason: string;
};
theme: string;
isMasterDetail: boolean; isMasterDetail: boolean;
blockUnauthenticatedAccess: boolean; blockUnauthenticatedAccess: boolean;
serverVersion: string; serverVersion: string;