diff --git a/app/actions/createDiscussion.js b/app/actions/createDiscussion.js deleted file mode 100644 index 5b6faa85..00000000 --- a/app/actions/createDiscussion.js +++ /dev/null @@ -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 - }; -} diff --git a/app/actions/createDiscussion.ts b/app/actions/createDiscussion.ts new file mode 100644 index 00000000..bf64baaa --- /dev/null +++ b/app/actions/createDiscussion.ts @@ -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 + }; +} diff --git a/app/definitions/redux/index.ts b/app/definitions/redux/index.ts index c99152a4..86512f25 100644 --- a/app/definitions/redux/index.ts +++ b/app/definitions/redux/index.ts @@ -2,6 +2,7 @@ import { TActionActiveUsers } from '../../actions/activeUsers'; import { TActionApp } from '../../actions/app'; import { TActionCreateChannel } from '../../actions/createChannel'; +import { TActionCreateDiscussion } from '../../actions/createDiscussion'; import { TActionCustomEmojis } from '../../actions/customEmojis'; import { TActionEncryption } from '../../actions/encryption'; import { TActionInviteLinks } from '../../actions/inviteLinks'; @@ -17,6 +18,7 @@ import { IActiveUsers } from '../../reducers/activeUsers'; import { IApp } from '../../reducers/app'; import { IConnect } from '../../reducers/connect'; import { ICreateChannel } from '../../reducers/createChannel'; +import { ICreateDiscussion } from '../../reducers/createDiscussion'; import { IEncryption } from '../../reducers/encryption'; import { IInviteLinks } from '../../reducers/inviteLinks'; import { IRoles } from '../../reducers/roles'; @@ -41,7 +43,7 @@ export interface IApplicationState { activeUsers: IActiveUsers; usersTyping: any; inviteLinks: IInviteLinks; - createDiscussion: any; + createDiscussion: ICreateDiscussion; inquiry: any; enterpriseModules: any; encryption: IEncryption; @@ -58,6 +60,7 @@ export type TApplicationActions = TActionActiveUsers & TActionEncryption & TActionSortPreferences & TActionUserTyping & + TActionCreateDiscussion& TActionCreateChannel & TActionsShare & TActionServer & diff --git a/app/reducers/createDiscussion.test.ts b/app/reducers/createDiscussion.test.ts new file mode 100644 index 00000000..0291cbb3 --- /dev/null +++ b/app/reducers/createDiscussion.test.ts @@ -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 } + }); + }); +}); diff --git a/app/reducers/createDiscussion.js b/app/reducers/createDiscussion.ts similarity index 62% rename from app/reducers/createDiscussion.js rename to app/reducers/createDiscussion.ts index 04081d15..4b1bada9 100644 --- a/app/reducers/createDiscussion.js +++ b/app/reducers/createDiscussion.ts @@ -1,13 +1,21 @@ +import { TApplicationActions } from '../definitions'; import { CREATE_DISCUSSION } from '../actions/actionsTypes'; -const initialState = { +export interface ICreateDiscussion { + isFetching: boolean; + failure: boolean; + result: Record; + error: Record; +} + +export const initialState: ICreateDiscussion = { isFetching: false, failure: false, result: {}, error: {} }; -export default function (state = initialState, action) { +export default function (state = initialState, action: TApplicationActions): ICreateDiscussion { switch (action.type) { case CREATE_DISCUSSION.REQUEST: return { diff --git a/app/views/CreateDiscussionView/index.tsx b/app/views/CreateDiscussionView/index.tsx index 53d741d2..34cebd89 100644 --- a/app/views/CreateDiscussionView/index.tsx +++ b/app/views/CreateDiscussionView/index.tsx @@ -24,7 +24,8 @@ import { E2E_ROOM_TYPES } from '../../lib/encryption/constants'; import styles from './styles'; import SelectUsers from './SelectUsers'; import SelectChannel from './SelectChannel'; -import { ICreateChannelViewProps } from './interfaces'; +import { ICreateChannelViewProps, IResult, IError } from './interfaces'; +import { IApplicationState } from '../../definitions'; class CreateChannelView extends React.Component { private channel: any; @@ -102,7 +103,7 @@ class CreateChannelView extends React.Component { users, encrypted } = this.state; - const { create } = this.props; + const { dispatch } = this.props; const params: any = { prid: prid || rid, @@ -115,7 +116,7 @@ class CreateChannelView extends React.Component { params.encrypted = encrypted ?? false; } - create(params); + dispatch(createDiscussionRequest(params)); }; valid = () => { @@ -203,21 +204,17 @@ class CreateChannelView extends React.Component { } } -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: IApplicationState) => ({ user: getUserSelector(state), server: state.server.server, - error: state.createDiscussion.error, + error: state.createDiscussion.error as IError, failure: state.createDiscussion.failure, loading: state.createDiscussion.isFetching, - result: state.createDiscussion.result, - blockUnauthenticatedAccess: state.settings.Accounts_AvatarBlockUnauthenticatedAccess ?? true, - serverVersion: state.server.version, + result: state.createDiscussion.result as IResult, + blockUnauthenticatedAccess: !!state.settings.Accounts_AvatarBlockUnauthenticatedAccess ?? true, + serverVersion: state.server.version as string, isMasterDetail: state.app.isMasterDetail, encryptionEnabled: state.encryption.enabled }); -const mapDispatchToProps = (dispatch: any) => ({ - create: (data: any) => dispatch(createDiscussionRequest(data)) -}); - -export default connect(mapStateToProps, mapDispatchToProps)(withTheme(CreateChannelView)); +export default connect(mapStateToProps)(withTheme(CreateChannelView)); diff --git a/app/views/CreateDiscussionView/interfaces.ts b/app/views/CreateDiscussionView/interfaces.ts index 6009881c..cde570d5 100644 --- a/app/views/CreateDiscussionView/interfaces.ts +++ b/app/views/CreateDiscussionView/interfaces.ts @@ -1,12 +1,17 @@ -import { RouteProp } from '@react-navigation/core'; -import { StackNavigationProp } from '@react-navigation/stack'; - import { NewMessageStackParamList } from '../../stacks/types'; import { SubscriptionType } from '../../definitions/ISubscription'; +import { IBaseScreen } from '../../definitions'; -export interface ICreateChannelViewProps { - navigation: StackNavigationProp; - route: RouteProp; +export interface IResult { + rid: string; + t: SubscriptionType; + prid: string; +} + +export interface IError { + reason: string; +} +export interface ICreateChannelViewProps extends IBaseScreen { server: string; user: { id: string; @@ -14,16 +19,9 @@ export interface ICreateChannelViewProps { }; create: Function; loading: boolean; - result: { - rid: string; - t: SubscriptionType; - prid: string; - }; + result: IResult; failure: boolean; - error: { - reason: string; - }; - theme: string; + error: IError; isMasterDetail: boolean; blockUnauthenticatedAccess: boolean; serverVersion: string;