fix issue that blocks adding test for thread screen (#2221)

This commit is contained in:
Saturnino Abril 2018-10-05 14:46:21 +08:00
parent 112fd06dfd
commit 82d9995f2b
6 changed files with 281 additions and 14 deletions

View file

@ -3,7 +3,7 @@
import {PropTypes} from 'prop-types';
import React from 'react';
import {injectIntl, intlShape} from 'react-intl';
import {intlShape} from 'react-intl';
import {
Clipboard,
StyleSheet,
@ -21,9 +21,8 @@ import mattermostManaged from 'app/mattermost_managed';
const MAX_LINES = 4;
class MarkdownCodeBlock extends React.PureComponent {
export default class MarkdownCodeBlock extends React.PureComponent {
static propTypes = {
intl: intlShape.isRequired,
navigator: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
language: PropTypes.string,
@ -36,8 +35,13 @@ class MarkdownCodeBlock extends React.PureComponent {
language: '',
};
static contextTypes = {
intl: intlShape,
};
handlePress = preventDoubleTap(() => {
const {intl, navigator, theme} = this.props;
const {navigator, theme} = this.props;
const {intl} = this.context;
const languageDisplayName = getDisplayNameForLanguage(this.props.language);
let title;
@ -76,7 +80,7 @@ class MarkdownCodeBlock extends React.PureComponent {
});
handleLongPress = async () => {
const {formatMessage} = this.props.intl;
const {formatMessage} = this.context.intl;
const config = await mattermostManaged.getLocalConfig();
@ -238,5 +242,3 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
},
};
});
export default injectIntl(MarkdownCodeBlock);

View file

@ -0,0 +1,147 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`thread should match snapshot, has root post 1`] = `
<Connect(SafeAreaIos)
excludeHeader={true}
keyboardOffset={20}
>
<Connect(StatusBar) />
<KeyboardLayout
style={
Object {
"backgroundColor": "#ffffff",
"flex": 1,
}
}
>
<Connect(PostList)
currentUserId="member_user_id"
indicateNewMessages={true}
navigator={
Object {
"dismissModal": [MockFunction],
"pop": [MockFunction],
"resetTo": [MockFunction],
"setTitle": [MockFunction] {
"calls": Array [
Array [
Object {
"title": undefined,
},
],
],
"results": Array [
Object {
"isThrow": false,
"value": undefined,
},
],
},
}
}
postIds={
Array [
"root_id",
"post_id_1",
"post_id_2",
]
}
renderFooter={[Function]}
/>
<Connect(PostTextbox)
channelId="channel_id"
channelIsArchived={false}
navigator={
Object {
"dismissModal": [MockFunction],
"pop": [MockFunction],
"resetTo": [MockFunction],
"setTitle": [MockFunction] {
"calls": Array [
Array [
Object {
"title": undefined,
},
],
],
"results": Array [
Object {
"isThrow": false,
"value": undefined,
},
],
},
}
}
onCloseChannel={[Function]}
rootId="root_id"
/>
</KeyboardLayout>
</Connect(SafeAreaIos)>
`;
exports[`thread should match snapshot, no root post, loading 1`] = `
<Connect(SafeAreaIos)
excludeHeader={true}
keyboardOffset={20}
>
<Connect(StatusBar) />
<KeyboardLayout
style={
Object {
"backgroundColor": "#ffffff",
"flex": 1,
}
}
>
<Loading
color="grey"
size="large"
style={Object {}}
/>
</KeyboardLayout>
</Connect(SafeAreaIos)>
`;
exports[`thread should match snapshot, render footer 1`] = `
<Loading
color="grey"
size="large"
style={Object {}}
/>
`;
exports[`thread should match snapshot, render footer 2`] = `null`;
exports[`thread should match snapshot, render footer 3`] = `
<DeletedPost
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"sidebarHeaderTextColor": "#ffffff",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
}
}
/>
`;

View file

@ -4,7 +4,7 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {Platform} from 'react-native';
import {injectIntl, intlShape} from 'react-intl';
import {intlShape} from 'react-intl';
import {General, RequestStatus} from 'mattermost-redux/constants';
import Loading from 'app/components/loading';
@ -16,7 +16,7 @@ import StatusBar from 'app/components/status_bar';
import {makeStyleSheetFromTheme, setNavigatorStyles} from 'app/utils/theme';
import DeletedPost from 'app/components/deleted_post';
class Thread extends PureComponent {
export default class Thread extends PureComponent {
static propTypes = {
actions: PropTypes.shape({
selectPost: PropTypes.func.isRequired,
@ -24,7 +24,6 @@ class Thread extends PureComponent {
channelId: PropTypes.string.isRequired,
channelType: PropTypes.string,
displayName: PropTypes.string,
intl: intlShape.isRequired,
navigator: PropTypes.object,
myMember: PropTypes.object.isRequired,
rootId: PropTypes.string.isRequired,
@ -36,8 +35,13 @@ class Thread extends PureComponent {
state = {};
static contextTypes = {
intl: intlShape,
};
componentWillMount() {
const {channelType, displayName, intl} = this.props;
const {channelType, displayName} = this.props;
const {intl} = this.context;
let title;
if (channelType === General.DM_CHANNEL) {
@ -182,5 +186,3 @@ const getStyle = makeStyleSheetFromTheme((theme) => {
},
};
});
export default injectIntl(Thread);

View file

@ -0,0 +1,103 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import {shallow} from 'enzyme';
import Preferences from 'mattermost-redux/constants/preferences';
import {General, RequestStatus} from 'mattermost-redux/constants';
import Thread from './thread.js';
jest.mock('react-intl');
describe('thread', () => {
const navigator = {
dismissModal: jest.fn(),
pop: jest.fn(),
resetTo: jest.fn(),
setTitle: jest.fn(),
};
const baseProps = {
actions: {
selectPost: jest.fn(),
},
channelId: 'channel_id',
channelType: General.OPEN_CHANNEL,
displayName: 'channel_display_name',
navigator,
myMember: {last_viewed_at: 0, user_id: 'member_user_id'},
rootId: 'root_id',
theme: Preferences.THEMES.default,
postIds: ['root_id', 'post_id_1', 'post_id_2'],
channelIsArchived: false,
threadLoadingStatus: {status: RequestStatus.STARTED},
};
test('should match snapshot, has root post', () => {
const wrapper = shallow(
<Thread {...baseProps}/>,
{context: {intl: {formatMessage: jest.fn()}}},
);
expect(wrapper.getElement()).toMatchSnapshot();
});
test('should match snapshot, no root post, loading', () => {
const newPostIds = ['post_id_1', 'post_id_2'];
const wrapper = shallow(
<Thread
{...baseProps}
postIds={newPostIds}
/>,
{context: {intl: {formatMessage: jest.fn()}}},
);
expect(wrapper.getElement()).toMatchSnapshot();
});
test('should call props.navigator on onCloseChannel', () => {
const channelScreen = {
screen: 'Channel',
title: '',
animated: false,
backButtonTitle: '',
navigatorStyle: {
animated: true,
animationType: 'fade',
navBarHidden: true,
statusBarHidden: false,
statusBarHideWithNavBar: false,
screenBackgroundColor: 'transparent',
},
};
const newNavigator = {...navigator};
const wrapper = shallow(
<Thread
{...baseProps}
navigator={newNavigator}
/>,
{context: {intl: {formatMessage: jest.fn()}}},
);
wrapper.instance().onCloseChannel();
expect(newNavigator.resetTo).toHaveBeenCalledTimes(1);
expect(newNavigator.resetTo).toBeCalledWith(channelScreen);
});
test('should match snapshot, render footer', () => {
const wrapper = shallow(
<Thread {...baseProps}/>,
{context: {intl: {formatMessage: jest.fn()}}},
);
// return loading
expect(wrapper.instance().renderFooter()).toMatchSnapshot();
// return null
wrapper.setProps({threadLoadingStatus: {status: RequestStatus.SUCCESS}});
expect(wrapper.instance().renderFooter()).toMatchSnapshot();
// return deleted post
const newPostIds = ['post_id_1', 'post_id_2'];
wrapper.setProps({postIds: newPostIds});
expect(wrapper.instance().renderFooter()).toMatchSnapshot();
});
});

View file

@ -131,6 +131,9 @@
],
"moduleNameMapper": {
"assets/images/video_player/(.*).png": "<rootDir>/dist/assets/images/video_player/$1@2x.png"
}
},
"transformIgnorePatterns": [
"node_modules/(?!react-native|jail-monkey)"
]
}
}

View file

@ -7,6 +7,16 @@ configure({adapter: new Adapter()});
/* eslint-disable no-console */
jest.mock('NativeModules', () => {
return {
BlurAppScreen: () => true,
MattermostManaged: {
getConfig: jest.fn(),
},
};
});
jest.mock('NativeEventEmitter');
let logs;
let warns;
let errors;