From 16c85c41aae3992e0b33834c52983e038b895902 Mon Sep 17 00:00:00 2001 From: Ezekiel Date: Fri, 23 Aug 2024 19:38:34 +0800 Subject: [PATCH] converted migrations_table class component to functional component (#27956) * converted migrations_table class component to functional component * added dependencylist for useffect & use memo for caching * Added tests * Remove commented code and used renderWithContext instead of render(withIntl(..)) --------- Co-authored-by: Ezekiel Co-authored-by: Mattermost Build --- .../database_settings.test.tsx.snap | 2 +- .../migrations_table.test.tsx.snap | 42 ++++++ .../database/migrations_table.test.tsx | 79 +++++++++++ .../database/migrations_table.tsx | 126 +++++++++--------- 4 files changed, 183 insertions(+), 66 deletions(-) create mode 100644 webapp/channels/src/components/admin_console/database/__snapshots__/migrations_table.test.tsx.snap create mode 100644 webapp/channels/src/components/admin_console/database/migrations_table.test.tsx diff --git a/webapp/channels/src/components/admin_console/__snapshots__/database_settings.test.tsx.snap b/webapp/channels/src/components/admin_console/__snapshots__/database_settings.test.tsx.snap index d9cfebf403..6e3218c0e1 100644 --- a/webapp/channels/src/components/admin_console/__snapshots__/database_settings.test.tsx.snap +++ b/webapp/channels/src/components/admin_console/__snapshots__/database_settings.test.tsx.snap @@ -381,7 +381,7 @@ exports[`components/DatabaseSettings should match snapshot 1`] = `
- +
+ +
+
+ + + + + + + + +
+ + + +
+
+
+`; diff --git a/webapp/channels/src/components/admin_console/database/migrations_table.test.tsx b/webapp/channels/src/components/admin_console/database/migrations_table.test.tsx new file mode 100644 index 0000000000..dafd28c90e --- /dev/null +++ b/webapp/channels/src/components/admin_console/database/migrations_table.test.tsx @@ -0,0 +1,79 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {act, screen, waitFor} from '@testing-library/react'; +import {shallow} from 'enzyme'; +import React from 'react'; +import {FormattedMessage} from 'react-intl'; + +import type {SchemaMigration} from '@mattermost/types/admin'; + +import type {ActionResult} from 'mattermost-redux/types/actions'; + +import {renderWithContext} from 'tests/react_testing_utils'; + +import MigrationsTable from './migrations_table'; + +const migrationsMockData: SchemaMigration[] = []; + +describe('components/MigrationsTable', () => { + const createHelpText = ( + + ); + + const baseProps = { + createHelpText, + className: '', + actions: { + getAppliedSchemaMigrations: (jest.fn()).mockResolvedValue({ + data: migrationsMockData, + } as ActionResult), + }, + }; + + test('should match snapshot when there are no migrations', () => { + const wrapper = shallow( + ); + + expect(wrapper).toMatchSnapshot(); + }); + + test('should have called actions.getAppliedSchemaMigrations only when first rendered', async () => { + const mockMigrations = [ + {version: '1.0', name: 'Initial migration'}, + {version: '1.1', name: 'Add users table'}, + ]; + const withDataProps = { + ...baseProps, + actions: { + getAppliedSchemaMigrations: (jest.fn()).mockResolvedValue({ + data: mockMigrations, + } as ActionResult), + }, + }; + + const view = renderWithContext(); + + await waitFor(() => { + expect(withDataProps.actions.getAppliedSchemaMigrations).toHaveBeenCalledTimes(1); + }); + + act(() => { + const newProps = {...withDataProps, className: 'foo'}; + view.rerender(); + }); + + await waitFor(() => { + expect(withDataProps.actions.getAppliedSchemaMigrations).toHaveBeenCalledTimes(1); + mockMigrations.forEach((migration) => { + expect(screen.getByText(migration.version)).toBeInTheDocument(); + expect(screen.getByText(migration.name)).toBeInTheDocument(); + }); + }); + }); +}); diff --git a/webapp/channels/src/components/admin_console/database/migrations_table.tsx b/webapp/channels/src/components/admin_console/database/migrations_table.tsx index 8c2dac0e1b..ac4b63bbd2 100644 --- a/webapp/channels/src/components/admin_console/database/migrations_table.tsx +++ b/webapp/channels/src/components/admin_console/database/migrations_table.tsx @@ -2,7 +2,7 @@ // See LICENSE.txt for license information. import classNames from 'classnames'; -import React from 'react'; +import React, {useEffect, useMemo, useState} from 'react'; import {FormattedMessage} from 'react-intl'; import type {SchemaMigration} from '@mattermost/types/admin'; @@ -11,7 +11,7 @@ import type {ActionResult} from 'mattermost-redux/types/actions'; import './migrations_table.scss'; -export type Props = { +type Props = { createHelpText: React.ReactElement; className?: string; actions: { @@ -19,72 +19,68 @@ export type Props = { }; } -type State = { - migrations: SchemaMigration[]; -} +const MigrationsTable = ({ + createHelpText, + className, + actions, +}: Props) => { + const [migrations, setMigrations] = useState([]); -class MigrationsTable extends React.PureComponent { - constructor(props: Props) { - super(props); - this.state = { - migrations: [], - }; - } + useEffect(() => { + async function handleGetAppliedSchemaMigrations() { + const result: ActionResult = await actions.getAppliedSchemaMigrations(); + if (result.data) { + setMigrations(result.data); + } + } - componentDidMount() { - this.props.actions.getAppliedSchemaMigrations().then((result) => { - this.setState({ - migrations: result.data, - }); - }); - } - - render() { - const items = this.state.migrations.map((migration) => { - return ( - - {migration.version} - {migration.name} - - ); - }); + handleGetAppliedSchemaMigrations(); + }, []); + const items = useMemo(() => migrations.map((migration) => { return ( -
-
- {this.props.createHelpText} -
-
- - - - - - - - - {items} - -
- - - -
-
-
+ + {migration.version} + {migration.name} + ); - } -} + }), [migrations]); -export default MigrationsTable; + return ( +
+
+ {createHelpText} +
+
+ + + + + + + + + {items} + +
+ + + +
+
+
+ ); +}; + +export default React.memo(MigrationsTable);