File size: 4,991 Bytes
76a7a50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*!
 * 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: '<img class="sparkline-stub" />',
  },
}), { 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<string, string> = {}) {
  // 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]);
  });
});