The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.test.tsx

177 lines
6.0 KiB

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { defaultIntervals } from '@grafana/ui';
import { TimeSrv } from '../../services/TimeSrv';
import { AutoRefreshIntervals, getValidIntervals, Props, validateIntervals } from './AutoRefreshIntervals';
const setupTestContext = (options: Partial<Props>) => {
const defaults: Props = {
refreshIntervals: ['1s', '5s', '10s'],
onRefreshIntervalChange: jest.fn(),
getIntervalsFunc: (intervals) => intervals,
validateIntervalsFunc: () => null,
};
const props = { ...defaults, ...options };
const { rerender } = render(<AutoRefreshIntervals {...props} />);
return { rerender, props };
};
describe('AutoRefreshIntervals', () => {
describe('when component is mounted with refreshIntervals', () => {
it('then supplied intervals should be shown', () => {
setupTestContext({ getIntervalsFunc: () => ['5s', '10s'] }); // remove 1s entry to validate we're calling getIntervalsFunc
expect(screen.getByRole('textbox')).toHaveValue('5s,10s');
});
});
describe('when component is mounted without refreshIntervals', () => {
it('then default intervals should be shown', () => {
setupTestContext({ refreshIntervals: null as unknown as string[] });
expect(screen.getByRole('textbox')).toHaveValue('5s,10s,30s,1m,5m,15m,30m,1h,2h,1d');
});
});
describe('when component is updated from Angular', () => {
it('then intervals should be updated', () => {
const { rerender, props } = setupTestContext({});
const newProps = { ...props, renderCount: 1, refreshIntervals: ['2s', '6s', '11s'] };
rerender(<AutoRefreshIntervals {...newProps} />);
expect(screen.getByRole('textbox')).toHaveValue('2s,6s,11s');
});
});
describe('when input loses focus and intervals are valid', () => {
it('then onRefreshIntervalChange should be called', async () => {
const { props } = setupTestContext({ validateIntervalsFunc: () => null });
await userEvent.type(screen.getByRole('textbox'), ',30s');
await userEvent.tab();
expect(screen.getByRole('textbox')).toHaveValue('1s,5s,10s,30s');
expect(props.onRefreshIntervalChange).toHaveBeenCalledTimes(1);
expect(props.onRefreshIntervalChange).toHaveBeenCalledWith(['1s', '5s', '10s', '30s']);
});
});
describe('when input loses focus and intervals are invalid', () => {
it('then onRefreshIntervalChange should not be called', async () => {
const { props } = setupTestContext({ validateIntervalsFunc: () => 'Not valid' });
await userEvent.type(screen.getByRole('textbox'), ',30q');
await userEvent.tab();
expect(screen.getByRole('textbox')).toHaveValue('1s,5s,10s,30q');
expect(props.onRefreshIntervalChange).toHaveBeenCalledTimes(0);
});
});
describe('when input loses focus and previous intervals were invalid', () => {
it('then onRefreshIntervalChange should be called', async () => {
const validateIntervalsFunc = jest.fn().mockReturnValueOnce('Not valid').mockReturnValue(null);
const { props } = setupTestContext({ validateIntervalsFunc });
await userEvent.type(screen.getByRole('textbox'), ',30q');
await userEvent.tab();
await userEvent.type(screen.getByRole('textbox'), '{backspace}s');
await userEvent.tab();
expect(screen.getByRole('textbox')).toHaveValue('1s,5s,10s,30s');
expect(props.onRefreshIntervalChange).toHaveBeenCalledTimes(1);
expect(props.onRefreshIntervalChange).toHaveBeenCalledWith(['1s', '5s', '10s', '30s']);
});
});
});
describe('getValidIntervals', () => {
describe('when called with empty intervals', () => {
it('then is should all non empty intervals', () => {
const emptyIntervals = ['', '5s', ' ', '10s', ' '];
const dependencies = {
getTimeSrv: () =>
({
getValidIntervals: (intervals: string[]) => intervals,
} as unknown as TimeSrv),
};
const result = getValidIntervals(emptyIntervals, dependencies);
expect(result).toEqual(['5s', '10s']);
});
});
describe('when called with duplicate intervals', () => {
it('then is should return no duplicates', () => {
const duplicateIntervals = ['5s', '10s', '1m', '5s', '30s', '10s', '5s', '2m'];
const dependencies = {
getTimeSrv: () =>
({
getValidIntervals: (intervals: string[]) => intervals,
} as unknown as TimeSrv),
};
const result = getValidIntervals(duplicateIntervals, dependencies);
expect(result).toEqual(['5s', '10s', '1m', '30s', '2m']);
});
});
describe('when called with untrimmed intervals', () => {
it('then is should return trimmed intervals', () => {
const duplicateIntervals = [' 5s', '10s ', ' 1m ', ' 3 0 s ', ' 2 m '];
const dependencies = {
getTimeSrv: () =>
({
getValidIntervals: (intervals: string[]) => intervals,
} as unknown as TimeSrv),
};
const result = getValidIntervals(duplicateIntervals, dependencies);
expect(result).toEqual(['5s', '10s', '1m', '30s', '2m']);
});
});
});
describe('validateIntervals', () => {
describe('when getValidIntervals does not throw', () => {
it('then it should return null', () => {
const dependencies = {
getTimeSrv: () =>
({
getValidIntervals: (intervals: string[]) => intervals,
} as unknown as TimeSrv),
};
const result = validateIntervals(defaultIntervals, dependencies);
expect(result).toBe(null);
});
});
describe('when getValidIntervals throws', () => {
it('then it should return the exception message', () => {
const dependencies = {
getTimeSrv: () =>
({
getValidIntervals: () => {
throw new Error('Some error');
},
} as unknown as TimeSrv),
};
const result = validateIntervals(defaultIntervals, dependencies);
expect(result).toEqual('Some error');
});
});
});