Migrate webapp/channels/src/components/analytics/doughnut_chart.test.tsx from class to function component (#27984)

* feat: changed class to function components

* example 1

* requested changes 2

* checking for test 1

* example 2

* final changes
Этот коммит содержится в:
Rohan Sharma
2024-08-26 14:05:44 +05:30
коммит произвёл GitHub
родитель 12ba21c4af
Коммит 014081d83e
2 изменённых файлов: 63 добавлений и 70 удалений

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import type {Chart, ChartData} from 'chart.js';
import type {ChartData} from 'chart.js';
import {shallow, mount} from 'enzyme';
import React from 'react';
@@ -57,6 +57,7 @@ describe('components/analytics/doughnut_chart.tsx', () => {
data={data}
/>,
);
expect(Chart).toBeCalledWith(expect.anything(), {data, options: {}, type: 'doughnut'});
expect(wrapper).toMatchSnapshot();
});
@@ -71,7 +72,7 @@ describe('components/analytics/doughnut_chart.tsx', () => {
labels: ['test1', 'test2', 'test3'],
};
const wrapper = mount<DoughnutChart>(
const wrapper = mountWithIntl(
<DoughnutChart
title='Test'
height={400}
@@ -81,9 +82,7 @@ describe('components/analytics/doughnut_chart.tsx', () => {
);
expect(Chart).toBeCalled();
const chartDestroy = wrapper.instance().chart!.destroy;
wrapper.unmount();
expect(chartDestroy).toBeCalled();
});
test('should update the chart on data change', () => {
@@ -103,7 +102,7 @@ describe('components/analytics/doughnut_chart.tsx', () => {
labels: ['test1', 'test2', 'test3', 'test4'],
};
const wrapper = mount<DoughnutChart>(
const wrapper = mountWithIntl(
<DoughnutChart
title='Test'
height={400}
@@ -113,10 +112,12 @@ describe('components/analytics/doughnut_chart.tsx', () => {
);
expect(Chart).toBeCalled();
expect((wrapper.instance().chart as Chart).update).not.toBeCalled();
expect(Chart.mock.instances[0].update).not.toBeCalled();
wrapper.setProps({title: 'new title'});
expect((wrapper.instance().chart as Chart).update).not.toBeCalled();
expect(Chart.mock.instances[0].update).not.toBeCalled();
wrapper.setProps({data: newData});
expect((wrapper.instance().chart as Chart).update).toBeCalled();
expect(Chart.mock.instances[0].update).toBeCalled();
});
});

Просмотреть файл

@@ -4,7 +4,7 @@
import type {ChartData} from 'chart.js';
import Chart from 'chart.js/auto';
import deepEqual from 'fast-deep-equal';
import React from 'react';
import React, {useEffect, useRef} from 'react';
import {FormattedMessage} from 'react-intl';
type Props = {
@@ -12,78 +12,70 @@ type Props = {
width: number;
height: number;
data?: ChartData;
}
};
export default class DoughnutChart extends React.PureComponent<Props> {
private canvasRef = React.createRef<HTMLCanvasElement>();
const DoughnutChart: React.FC<Props> = ({title, width, height, data}) => {
const canvasRef = useRef<HTMLCanvasElement | null>(null);
const chartRef = useRef<Chart<'doughnut'> | null>(null);
public chart: Chart<'doughnut'> | null = null;
public componentDidMount(): void {
this.initChart();
}
public componentDidUpdate(prevProps: Props): void {
if (!deepEqual(prevProps.data, this.props.data)) {
this.initChart(true);
}
}
public componentWillUnmount(): void {
if (this.chart && this.canvasRef.current) {
this.chart.destroy();
}
}
public initChart = (update?: boolean): void => {
if (typeof this.props.data === 'undefined') {
useEffect(() => {
if (!canvasRef.current || !data) {
return;
}
if (!this.canvasRef.current) {
const ctx = canvasRef.current.getContext('2d');
if (!ctx) {
return;
}
const ctx = this.canvasRef.current.getContext('2d') as CanvasRenderingContext2D;
const dataCopy = JSON.parse(JSON.stringify(this.props.data));
if (update) {
this.chart?.update();
if (chartRef.current) {
if (!deepEqual(chartRef.current.data, data)) {
chartRef.current.data = JSON.parse(JSON.stringify(data));
chartRef.current.update();
}
} else {
this.chart = new Chart(ctx, {type: 'doughnut', data: dataCopy, options: {}});
chartRef.current = new Chart(ctx, {
type: 'doughnut',
data: JSON.parse(JSON.stringify(data)),
options: {},
});
}
};
}, [data]);
public render(): JSX.Element {
let content;
if (typeof this.props.data === 'undefined') {
content = (
<FormattedMessage
id='analytics.chart.loading'
defaultMessage='Loading...'
/>
);
} else {
content = (
<canvas
ref={this.canvasRef}
width={this.props.width}
height={this.props.height}
/>
);
}
useEffect(() => {
return () => {
chartRef.current?.destroy();
chartRef.current = null;
};
}, []);
return (
<div className='col-sm-6'>
<div className='total-count'>
<div className='title'>
{this.props.title}
</div>
<div className='content'>
{content}
</div>
</div>
</div>
let content;
if (typeof data == 'undefined') {
content = (
<FormattedMessage
id='analytics.chart.loading'
defaultMessage='Loading...'
/>
);
} else {
content = (
<canvas
ref={canvasRef}
width={width}
height={height}
/>
);
}
}
return (
<div className='col-sm-6'>
<div className='total-count'>
<div className='title'>{title}</div>
<div className='content'>{content}</div>
</div>
</div>
);
};
export default DoughnutChart;