/*!
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
import { mount } from '@vue/test-utils';
// The shell renders the real NoComparison body, which mounts the real MetricValue (Tooltips
// directive) and the Sparkline. CoreHome has no jest module mapping, so mock it virtually.
jest.mock('CoreHome', () => ({
Tooltips: {},
Sparkline: {
name: 'Sparkline',
props: ['params', 'seriesIndices'],
template: '
',
},
// SparklineCard derives graph-params from the sparkline url; parse a query string like the real
// MatomoUrl.parse (which receives the query string without its leading '?').
MatomoUrl: {
parse: (search: string) => {
const params: Record = {};
new URLSearchParams(search).forEach((value, key) => {
params[key] = value;
});
return params;
},
},
}), { virtual: true });
// eslint-disable-next-line @typescript-eslint/no-var-requires
const SparklineCard = require('./SparklineCard.vue').default;
describe('CoreVisualizations/SparklineCard', () => {
const baseSparkline = {
url: '?module=API&action=get&columns=nb_visits',
metrics: { '': [{ value: '1,234', description: 'Visits', column: 'nb_visits' }] },
order: 1,
title: null,
group: '0',
seriesIndices: null,
graphParams: null,
};
function createWrapper(
sparkline: unknown = baseSparkline,
areSparklinesLinkable = true,
allMetricsDocumentation: Record = {},
) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return mount(SparklineCard as any, {
props: { sparkline, areSparklinesLinkable, allMetricsDocumentation },
});
}
it('renders the no-comparison body and forwards the sparkline to it', () => {
const wrapper = createWrapper();
const body = wrapper.findComponent({ name: 'NoComparison' });
expect(body.exists()).toBe(true);
expect(body.props('sparkline')).toEqual(baseSparkline);
});
it('forwards allMetricsDocumentation to the body so the title shows the metric tooltip', () => {
const wrapper = createWrapper(baseSparkline, true, { nb_visits: 'The number of visits.' });
const body = wrapper.findComponent({ name: 'NoComparison' });
expect(body.props('allMetricsDocumentation')).toEqual({ nb_visits: 'The number of visits.' });
expect(wrapper.find('.metricValue__title').attributes('title')).toBe('The number of visits.');
});
it('renders the card frame classes and composes the primary value + sparkline', () => {
const wrapper = createWrapper();
expect(wrapper.classes()).toContain('sparkline');
expect(wrapper.classes()).toContain('sparklineCard');
expect(wrapper.classes()).not.toContain('notLinkable');
expect(wrapper.find('.metricValue__title').text()).toBe('Visits');
expect(wrapper.find('.metricValue__number').text()).toBe('1,234');
expect(wrapper.find('.sparkline-stub').exists()).toBe(true);
});
it('does not render the segment title region in no-comparison mode', () => {
const wrapper = createWrapper();
expect(wrapper.find('.sparklineCard__title').exists()).toBe(false);
});
it('renders the segment title region when sparkline.title is set', () => {
const wrapper = createWrapper({ ...baseSparkline, title: 'Firefox' });
expect(wrapper.find('.sparklineCard__title').text()).toBe('Firefox');
});
it('omits graph-params / series-indices when none is set nor derivable from the url', () => {
const wrapper = createWrapper({ ...baseSparkline, url: '?module=API&action=get' });
expect(wrapper.attributes('data-graph-params')).toBeUndefined();
expect(wrapper.attributes('data-series-indices')).toBeUndefined();
});
it('derives graph-params columns/rows/idGoal from the url when graphParams is empty', () => {
// The reused Sparkline renders its image with `src` (no `data-src`), so the legacy click
// handler can't read the reload columns off the img; the card supplies them from its url.
const wrapper = createWrapper({
...baseSparkline,
url: '?module=API&action=get&columns=nb_visits&rows=Search&idGoal=1',
});
expect(wrapper.attributes('data-graph-params')).toBe(
'{"columns":"nb_visits","rows":"Search","idGoal":"1"}',
);
});
it('emits explicit graphParams verbatim, taking precedence over the url', () => {
const wrapper = createWrapper({
...baseSparkline,
// url carries nb_visits, but explicit graphParams wins.
graphParams: { columns: 'nb_actions' },
seriesIndices: [0, 1],
});
expect(wrapper.attributes('data-graph-params')).toBe('{"columns":"nb_actions"}');
expect(wrapper.attributes('data-series-indices')).toBe('[0,1]');
});
it('adds the notLinkable class when sparklines are not linkable', () => {
const wrapper = createWrapper(baseSparkline, false);
expect(wrapper.classes()).toContain('notLinkable');
});
});