github.com/thanos-io/thanos@v0.32.5/pkg/ui/react-app/src/pages/graph/GraphControls.test.tsx (about)

     1  import * as React from 'react';
     2  import { shallow } from 'enzyme';
     3  import GraphControls from './GraphControls';
     4  import { Button, ButtonGroup, Form, InputGroup, InputGroupAddon, Input } from 'reactstrap';
     5  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
     6  import { faPlus, faMinus, faChartArea, faChartLine } from '@fortawesome/free-solid-svg-icons';
     7  import TimeInput from './TimeInput';
     8  
     9  const defaultGraphControlProps = {
    10    range: 60 * 60 * 24 * 1000,
    11    endTime: 1572100217898,
    12    useLocalTime: false,
    13    resolution: 10,
    14    stacked: false,
    15    maxSourceResolution: '0s',
    16  
    17    onChangeRange: (): void => {
    18      // Do nothing.
    19    },
    20    onChangeEndTime: (): void => {
    21      // Do nothing.
    22    },
    23    onChangeResolution: (): void => {
    24      // Do nothing.
    25    },
    26    onChangeStacking: (): void => {
    27      // Do nothing.
    28    },
    29    onChangeMaxSourceResolution: (): void => {
    30      // Do nothing.
    31    },
    32  };
    33  
    34  describe('GraphControls', () => {
    35    it('renders a form', () => {
    36      const controls = shallow(<GraphControls {...defaultGraphControlProps} />);
    37      const form = controls.find(Form);
    38      expect(form).toHaveLength(1);
    39      expect(form.prop('className')).toEqual('graph-controls');
    40      expect(form.prop('inline')).toBe(true);
    41    });
    42  
    43    it('renders an Input Group for range', () => {
    44      const controls = shallow(<GraphControls {...defaultGraphControlProps} />);
    45      const form = controls.find(InputGroup);
    46      expect(form).toHaveLength(1);
    47      expect(form.prop('className')).toEqual('range-input');
    48      expect(form.prop('size')).toBe('sm');
    49    });
    50  
    51    it('renders a decrease/increase range buttons', () => {
    52      [
    53        {
    54          position: 'prepend',
    55          title: 'Decrease range',
    56          icon: faMinus,
    57        },
    58        {
    59          position: 'append',
    60          title: 'Increase range',
    61          icon: faPlus,
    62        },
    63      ].forEach((testCase) => {
    64        const controls = shallow(<GraphControls {...defaultGraphControlProps} />);
    65        const addon = controls.find(InputGroupAddon).filterWhere((addon) => addon.prop('addonType') === testCase.position);
    66        const button = addon.find(Button);
    67        const icon = button.find(FontAwesomeIcon);
    68        expect(button.prop('title')).toEqual(testCase.title);
    69        expect(icon).toHaveLength(1);
    70        expect(icon.prop('icon')).toEqual(testCase.icon);
    71        expect(icon.prop('fixedWidth')).toBe(true);
    72      });
    73    });
    74  
    75    it('renders an Input for range', () => {
    76      const controls = shallow(<GraphControls {...defaultGraphControlProps} />);
    77      const form = controls.find(InputGroup);
    78      const input = form.find(Input);
    79      expect(input).toHaveLength(1);
    80      expect(input.prop('defaultValue')).toEqual('1d');
    81      expect(input.prop('innerRef')).toEqual({ current: null });
    82    });
    83  
    84    it('renders a TimeInput with props', () => {
    85      const controls = shallow(<GraphControls {...defaultGraphControlProps} />);
    86      const timeInput = controls.find(TimeInput);
    87      expect(timeInput).toHaveLength(1);
    88      expect(timeInput.prop('time')).toEqual(1572100217898);
    89      expect(timeInput.prop('range')).toEqual(86400000);
    90      expect(timeInput.prop('placeholder')).toEqual('End time');
    91    });
    92  
    93    it('renders a TimeInput with a callback', () => {
    94      const results: (number | null)[] = [];
    95      const onChange = (endTime: number | null): void => {
    96        results.push(endTime);
    97      };
    98      const controls = shallow(<GraphControls {...defaultGraphControlProps} onChangeEndTime={onChange} />);
    99      const timeInput = controls.find(TimeInput);
   100      const onChangeTime = timeInput.prop('onChangeTime');
   101      if (onChangeTime) {
   102        onChangeTime(5);
   103        expect(results).toHaveLength(1);
   104        expect(results[0]).toEqual(5);
   105        results.pop();
   106      } else {
   107        fail('Expected onChangeTime to be defined but it was not');
   108      }
   109    });
   110  
   111    it('renders a resolution Input with props', () => {
   112      const controls = shallow(<GraphControls {...defaultGraphControlProps} />);
   113      const input = controls.find(Input).filterWhere((input) => input.prop('className') === 'resolution-input');
   114      expect(input.prop('placeholder')).toEqual('Res. (s)');
   115      expect(input.prop('defaultValue')).toEqual('10');
   116      expect(input.prop('innerRef')).toEqual({ current: null });
   117      expect(input.prop('bsSize')).toEqual('sm');
   118    });
   119  
   120    it('renders a button group', () => {
   121      const controls = shallow(<GraphControls {...defaultGraphControlProps} />);
   122      const group = controls.find(ButtonGroup);
   123      expect(group.prop('className')).toEqual('stacked-input');
   124      expect(group.prop('size')).toEqual('sm');
   125    });
   126  
   127    it('renders buttons inside the button group', () => {
   128      [
   129        {
   130          title: 'Show unstacked line graph',
   131          icon: faChartLine,
   132          active: true,
   133        },
   134        {
   135          title: 'Show stacked graph',
   136          icon: faChartArea,
   137          active: false,
   138        },
   139      ].forEach((testCase) => {
   140        const controls = shallow(<GraphControls {...defaultGraphControlProps} />);
   141        const group = controls.find(ButtonGroup);
   142        const btn = group.find(Button).filterWhere((btn) => btn.prop('title') === testCase.title);
   143        expect(btn.prop('active')).toEqual(testCase.active);
   144        const icon = btn.find(FontAwesomeIcon);
   145        expect(icon.prop('icon')).toEqual(testCase.icon);
   146      });
   147    });
   148  
   149    it('renders buttons with callbacks', () => {
   150      [
   151        {
   152          title: 'Show unstacked line graph',
   153          active: true,
   154        },
   155        {
   156          title: 'Show stacked graph',
   157          active: false,
   158        },
   159      ].forEach((testCase) => {
   160        const results: boolean[] = [];
   161        const onChange = (stacked: boolean): void => {
   162          results.push(stacked);
   163        };
   164        const controls = shallow(<GraphControls {...defaultGraphControlProps} onChangeStacking={onChange} />);
   165        const group = controls.find(ButtonGroup);
   166        const btn = group.find(Button).filterWhere((btn) => btn.prop('title') === testCase.title);
   167        const onClick = btn.prop('onClick');
   168        if (onClick) {
   169          onClick({} as React.MouseEvent<HTMLButtonElement, MouseEvent>);
   170          expect(results).toHaveLength(1);
   171          expect(results[0]).toBe(!testCase.active);
   172          results.pop();
   173        } else {
   174          fail('Expected onClick to be defined but it was not');
   175        }
   176      });
   177    });
   178  
   179    it('renders a select box for max source resolution', () => {
   180      const controls = shallow(<GraphControls {...defaultGraphControlProps} />);
   181      const input = controls.find(Input).filterWhere((input) => input.prop('className') === 'max-source-resolution-input');
   182      expect(input.prop('type')).toEqual('select');
   183      expect(input.prop('value')).toEqual('0s');
   184    });
   185  });