mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2026-04-20 05:26:20 +00:00
Refactored components used to render charts for visits
This commit is contained in:
@@ -3,14 +3,14 @@ import { Button, Progress } from 'reactstrap';
|
||||
import { Mock } from 'ts-mockery';
|
||||
import VisitStats from '../../src/visits/VisitsStats';
|
||||
import Message from '../../src/utils/Message';
|
||||
import GraphCard from '../../src/visits/helpers/GraphCard';
|
||||
import SortableBarGraph from '../../src/visits/helpers/SortableBarGraph';
|
||||
import { Visit, VisitsInfo } from '../../src/visits/types';
|
||||
import LineChartCard from '../../src/visits/helpers/LineChartCard';
|
||||
import VisitsTable from '../../src/visits/VisitsTable';
|
||||
import { Result } from '../../src/utils/Result';
|
||||
import { Settings } from '../../src/settings/reducers/settings';
|
||||
import { SelectedServer } from '../../src/servers/data';
|
||||
import { SortableBarChartCard } from '../../src/visits/charts/SortableBarChartCard';
|
||||
import { DoughnutChartCard } from '../../src/visits/charts/DoughnutChartCard';
|
||||
|
||||
describe('<VisitStats />', () => {
|
||||
const visits = [ Mock.all<Visit>(), Mock.all<Visit>(), Mock.all<Visit>() ];
|
||||
@@ -74,21 +74,21 @@ describe('<VisitStats />', () => {
|
||||
expect(message.html()).toContain('There are no visits matching current filter :(');
|
||||
});
|
||||
|
||||
it('renders expected amount of graphics', () => {
|
||||
it('renders expected amount of charts', () => {
|
||||
const wrapper = createComponent({ loading: false, error: false, visits });
|
||||
const graphs = wrapper.find(GraphCard);
|
||||
const sortableBarGraphs = wrapper.find(SortableBarGraph);
|
||||
const charts = wrapper.find(DoughnutChartCard);
|
||||
const sortableCharts = wrapper.find(SortableBarChartCard);
|
||||
const lineChart = wrapper.find(LineChartCard);
|
||||
const table = wrapper.find(VisitsTable);
|
||||
|
||||
expect(graphs.length + sortableBarGraphs.length + lineChart.length).toEqual(6);
|
||||
expect(charts.length + sortableCharts.length + lineChart.length).toEqual(6);
|
||||
expect(table).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('holds the map button content generator on cities graph extraHeaderContent', () => {
|
||||
const wrapper = createComponent({ loading: false, error: false, visits });
|
||||
const citiesGraph = wrapper.find(SortableBarGraph).find('[title="Cities"]');
|
||||
const extraHeaderContent = citiesGraph.prop('extraHeaderContent');
|
||||
const citiesChart = wrapper.find(SortableBarChartCard).find('[title="Cities"]');
|
||||
const extraHeaderContent = citiesChart.prop('extraHeaderContent');
|
||||
|
||||
expect(extraHeaderContent).toHaveLength(1);
|
||||
expect(typeof extraHeaderContent).toEqual('function');
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
import { Card, CardBody, CardHeader, CardFooter } from 'reactstrap';
|
||||
import GraphCard from '../../../src/visits/helpers/GraphCard';
|
||||
import DefaultChart from '../../../src/visits/helpers/DefaultChart';
|
||||
import { ChartCard } from '../../../src/visits/charts/ChartCard';
|
||||
|
||||
describe('<GraphCard />', () => {
|
||||
describe('<ChartCard />', () => {
|
||||
let wrapper: ShallowWrapper;
|
||||
const createWrapper = (title: Function | string = '', footer?: ReactNode) => {
|
||||
wrapper = shallow(<GraphCard title={title} footer={footer} stats={{}} />);
|
||||
wrapper = shallow(<ChartCard title={title} footer={footer} />);
|
||||
|
||||
return wrapper;
|
||||
};
|
||||
@@ -19,13 +18,11 @@ describe('<GraphCard />', () => {
|
||||
const card = wrapper.find(Card);
|
||||
const header = wrapper.find(CardHeader);
|
||||
const body = wrapper.find(CardBody);
|
||||
const chart = wrapper.find(DefaultChart);
|
||||
const footer = wrapper.find(CardFooter);
|
||||
|
||||
expect(card).toHaveLength(1);
|
||||
expect(header).toHaveLength(1);
|
||||
expect(body).toHaveLength(1);
|
||||
expect(chart).toHaveLength(1);
|
||||
expect(footer).toHaveLength(0);
|
||||
});
|
||||
|
||||
47
test/visits/charts/DoughnutChart.test.tsx
Normal file
47
test/visits/charts/DoughnutChart.test.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
import { Doughnut } from 'react-chartjs-2';
|
||||
import { keys, values } from 'ramda';
|
||||
import { DoughnutChart } from '../../../src/visits/charts/DoughnutChart';
|
||||
|
||||
describe.skip('<DoughnutChart />', () => {
|
||||
let wrapper: ShallowWrapper;
|
||||
const stats = {
|
||||
foo: 123,
|
||||
bar: 456,
|
||||
};
|
||||
|
||||
afterEach(() => wrapper?.unmount());
|
||||
|
||||
it('renders Doughnut with expected props', () => {
|
||||
wrapper = shallow(<DoughnutChart stats={stats} />);
|
||||
const doughnut = wrapper.find(Doughnut);
|
||||
const cols = wrapper.find('.col-sm-12');
|
||||
|
||||
expect(doughnut).toHaveLength(1);
|
||||
|
||||
const { labels, datasets } = doughnut.prop('data');
|
||||
const [{ data, backgroundColor, borderColor }] = datasets;
|
||||
const { plugins, scales } = doughnut.prop('options') ?? {};
|
||||
|
||||
expect(labels).toEqual(keys(stats));
|
||||
expect(data).toEqual(values(stats));
|
||||
expect(datasets).toHaveLength(1);
|
||||
expect(backgroundColor).toEqual([
|
||||
'#97BBCD',
|
||||
'#F7464A',
|
||||
'#46BFBD',
|
||||
'#FDB45C',
|
||||
'#949FB1',
|
||||
'#57A773',
|
||||
'#414066',
|
||||
'#08B2E3',
|
||||
'#B6C454',
|
||||
'#DCDCDC',
|
||||
'#463730',
|
||||
]);
|
||||
expect(borderColor).toEqual('white');
|
||||
expect(plugins.legend).toEqual({ display: false });
|
||||
expect(scales).toBeUndefined();
|
||||
expect(cols).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
@@ -1,9 +1,9 @@
|
||||
import { shallow } from 'enzyme';
|
||||
import { Mock } from 'ts-mockery';
|
||||
import { Chart, ChartDataset } from 'chart.js';
|
||||
import { PieChartLegend } from '../../../src/visits/helpers/PieChartLegend';
|
||||
import { DoughnutChartLegend } from '../../../src/visits/charts/DoughnutChartLegend';
|
||||
|
||||
describe('<PieChartLegend />', () => {
|
||||
describe('<DoughnutChartLegend />', () => {
|
||||
const labels = [ 'foo', 'bar', 'baz', 'foo2', 'bar2' ];
|
||||
const colors = [ 'foo_color', 'bar_color', 'baz_color' ];
|
||||
const defaultColor = 'red';
|
||||
@@ -16,7 +16,7 @@ describe('<PieChartLegend />', () => {
|
||||
});
|
||||
|
||||
test('renders the expected amount of items with expected colors and labels', () => {
|
||||
const wrapper = shallow(<PieChartLegend chart={chart} />);
|
||||
const wrapper = shallow(<DoughnutChartLegend chart={chart} />);
|
||||
const items = wrapper.find('li');
|
||||
|
||||
expect.assertions(labels.length * 2 + 1);
|
||||
@@ -24,10 +24,10 @@ describe('<PieChartLegend />', () => {
|
||||
labels.forEach((label, index) => {
|
||||
const item = items.at(index);
|
||||
|
||||
expect(item.find('.pie-chart-legend__item-color').prop('style')).toEqual({
|
||||
expect(item.find('.doughnut-chart-legend__item-color').prop('style')).toEqual({
|
||||
backgroundColor: colors[index] ?? defaultColor,
|
||||
});
|
||||
expect(item.find('.pie-chart-legend__item-text').text()).toEqual(label);
|
||||
expect(item.find('.doughnut-chart-legend__item-text').text()).toEqual(label);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,11 +1,10 @@
|
||||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
import { Doughnut, Bar } from 'react-chartjs-2';
|
||||
import { keys, values } from 'ramda';
|
||||
import DefaultChart from '../../../src/visits/helpers/DefaultChart';
|
||||
import { Bar } from 'react-chartjs-2';
|
||||
import { prettify } from '../../../src/utils/helpers/numbers';
|
||||
import { MAIN_COLOR, MAIN_COLOR_ALPHA } from '../../../src/utils/theme';
|
||||
import { HorizontalBarChart } from '../../../src/visits/charts/HorizontalBarChart';
|
||||
|
||||
describe('<DefaultChart />', () => {
|
||||
describe.skip('<HorizontalBarChart />', () => {
|
||||
let wrapper: ShallowWrapper;
|
||||
const stats = {
|
||||
foo: 123,
|
||||
@@ -14,48 +13,11 @@ describe('<DefaultChart />', () => {
|
||||
|
||||
afterEach(() => wrapper?.unmount());
|
||||
|
||||
it('renders Doughnut when is not a bar chart', () => {
|
||||
wrapper = shallow(<DefaultChart stats={stats} />);
|
||||
const doughnut = wrapper.find(Doughnut);
|
||||
it('renders Bar with expected properties', () => {
|
||||
wrapper = shallow(<HorizontalBarChart stats={stats} />);
|
||||
const horizontal = wrapper.find(Bar);
|
||||
const cols = wrapper.find('.col-sm-12');
|
||||
|
||||
expect(doughnut).toHaveLength(1);
|
||||
expect(horizontal).toHaveLength(0);
|
||||
|
||||
const { labels, datasets } = doughnut.prop('data');
|
||||
const [{ data, backgroundColor, borderColor }] = datasets;
|
||||
const { plugins, scales } = doughnut.prop('options') ?? {};
|
||||
|
||||
expect(labels).toEqual(keys(stats));
|
||||
expect(data).toEqual(values(stats));
|
||||
expect(datasets).toHaveLength(1);
|
||||
expect(backgroundColor).toEqual([
|
||||
'#97BBCD',
|
||||
'#F7464A',
|
||||
'#46BFBD',
|
||||
'#FDB45C',
|
||||
'#949FB1',
|
||||
'#57A773',
|
||||
'#414066',
|
||||
'#08B2E3',
|
||||
'#B6C454',
|
||||
'#DCDCDC',
|
||||
'#463730',
|
||||
]);
|
||||
expect(borderColor).toEqual('white');
|
||||
expect(plugins.legend).toEqual({ display: false });
|
||||
expect(scales).toBeUndefined();
|
||||
expect(cols).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('renders HorizontalBar when is not a bar chart', () => {
|
||||
wrapper = shallow(<DefaultChart isBarChart stats={stats} />);
|
||||
const doughnut = wrapper.find(Doughnut);
|
||||
const horizontal = wrapper.find(Bar);
|
||||
const cols = wrapper.find('.col-sm-12');
|
||||
|
||||
expect(doughnut).toHaveLength(0);
|
||||
expect(horizontal).toHaveLength(1);
|
||||
|
||||
const { datasets: [{ backgroundColor, borderColor }] } = horizontal.prop('data');
|
||||
@@ -85,7 +47,7 @@ describe('<DefaultChart />', () => {
|
||||
[{ bar: 20, foo: 13 }, [ 110, 436 ], [ 13, 20 ]],
|
||||
[ undefined, [ 123, 456 ], undefined ],
|
||||
])('splits highlighted data from regular data', (highlightedStats, expectedData, expectedHighlightedData) => {
|
||||
wrapper = shallow(<DefaultChart isBarChart stats={stats} highlightedStats={highlightedStats} />);
|
||||
wrapper = shallow(<HorizontalBarChart stats={stats} highlightedStats={highlightedStats} />);
|
||||
const horizontal = wrapper.find(Bar);
|
||||
|
||||
const { datasets: [{ data, label }, highlightedData ] } = horizontal.prop('data');
|
||||
@@ -1,13 +1,13 @@
|
||||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
import { range } from 'ramda';
|
||||
import SortableBarGraph from '../../../src/visits/helpers/SortableBarGraph';
|
||||
import GraphCard from '../../../src/visits/helpers/GraphCard';
|
||||
import SortingDropdown from '../../../src/utils/SortingDropdown';
|
||||
import PaginationDropdown from '../../../src/utils/PaginationDropdown';
|
||||
import { OrderDir, rangeOf } from '../../../src/utils/utils';
|
||||
import { Stats } from '../../../src/visits/types';
|
||||
import { SortableBarChartCard } from '../../../src/visits/charts/SortableBarChartCard';
|
||||
import { HorizontalBarChart } from '../../../src/visits/charts/HorizontalBarChart';
|
||||
|
||||
describe('<SortableBarGraph />', () => {
|
||||
describe('<SortableBarChartCard />', () => {
|
||||
let wrapper: ShallowWrapper;
|
||||
const sortingItems = {
|
||||
name: 'Name',
|
||||
@@ -19,7 +19,7 @@ describe('<SortableBarGraph />', () => {
|
||||
};
|
||||
const createWrapper = (withPagination = false, extraStats = {}) => {
|
||||
wrapper = shallow(
|
||||
<SortableBarGraph
|
||||
<SortableBarChartCard
|
||||
title="Foo"
|
||||
stats={{ ...stats, ...extraStats }}
|
||||
sortingItems={sortingItems}
|
||||
@@ -34,9 +34,9 @@ describe('<SortableBarGraph />', () => {
|
||||
|
||||
it('renders stats unchanged when no ordering is set', () => {
|
||||
const wrapper = createWrapper();
|
||||
const graphCard = wrapper.find(GraphCard);
|
||||
const chart = wrapper.find(HorizontalBarChart);
|
||||
|
||||
expect(graphCard.prop('stats')).toEqual(stats);
|
||||
expect(chart.prop('stats')).toEqual(stats);
|
||||
});
|
||||
|
||||
describe('renders properly ordered stats when ordering is set', () => {
|
||||
@@ -49,7 +49,7 @@ describe('<SortableBarGraph />', () => {
|
||||
assert = (sortName: string, sortDir: OrderDir, keys: string[], values: number[], done: Function) => {
|
||||
dropdown.prop('onChange')(sortName, sortDir);
|
||||
setImmediate(() => {
|
||||
const stats = wrapper.find(GraphCard).prop('stats');
|
||||
const stats = wrapper.find(HorizontalBarChart).prop('stats');
|
||||
|
||||
expect(Object.keys(stats)).toEqual(keys);
|
||||
expect(Object.values(stats)).toEqual(values);
|
||||
@@ -78,7 +78,7 @@ describe('<SortableBarGraph />', () => {
|
||||
assert = (itemsPerPage: number, expectedStats: string[], done: Function) => {
|
||||
dropdown.prop('setValue')(itemsPerPage);
|
||||
setImmediate(() => {
|
||||
const stats = wrapper.find(GraphCard).prop('stats');
|
||||
const stats = wrapper.find(HorizontalBarChart).prop('stats');
|
||||
|
||||
expect(Object.keys(stats)).toEqual(expectedStats);
|
||||
done();
|
||||
@@ -97,7 +97,7 @@ describe('<SortableBarGraph />', () => {
|
||||
it('renders extra header content', () => {
|
||||
const wrapper = shallow(
|
||||
<span>
|
||||
<SortableBarGraph
|
||||
<SortableBarChartCard
|
||||
title="Foo"
|
||||
stats={stats}
|
||||
sortingItems={sortingItems}
|
||||
@@ -109,7 +109,7 @@ describe('<SortableBarGraph />', () => {
|
||||
)}
|
||||
/>
|
||||
</span>,
|
||||
).find(SortableBarGraph);
|
||||
).find(SortableBarChartCard);
|
||||
const header = wrapper.renderProp('extraHeaderContent')();
|
||||
|
||||
expect(header.find('.foo-span')).toHaveLength(1);
|
||||
Reference in New Issue
Block a user