/*! * 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'); }); });