1import React, { SyntheticEvent } from 'react';
2import { render, screen } from '@testing-library/react';
3import { EventsWithValidation } from '@grafana/ui';
4import { SelectableValue } from '@grafana/data';
5import { getValueFromEventItem, promSettingsValidationEvents, PromSettings } from './PromSettings';
6import { createDefaultConfigOptions } from './mocks';
7
8describe('PromSettings', () => {
9  describe('getValueFromEventItem', () => {
10    describe('when called with undefined', () => {
11      it('then it should return empty string', () => {
12        const result = getValueFromEventItem(
13          (undefined as unknown) as SyntheticEvent<HTMLInputElement> | SelectableValue<string>
14        );
15        expect(result).toEqual('');
16      });
17    });
18
19    describe('when called with an input event', () => {
20      it('then it should return value from currentTarget', () => {
21        const value = 'An input value';
22        const result = getValueFromEventItem({ currentTarget: { value } });
23        expect(result).toEqual(value);
24      });
25    });
26
27    describe('when called with a select event', () => {
28      it('then it should return value', () => {
29        const value = 'A select value';
30        const result = getValueFromEventItem({ value });
31        expect(result).toEqual(value);
32      });
33    });
34  });
35
36  describe('promSettingsValidationEvents', () => {
37    const validationEvents = promSettingsValidationEvents;
38
39    it('should have one event handlers', () => {
40      expect(Object.keys(validationEvents).length).toEqual(1);
41    });
42
43    it('should have an onBlur handler', () => {
44      expect(validationEvents.hasOwnProperty(EventsWithValidation.onBlur)).toBe(true);
45    });
46
47    it('should have one rule', () => {
48      expect(validationEvents[EventsWithValidation.onBlur].length).toEqual(1);
49    });
50
51    describe('when calling the rule with an empty string', () => {
52      it('then it should return true', () => {
53        expect(validationEvents[EventsWithValidation.onBlur][0].rule('')).toBe(true);
54      });
55    });
56
57    it.each`
58      value    | expected
59      ${'1ms'} | ${true}
60      ${'1M'}  | ${true}
61      ${'1w'}  | ${true}
62      ${'1d'}  | ${true}
63      ${'1h'}  | ${true}
64      ${'1m'}  | ${true}
65      ${'1s'}  | ${true}
66      ${'1y'}  | ${true}
67    `(
68      "when calling the rule with correct formatted value: '$value' then result should be '$expected'",
69      ({ value, expected }) => {
70        expect(validationEvents[EventsWithValidation.onBlur][0].rule(value)).toBe(expected);
71      }
72    );
73
74    it.each`
75      value     | expected
76      ${'1 ms'} | ${false}
77      ${'1x'}   | ${false}
78      ${' '}    | ${false}
79      ${'w'}    | ${false}
80      ${'1.0s'} | ${false}
81    `(
82      "when calling the rule with incorrect formatted value: '$value' then result should be '$expected'",
83      ({ value, expected }) => {
84        expect(validationEvents[EventsWithValidation.onBlur][0].rule(value)).toBe(expected);
85      }
86    );
87  });
88  describe('PromSettings component', () => {
89    const defaultProps = createDefaultConfigOptions();
90
91    it('should show POST httpMethod if no httpMethod', () => {
92      const options = defaultProps;
93      options.url = '';
94      options.jsonData.httpMethod = '';
95
96      render(
97        <div>
98          <PromSettings onOptionsChange={() => {}} options={options} />
99        </div>
100      );
101      expect(screen.getByText('POST')).toBeInTheDocument();
102    });
103    it('should show POST httpMethod if POST httpMethod is configured', () => {
104      const options = defaultProps;
105      options.url = 'test_url';
106      options.jsonData.httpMethod = 'POST';
107
108      render(
109        <div>
110          <PromSettings onOptionsChange={() => {}} options={options} />
111        </div>
112      );
113      expect(screen.getByText('POST')).toBeInTheDocument();
114    });
115    it('should show GET httpMethod if GET httpMethod is configured', () => {
116      const options = defaultProps;
117      options.url = 'test_url';
118      options.jsonData.httpMethod = 'GET';
119
120      render(
121        <div>
122          <PromSettings onOptionsChange={() => {}} options={options} />
123        </div>
124      );
125      expect(screen.getByText('GET')).toBeInTheDocument();
126    });
127  });
128});
129