/*! * 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'; // CoreHome is a package-style cross-plugin import with no jest module mapping, so it must be // virtually mocked. Sparkline becomes a stub that declares its props (so they can be asserted), // and Tooltips is the (no-op here) directive used by the real MetricValue this component mounts. jest.mock('CoreHome', () => ({ Tooltips: {}, Sparkline: { name: 'Sparkline', props: ['params', 'seriesIndices'], template: '', }, }), { virtual: true }); // eslint-disable-next-line @typescript-eslint/no-var-requires const NoComparison = require('./NoComparison.vue').default; function makeSparkline(overrides = {}) { return { url: '?module=API&action=get&columns=nb_visits', metrics: { '': [{ value: '10,558', description: 'Visits', column: 'nb_visits' }] }, order: 1, title: null, group: '0', seriesIndices: null, graphParams: null, ...overrides, }; } function createWrapper(sparkline: unknown, allMetricsDocumentation: Record = {}) { // eslint-disable-next-line @typescript-eslint/no-explicit-any return mount(NoComparison as any, { props: { sparkline, allMetricsDocumentation } }); } describe('CoreVisualizations/NoComparison', () => { it('passes the primary metric to MetricValue as title + value', () => { const wrapper = createWrapper(makeSparkline()); const metricValue = wrapper.findComponent({ name: 'MetricValue' }); expect(metricValue.props('title')).toBe('Visits'); expect(metricValue.props('value')).toBe('10,558'); }); it('resolves the primary metric documentation by column and passes it to MetricValue', () => { const wrapper = createWrapper( makeSparkline(), { nb_visits: 'The number of visits.' }, ); expect(wrapper.findComponent({ name: 'MetricValue' }).props('documentation')) .toBe('The number of visits.'); }); it('passes undefined documentation when the metric column is unknown or empty', () => { const wrapper = createWrapper( makeSparkline({ metrics: { '': [{ value: '10,558', description: 'Visits', column: '' }] } }), { nb_visits: 'The number of visits.' }, ); expect(wrapper.findComponent({ name: 'MetricValue' }).props('documentation')).toBeUndefined(); }); it('passes a second metric to MetricValue as the secondary value + label', () => { const wrapper = createWrapper(makeSparkline({ metrics: { '': [ { value: '10,558', description: 'Visits' }, { value: '9,527', description: 'unique' }, ], }, })); const metricValue = wrapper.findComponent({ name: 'MetricValue' }); expect(metricValue.props('secondaryValue')).toBe('9,527'); expect(metricValue.props('secondaryLabel')).toBe('unique'); expect(wrapper.find('.metricValue__secondaryValue').text()).toBe('9,527'); }); it('omits the secondary line when there is only one metric', () => { const wrapper = createWrapper(makeSparkline()); const metricValue = wrapper.findComponent({ name: 'MetricValue' }); expect(metricValue.props('secondaryValue')).toBeUndefined(); expect(wrapper.find('.metricValue__secondary').exists()).toBe(false); }); it('renders an EvolutionBadge with the entry evolution props when present', () => { const wrapper = createWrapper(makeSparkline({ evolution: { percent: '+0.5%', trend: 53, isLowerValueBetter: false, tooltip: 'since last period', }, })); const badge = wrapper.findComponent({ name: 'EvolutionBadge' }); expect(badge.exists()).toBe(true); expect(badge.props('percent')).toBe('+0.5%'); expect(badge.props('trend')).toBe(53); expect(badge.props('isLowerValueBetter')).toBe(false); expect(badge.props('tooltip')).toBe('since last period'); }); it('renders no EvolutionBadge when the entry has no evolution', () => { const wrapper = createWrapper(makeSparkline()); expect(wrapper.findComponent({ name: 'EvolutionBadge' }).exists()).toBe(false); }); it('coerces a null evolution tooltip to an empty string for the badge', () => { const wrapper = createWrapper(makeSparkline({ evolution: { percent: '-2%', trend: -10, isLowerValueBetter: false, tooltip: null, }, })); expect(wrapper.findComponent({ name: 'EvolutionBadge' }).props('tooltip')).toBe(''); }); it('passes the sparkline url and series indices to the Sparkline', () => { const wrapper = createWrapper(makeSparkline({ seriesIndices: [0, 1] })); const sparkline = wrapper.findComponent({ name: 'Sparkline' }); expect(sparkline.props('params')).toBe('?module=API&action=get&columns=nb_visits'); expect(sparkline.props('seriesIndices')).toEqual([0, 1]); }); });