Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "none",
"comment": "Added component tests for donut chart",
"packageName": "@fluentui/react-charting",
"email": "[email protected]",
"dependentChangeType": "none"
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions packages/react-charting/docs/Component tests/DonutChartTestPlan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<div align="center">

# Component testing - Donut chart test plan

![Alt text](BasicDonutChart.png)

## Subcomponents: Pie and Legend

## Library used: jest and (enzyme or react testing library)

</div>

### Test case 1: [Snapshot testing] [Component]

- Renders donut chart correctly with data. - [enzyme]

### Test case 2: [Snapshot testing] [Individual Props] Renders donut chart with:

- HideTooltip prop set to “true”. - [enzyme]
- HideLegend prop set to “true”. - [enzyme]
- EnabledLegendsWrapLines prop set to “true”. - [enzyme]
- ValueInsideDonut set to a string / number. - [enzyme]

### Test case 3: [Specific DOM elements] Renders individual elements on a prop change:

- Should mount legend when hideLegend prop is set to “false”. - [enzyme]
- Should mount callout when hideTootip prop is set to “false”. - [enzyme]
- Should not render onRenderCalloutPerStack with just data as a prop. - [enzyme]
- Should render onRenderCalloutPerDataPoint when the prop is given otherwise should not render onRenderCalloutPerDataPoint. - [enzyme]

### Test case 4: [Mouse events – Donut chart] Renders individual elements on mouse events:

- On mouseOver on the donut chart should render callout. - [enzyme]
- On mouseMove on Pie 1 (step 1) -> mouseLeave (step 2) -> mouseMove on Pie 2 (step 3), html in step 1 should not be the same as in step 3. - [enzyme]
- On mouseover with onRenderCalloutPerDataPoint prop provided, should render the custom callout. [enzyme]
- On mouseOver, callout should be defined, on mouseLeave, callout should disappear. - [enzyme]

### Test case 5: [Mouse events – Legends] Renders individual elements on mouse events:

- On mouseOver should highlight the corresponding pie. - [RTL]
- On mouseOver should change the value inside donut with the legend value. - [enzyme]
- On click should highlight the corresponding pie with aria-selected set to “true” and tabIndex set to 0. - [RTL]
- On mouseOut after mouseOver on first legend, should have opacity 0.1 for second Pie initially (during mouseOver on first legend) and opacity set to 1 for both the Pies on mouseOut. - [RTL]

### Test case 6: [Keyboard events – Donut chart] Renders individual elements on keyboard events:

- On focus should render the corresponding callout. - [RTL]
- On blur should remove focus from the corresponding Pie. - [RTL]
2 changes: 1 addition & 1 deletion packages/react-charting/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function getEsmOnlyPackagesToCjsMapping() {
const config = createConfig({
setupFiles: ['./config/tests.js'],
snapshotSerializers: ['@fluentui/jest-serializer-merge-styles', 'enzyme-to-json/serializer'],

setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
moduleNameMapper: {
...getEsmOnlyPackagesToCjsMapping(),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const points: IChartDataPoint[] = [

const chartTitle = 'Stacked Bar chart example';

const chartPoints: IChartProps = {
export const chartPoints: IChartProps = {
chartTitle: chartTitle,
chartData: points,
};
Expand Down Expand Up @@ -159,4 +159,26 @@ describe('DonutChart - mouse events', () => {
const tree = toJson(wrapper, { mode: 'deep' });
expect(tree).toMatchSnapshot();
});

it('Should change value inside donut with the legend value on mouseOver legend ', () => {
// Arrange
wrapper = mount(<DonutChart data={chartPoints} innerRadius={55} hideLegend={false} valueInsideDonut={1000} />);

// Act
wrapper.find('LegendsBase').find('button').at(0).simulate('mouseover');

// Assert
expect(
wrapper
.findWhere(node => node.hasClass(/insideDonutString.*?/))
.at(0)
.text(),
).toBe('20,000');
expect(
wrapper
.findWhere(node => node.hasClass(/insideDonutString.*?/))
.at(1)
.text(),
).toBe('20,000');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { render, screen, queryAllByAttribute, fireEvent } from '@testing-library/react';
import { chartPoints } from './DonutChart.test';
import { DonutChart } from './index';
import * as React from 'react';

test('Should hide callout on mouse leave', () => {
// Arrange
const { container } = render(<DonutChart data={chartPoints} innerRadius={55} calloutProps={{ doNotLayer: true }} />);

// Act
const getById = queryAllByAttribute.bind(null, 'id');
fireEvent.mouseOver(getById(container, /Pie/i)[0]);
expect(getById(container, /callout/i)[0]).toBeDefined();
fireEvent.mouseLeave(getById(container, /Pie/i)[0]);

// Assert
expect(getById(container, /callout/i)[0]).toHaveStyle('opacity: 0');
});

test('Should show callout on focus', () => {
// Arrange
const { container } = render(<DonutChart data={chartPoints} innerRadius={55} calloutProps={{ doNotLayer: true }} />);

// Act
const getById = queryAllByAttribute.bind(null, 'id');
fireEvent.focus(getById(container, /Pie/i)[0]);

// Assert
expect(getById(container, /focusRing/i)).toBeDefined();
});

test('Should remove focus on blur', () => {
// Arrange
const { container } = render(<DonutChart data={chartPoints} innerRadius={55} calloutProps={{ doNotLayer: true }} />);

// Act
const getById = queryAllByAttribute.bind(null, 'id');
fireEvent.blur(getById(container, /Pie/i)[0]);

// Assert
const value = getById(container, /Pie/i)[0].getAttribute('id');
expect(value).not.toContain('focusRing');
});

test('Should highlight the corresponding Pie on mouse over on legends', () => {
// Arrange
const { container } = render(<DonutChart data={chartPoints} innerRadius={55} hideLegend={false} />);

// Act
const legend = screen.queryByText('first');
fireEvent.mouseOver(legend!);

// Assert
const getById = queryAllByAttribute.bind(null, 'id');
expect(getById(container, /Pie.*?second/i)[0]).toHaveAttribute('opacity', '0.1');
});

test('Should select legend on single mouse click on legends', () => {
// Arrange
const { container } = render(<DonutChart data={chartPoints} innerRadius={55} hideLegend={false} />);

// Act
const legend = screen.queryByText('first');
fireEvent.click(legend!);

// Assert
const getById = queryAllByAttribute.bind(null, 'id');
expect(getById(container, /Pie.*?second/i)[0]).toHaveAttribute('opacity', '0.1');
const firstLegend = screen.queryByText('first')?.closest('button');
expect(firstLegend).toHaveAttribute('aria-selected', 'true');
expect(firstLegend).toHaveAttribute('tabIndex', '0');
});

test('Should deselect legend on double mouse click on legends', () => {
// Arrange
const { container } = render(<DonutChart data={chartPoints} innerRadius={55} hideLegend={false} />);

// Act
const legend = screen.queryByText('first');
//single click on first legend
fireEvent.click(legend!);
const getById = queryAllByAttribute.bind(null, 'id');
expect(getById(container, /Pie.*?second/i)[0]).toHaveAttribute('opacity', '0.1');
const firstLegend = screen.queryByText('first')?.closest('button');
expect(firstLegend).toHaveAttribute('aria-selected', 'true');
expect(firstLegend).toHaveAttribute('tabIndex', '0');
// double click on same first legend
fireEvent.click(legend!);

// Assert
expect(firstLegend).toHaveAttribute('aria-selected', 'false');
});

test('Should show Pies with same opacity on mouse out of legends', () => {
// Arrange
const { container } = render(<DonutChart data={chartPoints} innerRadius={55} hideLegend={false} />);

// Act
const legend = screen.queryByText('first');
fireEvent.mouseOver(legend!);
const getById = queryAllByAttribute.bind(null, 'id');
expect(getById(container, /Pie.*?second/i)[0]).toHaveAttribute('opacity', '0.1');
fireEvent.mouseOut(legend!);

// Assert
expect(getById(container, /Pie.*?first/i)[0]).toHaveAttribute('opacity', '1');
expect(getById(container, /Pie.*?second/i)[0]).toHaveAttribute('opacity', '1');
});
Loading