From ea095d6206ad8bb9b1b1ffbf74584669a24f1ca8 Mon Sep 17 00:00:00 2001 From: 94117nl Date: Thu, 3 Aug 2017 08:25:07 -0500 Subject: GH-6452 Migrate installed_command.jsx to be pure and use Redux (#6903) * Migrate installed_command.jsx to be pure and use Redux * Add test for InstalledCommand component * Fix failing test and typo * Whoops. Revert back deleted filter * Add filter test * Remove commands related code from /stores/integration_store.jsx --- .../commands_container/commands_container.jsx | 2 +- .../integrations/components/installed_command.jsx | 65 ++++++++----- .../installed_commands/installed_commands.jsx | 4 +- webapp/stores/integration_store.jsx | 30 ------ .../__snapshots__/installed_command.test.jsx.snap | 103 +++++++++++++++++++++ .../integrations/installed_command.test.jsx | 83 +++++++++++++++++ 6 files changed, 230 insertions(+), 57 deletions(-) create mode 100644 webapp/tests/components/integrations/__snapshots__/installed_command.test.jsx.snap create mode 100644 webapp/tests/components/integrations/installed_command.test.jsx diff --git a/webapp/components/integrations/components/commands_container/commands_container.jsx b/webapp/components/integrations/components/commands_container/commands_container.jsx index 55ce2017b..8f89ff631 100644 --- a/webapp/components/integrations/components/commands_container/commands_container.jsx +++ b/webapp/components/integrations/components/commands_container/commands_container.jsx @@ -33,7 +33,7 @@ export default class CommandsContainer extends React.PureComponent { users: PropTypes.object, /** - * Installed splash commands to display + * Installed slash commands to display */ commands: PropTypes.array, diff --git a/webapp/components/integrations/components/installed_command.jsx b/webapp/components/integrations/components/installed_command.jsx index 691ae75fb..1470712b0 100644 --- a/webapp/components/integrations/components/installed_command.jsx +++ b/webapp/components/integrations/components/installed_command.jsx @@ -1,43 +1,59 @@ -import PropTypes from 'prop-types'; - // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import React from 'react'; +import PropTypes from 'prop-types'; import {Link} from 'react-router'; import {FormattedMessage} from 'react-intl'; import DeleteIntegration from './delete_integration.jsx'; -export default class InstalledCommand extends React.Component { - static get propTypes() { - return { - team: PropTypes.object.isRequired, - command: PropTypes.object.isRequired, - onRegenToken: PropTypes.func.isRequired, - onDelete: PropTypes.func.isRequired, - filter: PropTypes.string, - creator: PropTypes.object.isRequired, - canChange: PropTypes.bool.isRequired - }; - } - - constructor(props) { - super(props); - - this.handleRegenToken = this.handleRegenToken.bind(this); - this.handleDelete = this.handleDelete.bind(this); - - this.matchesFilter = this.matchesFilter.bind(this); +export default class InstalledCommand extends React.PureComponent { + static propTypes = { + + /** + * The team data + */ + team: PropTypes.object.isRequired, + + /** + * Installed slash command to display + */ + command: PropTypes.object.isRequired, + + /** + * The function to call when Regenerate Token link is clicked + */ + onRegenToken: PropTypes.func.isRequired, + + /** + * The function to call when Delete link is clicked + */ + onDelete: PropTypes.func.isRequired, + + /** + * Set to filter command, comes from BackstageList + */ + filter: PropTypes.string, + + /** + * The creator user data + */ + creator: PropTypes.object.isRequired, + + /** + * Set to show edit link + */ + canChange: PropTypes.bool.isRequired } - handleRegenToken(e) { + handleRegenToken = (e) => { e.preventDefault(); this.props.onRegenToken(this.props.command); } - handleDelete() { + handleDelete = () => { this.props.onDelete(this.props.command); } @@ -60,6 +76,7 @@ export default class InstalledCommand extends React.Component { } let name; + if (command.display_name) { name = command.display_name; } else { diff --git a/webapp/components/integrations/components/installed_commands/installed_commands.jsx b/webapp/components/integrations/components/installed_commands/installed_commands.jsx index 379ade8a1..7085afdc4 100644 --- a/webapp/components/integrations/components/installed_commands/installed_commands.jsx +++ b/webapp/components/integrations/components/installed_commands/installed_commands.jsx @@ -30,7 +30,7 @@ export default class InstalledCommands extends React.PureComponent { users: PropTypes.object, /** - * Installed splash commands to display + * Installed slash commands to display */ commands: PropTypes.array, @@ -40,7 +40,7 @@ export default class InstalledCommands extends React.PureComponent { loading: PropTypes.bool, /** - * Set to allow changes to installed splash commands + * Set to allow changes to installed slash commands */ isAdmin: PropTypes.bool, diff --git a/webapp/stores/integration_store.jsx b/webapp/stores/integration_store.jsx index ff01774e1..f1e86d881 100644 --- a/webapp/stores/integration_store.jsx +++ b/webapp/stores/integration_store.jsx @@ -91,36 +91,6 @@ class IntegrationStore extends EventEmitter { return store.getState().entities.integrations.outgoingHooks[id]; } - hasReceivedCommands(teamId) { - const commands = store.getState().entities.integrations.commands; - - let hasTeam = false; - Object.values(commands).forEach((command) => { - if (command.team_id === teamId) { - hasTeam = true; - } - }); - - return hasTeam; - } - - getCommands(teamId) { - const commands = store.getState().entities.integrations.commands; - - const teamCommands = []; - Object.values(commands).forEach((command) => { - if (command.team_id === teamId) { - teamCommands.push(command); - } - }); - - return teamCommands; - } - - getCommand(teamId, id) { - return store.getState().entities.integrations.commands[id]; - } - hasReceivedOAuthApps() { return Object.keys(store.getState().entities.integrations.oauthApps).length > 0; } diff --git a/webapp/tests/components/integrations/__snapshots__/installed_command.test.jsx.snap b/webapp/tests/components/integrations/__snapshots__/installed_command.test.jsx.snap new file mode 100644 index 000000000..910b35e25 --- /dev/null +++ b/webapp/tests/components/integrations/__snapshots__/installed_command.test.jsx.snap @@ -0,0 +1,103 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`components/integrations/InstalledCommand should filter out command 1`] = `null`; + +exports[`components/integrations/InstalledCommand should match snapshot 1`] = ` +
+
+
+ + test + + + - /trigger test + +
+
+ + test + +
+
+ + + +
+
+ + + +
+
+
+ + + + - + + + + - + +
+
+`; diff --git a/webapp/tests/components/integrations/installed_command.test.jsx b/webapp/tests/components/integrations/installed_command.test.jsx new file mode 100644 index 000000000..b38d04754 --- /dev/null +++ b/webapp/tests/components/integrations/installed_command.test.jsx @@ -0,0 +1,83 @@ +// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import React from 'react'; +import {shallow} from 'enzyme'; + +import InstalledCommand from 'components/integrations/components/installed_command.jsx'; + +describe('components/integrations/InstalledCommand', () => { + const emptyFunction = jest.fn(); + const command = { + id: 'r5tpgt4iepf45jt768jz84djic', + display_name: 'test', + description: 'test', + trigger: 'trigger', + auto_complete: 'test', + auto_complete_hint: 'test', + token: 'testToken', + create_at: '1499722850203' + }; + + test('should match snapshot', () => { + const wrapper = shallow( + + ); + expect(wrapper).toMatchSnapshot(); + }); + + test('should call onRegenToken function', () => { + const onRegenToken = jest.fn(); + const wrapper = shallow( + + ); + wrapper.find('div.item-actions a').first().simulate('click', {preventDefault() { + return jest.fn(); + }}); + + expect(onRegenToken).toBeCalled(); + }); + + test('should filter out command', () => { + const wrapper = shallow( + + ); + expect(wrapper).toMatchSnapshot(); + }); +}); -- cgit v1.2.3-1-g7c22