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 <ezekiel@itsmart.my> Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
@@ -381,7 +381,7 @@ exports[`components/DatabaseSettings should match snapshot 1`] = `
|
||||
<div
|
||||
className="migrations-table-setting"
|
||||
>
|
||||
<Connect(MigrationsTable)
|
||||
<Connect(Component)
|
||||
createHelpText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="All applied migrations."
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/MigrationsTable should match snapshot when there are no migrations 1`] = `
|
||||
<div
|
||||
className="MigrationsTable migrations-table__panel"
|
||||
>
|
||||
<div
|
||||
className="help-text"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="All applied migrations."
|
||||
id="admin.database.migrations_table.help_text"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="migrations-table__table"
|
||||
>
|
||||
<table
|
||||
className="table"
|
||||
data-testid="migrationsTable"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Version"
|
||||
id="admin.database.migrations_table.version"
|
||||
/>
|
||||
</th>
|
||||
<th>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Name"
|
||||
id="admin.database.migrations_table.name"
|
||||
/>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody />
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -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 = (
|
||||
<FormattedMessage
|
||||
id='admin.database.migrations_table.help_text'
|
||||
defaultMessage='All applied migrations.'
|
||||
/>
|
||||
);
|
||||
|
||||
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(
|
||||
<MigrationsTable
|
||||
{...baseProps}
|
||||
/>);
|
||||
|
||||
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(<MigrationsTable {...withDataProps}/>);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(withDataProps.actions.getAppliedSchemaMigrations).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
act(() => {
|
||||
const newProps = {...withDataProps, className: 'foo'};
|
||||
view.rerender(<MigrationsTable {...newProps}/>);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(withDataProps.actions.getAppliedSchemaMigrations).toHaveBeenCalledTimes(1);
|
||||
mockMigrations.forEach((migration) => {
|
||||
expect(screen.getByText(migration.version)).toBeInTheDocument();
|
||||
expect(screen.getByText(migration.name)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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<SchemaMigration[]>([]);
|
||||
|
||||
class MigrationsTable extends React.PureComponent<Props, State> {
|
||||
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 (
|
||||
<tr
|
||||
key={migration.version}
|
||||
>
|
||||
<td className='whitespace--nowrap'>{migration.version}</td>
|
||||
<td className='whitespace--nowrap'>{migration.name}</td>
|
||||
</tr>
|
||||
);
|
||||
});
|
||||
handleGetAppliedSchemaMigrations();
|
||||
}, []);
|
||||
|
||||
const items = useMemo(() => migrations.map((migration) => {
|
||||
return (
|
||||
<div className={classNames('MigrationsTable', 'migrations-table__panel', this.props.className)}>
|
||||
<div className='help-text'>
|
||||
{this.props.createHelpText}
|
||||
</div>
|
||||
<div className='migrations-table__table'>
|
||||
<table
|
||||
className='table'
|
||||
data-testid='migrationsTable'
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<FormattedMessage
|
||||
id='admin.database.migrations_table.version'
|
||||
defaultMessage='Version'
|
||||
/>
|
||||
</th>
|
||||
<th>
|
||||
<FormattedMessage
|
||||
id='admin.database.migrations_table.name'
|
||||
defaultMessage='Name'
|
||||
/>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<tr
|
||||
key={migration.version}
|
||||
>
|
||||
<td className='whitespace--nowrap'>{migration.version}</td>
|
||||
<td className='whitespace--nowrap'>{migration.name}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
}), [migrations]);
|
||||
|
||||
export default MigrationsTable;
|
||||
return (
|
||||
<div className={classNames('MigrationsTable', 'migrations-table__panel', className)}>
|
||||
<div className='help-text'>
|
||||
{createHelpText}
|
||||
</div>
|
||||
<div className='migrations-table__table'>
|
||||
<table
|
||||
className='table'
|
||||
data-testid='migrationsTable'
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<FormattedMessage
|
||||
id='admin.database.migrations_table.version'
|
||||
defaultMessage='Version'
|
||||
/>
|
||||
</th>
|
||||
<th>
|
||||
<FormattedMessage
|
||||
id='admin.database.migrations_table.name'
|
||||
defaultMessage='Name'
|
||||
/>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(MigrationsTable);
|
||||
|
||||
Ссылка в новой задаче
Block a user