Skip to content

Commit

Permalink
Mock ComposedCharts and add click handler tests
Browse files Browse the repository at this point in the history
  • Loading branch information
canac committed Feb 18, 2025
1 parent 74948b1 commit 96e2a30
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 40 deletions.
119 changes: 88 additions & 31 deletions src/components/Dashboard/DonationHistories/DonationHistories.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import React from 'react';
import { ThemeProvider } from '@mui/material/styles';
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import {
CategoricalChartProps,
CategoricalChartState,
} from 'recharts/types/chart/generateCategoricalChart.d';
import TestRouter from '__tests__/util/TestRouter';
import theme from 'src/theme';
import {
Expand All @@ -9,6 +14,31 @@ import {
} from './DonationHistories';
import DonationHistories from '.';

jest.mock('recharts', () => ({
...jest.requireActual('recharts'),
ComposedChart: (props: CategoricalChartProps) => (
<>
<button
onClick={() =>
props.onClick?.(
{ activePayload: [{ payload: props.data![0] }] },
null,
)
}
>
Period 1
</button>
<button
onClick={() =>
props.onClick?.(null as unknown as CategoricalChartState, null)
}
>
Outside Period
</button>
</>
),
}));

const push = jest.fn();

const router = {
Expand All @@ -17,10 +47,34 @@ const router = {
push,
};

const donationsData: DonationHistoriesData = {
accountList: {
currency: 'USD',
monthlyGoal: 100,
totalPledges: 2500,
},
reportsDonationHistories: {
periods: [
{
convertedTotal: 50,
startDate: '2019-01-01',
totals: [{ currency: 'USD', convertedAmount: 50 }],
},
{
convertedTotal: 60,
startDate: '2019-02-01',
totals: [{ currency: 'NZD', convertedAmount: 60 }],
},
],
averageIgnoreCurrent: 1000,
},
healthIndicatorData: [],
};

const TestComponent: React.FC<DonationHistoriesProps> = (props) => (
<ThemeProvider theme={theme}>
<TestRouter router={router}>
<DonationHistories {...props} />,
<DonationHistories {...props} />
</TestRouter>
</ThemeProvider>
);
Expand All @@ -36,10 +90,7 @@ describe('DonationHistories', () => {

it('empty periods', () => {
const data: DonationHistoriesData = {
accountList: {
currency: 'USD',
totalPledges: 1000,
},
...donationsData,
reportsDonationHistories: {
periods: [
{
Expand All @@ -55,7 +106,6 @@ describe('DonationHistories', () => {
],
averageIgnoreCurrent: 0,
},
healthIndicatorData: [],
};

const { getByTestId, queryByTestId } = render(
Expand All @@ -75,31 +125,7 @@ describe('DonationHistories', () => {

describe('populated periods', () => {
it('shows references', () => {
const data: DonationHistoriesData = {
accountList: {
currency: 'USD',
monthlyGoal: 100,
totalPledges: 2500,
},
reportsDonationHistories: {
periods: [
{
convertedTotal: 50,
startDate: '1-1-2019',
totals: [{ currency: 'USD', convertedAmount: 50 }],
},
{
convertedTotal: 60,
startDate: '1-2-2019',
totals: [{ currency: 'NZD', convertedAmount: 60 }],
},
],
averageIgnoreCurrent: 1000,
},
healthIndicatorData: [],
};

const { getByTestId } = render(<TestComponent data={data} />);
const { getByTestId } = render(<TestComponent data={donationsData} />);
expect(
getByTestId('DonationHistoriesTypographyGoal').textContent,
).toEqual('Goal $100');
Expand All @@ -111,4 +137,35 @@ describe('DonationHistories', () => {
).toEqual('Committed $2,500');
});
});

describe('onPeriodClick', () => {
it('is called when a period is clicked', () => {
const handlePeriodClick = jest.fn();
const { getByRole } = render(
<TestComponent
data={donationsData}
onPeriodClick={handlePeriodClick}
/>,
);

userEvent.click(getByRole('button', { name: 'Period 1' }));
expect(handlePeriodClick).toHaveBeenCalledTimes(1);
expect(handlePeriodClick.mock.calls[0][0].toISODate()).toBe(
donationsData.reportsDonationHistories.periods[0].startDate,
);
});

it('is not called when the chart is clicked', () => {
const handlePeriodClick = jest.fn();
const { getByRole } = render(
<TestComponent
data={donationsData}
onPeriodClick={handlePeriodClick}
/>,
);

userEvent.click(getByRole('button', { name: 'Outside Period' }));
expect(handlePeriodClick).not.toHaveBeenCalled();
});
});
});
16 changes: 7 additions & 9 deletions src/components/Dashboard/DonationHistories/DonationHistories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,13 @@ const DonationHistories = ({
} = calculateGraphData({ locale, data: data, currencyColors: fills });
const empty = !loading && periodsEmpty;

const handleClick: CategoricalChartFunc = (period) => {
if (!period?.activePayload) {
const handleClick: CategoricalChartFunc = (state) => {
if (!state?.activePayload) {
// The click was inside the chart but wasn't on a period
return;
}

if (onPeriodClick) {
onPeriodClick?.(period.activePayload[0].payload.period);
}
onPeriodClick?.(state.activePayload[0].payload.period);
};

return (
Expand Down Expand Up @@ -212,11 +210,11 @@ const DonationHistories = ({
</Box>
) : (
<>
<Box display={{ xs: 'none', md: 'block' }} height={250}>
<Box display={{ xs: 'none', md: 'block' }}>
{loading ? (
<BarChartSkeleton bars={12} />
) : (
<ResponsiveContainer minWidth={600}>
<ResponsiveContainer height={250}>
<ComposedChart
data={periods}
margin={{
Expand Down Expand Up @@ -288,11 +286,11 @@ const DonationHistories = ({
</ResponsiveContainer>
)}
</Box>
<Box display={{ xs: 'block', md: 'none' }} height={150}>
<Box display={{ xs: 'block', md: 'none' }}>
{loading ? (
<BarChartSkeleton bars={12} width={10} />
) : (
<ResponsiveContainer>
<ResponsiveContainer height={150}>

Check notice on line 293 in src/components/Dashboard/DonationHistories/DonationHistories.tsx

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (health-indicator)

✅ Getting better: Complex Method

DonationHistories decreases in cyclomatic complexity from 23 to 21, threshold = 10. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.
<BarChart data={periods}>
<XAxis tickLine={false} dataKey="startDate" />
<Tooltip />
Expand Down

0 comments on commit 96e2a30

Please sign in to comment.