gitlab-ce/spec/frontend/observability/utils_spec.js

294 lines
9.5 KiB
JavaScript

import {
periodToDate,
periodToDateRange,
dateFilterObjToQuery,
queryToDateFilterObj,
addTimeToDate,
formattedTimeFromDate,
isTracingDateRangeOutOfBounds,
validatedDateRangeQuery,
parseGraphQLIssueLinksToRelatedIssues,
createIssueUrlWithDetails,
} from '~/observability/utils';
import {
CUSTOM_DATE_RANGE_OPTION,
DATE_RANGE_QUERY_KEY,
DATE_RANGE_START_QUERY_KEY,
DATE_RANGE_END_QUERY_KEY,
TIMESTAMP_QUERY_KEY,
TIME_RANGE_OPTIONS_VALUES,
} from '~/observability/constants';
import { mockGraphQlIssueLinks, mockRelatedIssues } from './mock_data';
const MOCK_NOW_DATE = new Date('2023-10-09 15:30:00');
const realDateNow = Date.now;
describe('periodToDate', () => {
beforeEach(() => {
global.Date.now = jest.fn().mockReturnValue(MOCK_NOW_DATE);
});
afterEach(() => {
global.Date.now = realDateNow;
});
it.each`
periodLabel | period | expectedMinDate
${'minutes (m)'} | ${'30m'} | ${new Date('2023-10-09 15:00:00')}
${'hours (h)'} | ${'2h'} | ${new Date('2023-10-09 13:30:00')}
${'days (d)'} | ${'7d'} | ${new Date('2023-10-02 15:30:00')}
`('should return the correct date range for $periodLabel', ({ period, expectedMinDate }) => {
const result = periodToDate(period);
expect(result.min).toEqual(expectedMinDate);
expect(result.max).toEqual(MOCK_NOW_DATE);
});
it('should return an empty object if period value is not a positive integer', () => {
expect(periodToDate('')).toEqual({});
expect(periodToDate('-5d')).toEqual({});
expect(periodToDate('invalid')).toEqual({});
});
it('should return an empty object if unit is not "m", "h", or "d"', () => {
expect(periodToDate('2w')).toEqual({});
});
});
describe('periodToDateRange', () => {
beforeEach(() => {
global.Date.now = jest.fn().mockReturnValue(MOCK_NOW_DATE);
});
afterEach(() => {
global.Date.now = realDateNow;
});
it('returns a date range object from period', () => {
expect(periodToDateRange('30m')).toEqual({
value: 'custom',
endDate: new Date('2023-10-09T15:30:00.000Z'),
startDate: new Date('2023-10-09T15:00:00.000Z'),
});
});
});
describe('queryToDateFilterObj', () => {
it('returns default date range if no query params provided', () => {
expect(queryToDateFilterObj({})).toEqual({ value: '1h' });
});
it('returns query params with provided value', () => {
expect(
queryToDateFilterObj({
[DATE_RANGE_QUERY_KEY]: '7d',
}),
).toEqual({ value: '7d' });
});
it('returns custom range if custom params provided', () => {
const query = {
[DATE_RANGE_QUERY_KEY]: CUSTOM_DATE_RANGE_OPTION,
[DATE_RANGE_START_QUERY_KEY]: '2020-01-01T00:00:00.000Z',
[DATE_RANGE_END_QUERY_KEY]: '2020-01-02T00:00:00.000Z',
};
expect(queryToDateFilterObj(query)).toEqual({
value: CUSTOM_DATE_RANGE_OPTION,
startDate: new Date('2020-01-01T00:00:00.000Z'),
endDate: new Date('2020-01-02T00:00:00.000Z'),
});
});
it('returns default range if custom params invalid', () => {
const query = {
[DATE_RANGE_QUERY_KEY]: CUSTOM_DATE_RANGE_OPTION,
[DATE_RANGE_START_QUERY_KEY]: 'invalid',
[DATE_RANGE_END_QUERY_KEY]: 'invalid',
};
expect(queryToDateFilterObj(query)).toEqual({ value: '1h' });
});
it('returns a date range object from a nano timestamp', () => {
expect(queryToDateFilterObj({ timestamp: '2024-02-19T16:10:15.4433398Z' })).toEqual({
value: CUSTOM_DATE_RANGE_OPTION,
startDate: new Date('2024-02-19T16:10:15.443Z'),
endDate: new Date('2024-02-19T16:10:15.443Z'),
timestamp: '2024-02-19T16:10:15.4433398Z',
});
});
});
describe('dateFilterObjToQuery', () => {
it('converts a default date filter', () => {
expect(
dateFilterObjToQuery({
value: '7d',
}),
).toEqual({
[DATE_RANGE_QUERY_KEY]: '7d',
});
});
it('converts custom filter', () => {
const filter = {
value: CUSTOM_DATE_RANGE_OPTION,
startDate: new Date('2020-01-01T00:00:00.000Z'),
endDate: new Date('2020-01-02T00:00:00.000Z'),
};
expect(dateFilterObjToQuery(filter)).toEqual({
[DATE_RANGE_QUERY_KEY]: CUSTOM_DATE_RANGE_OPTION,
[DATE_RANGE_START_QUERY_KEY]: '2020-01-01T00:00:00.000Z',
[DATE_RANGE_END_QUERY_KEY]: '2020-01-02T00:00:00.000Z',
});
});
it('converts a filter with timestamp', () => {
expect(dateFilterObjToQuery({ timestamp: '2024-02-19T16:10:15.4433398Z' })).toEqual({
[TIMESTAMP_QUERY_KEY]: '2024-02-19T16:10:15.4433398Z',
});
});
it('returns empty object if filter is empty', () => {
expect(dateFilterObjToQuery({})).toEqual({});
});
it('returns empty object if filter undefined', () => {
expect(dateFilterObjToQuery()).toEqual({});
});
});
describe('formattedTimeFromDate', () => {
it('should return an empty string when given an invalid date', () => {
expect(formattedTimeFromDate(null)).toBe('');
expect(formattedTimeFromDate(undefined)).toBe('');
expect(formattedTimeFromDate('invalid')).toBe('');
});
it('should return the time in the format "HH:mm:ss"', () => {
const date = new Date('2023-04-20T12:00:56.789Z');
expect(formattedTimeFromDate(date)).toBe('12:00:56');
});
it('should pad single-digit hours, minutes, and seconds with a leading zero', () => {
const date = new Date('2023-04-20T07:08:09.012Z');
expect(formattedTimeFromDate(date)).toBe('07:08:09');
});
});
describe('addTimeToDate', () => {
it('should add the time to the date', () => {
const origDate = new Date('2023-04-01T00:00:00.000Z');
const timeString = '12:34:56';
const result = addTimeToDate(timeString, origDate);
expect(result).toEqual(new Date('2023-04-01T12:34:56.000Z'));
});
it('should handle missing seconds', () => {
const origDate = new Date('2023-04-01T00:00:00.000Z');
const timeString = '12:34';
const result = addTimeToDate(timeString, origDate);
expect(result).toEqual(new Date('2023-04-01T12:34:00.000Z'));
});
it('should gracefully handle missing minutes and seconds', () => {
const origDate = new Date('2023-04-01T00:00:00.000Z');
const timeString = '12';
expect(addTimeToDate(timeString, origDate)).toEqual(origDate);
});
it('should gracefully handle invalid time strings', () => {
const origDate = new Date('2023-04-01T00:00:00.000Z');
const timeString = 'invalid';
expect(addTimeToDate(timeString, origDate)).toEqual(origDate);
});
it('should gracefully handle empty time strings', () => {
const origDate = new Date('2023-04-01T00:00:00.000Z');
const timeString = '';
expect(addTimeToDate(timeString, origDate)).toEqual(origDate);
});
});
describe('isTracingDateRangeOutOfBounds', () => {
it('returns false if date range is not custom', () => {
expect(isTracingDateRangeOutOfBounds({ value: TIME_RANGE_OPTIONS_VALUES.FIVE_MIN })).toBe(
false,
);
});
it('returns true if custom date range is <= 12h', () => {
expect(
isTracingDateRangeOutOfBounds({
value: CUSTOM_DATE_RANGE_OPTION,
startDate: new Date('2023-04-01T00:00:00'),
endDate: new Date('2023-04-01T12:00:00'),
}),
).toBe(false);
});
it('returns true if custom date range is > 12h', () => {
expect(
isTracingDateRangeOutOfBounds({
value: CUSTOM_DATE_RANGE_OPTION,
startDate: new Date('2023-04-01T00:00:00'),
endDate: new Date('2023-04-01T12:00:01'),
}),
).toBe(true);
});
it('returns true if custom date range is in invalid', () => {
expect(
isTracingDateRangeOutOfBounds({
value: CUSTOM_DATE_RANGE_OPTION,
startDate: 'foo',
endDate: 'baz',
}),
).toBe(true);
});
});
describe('validatedDateRangeQuery', () => {
it('returns the default time range when dateRangeValue is not "custom"', () => {
const result = validatedDateRangeQuery('1h', '', '');
expect(result).toEqual({ value: '1h' });
});
it('returns the default time range when dateRangeStart or dateRangeEnd is invalid', () => {
const result = validatedDateRangeQuery('custom', 'invalid', '2023-05-01T00:00:00.000Z');
expect(result).toEqual({ value: '1h' });
});
it('returns the custom date range when dateRangeValue is "custom" and dateRangeStart and dateRangeEnd are valid', () => {
const startDate = '2023-04-01T00:00:00.000Z';
const endDate = '2023-05-01T00:00:00.000Z';
const result = validatedDateRangeQuery('custom', startDate, endDate);
expect(result).toEqual({
value: 'custom',
startDate: new Date(startDate),
endDate: new Date(endDate),
});
});
it('returns the default date range when dateRangeValue is custom but dateRangeStart or dateRangeEnd are invalid', () => {
const result = validatedDateRangeQuery('custom', 'foo', 'bar');
expect(result).toEqual({ value: '1h' });
});
it('returns the default time range when dateRangeValue is undefined', () => {
const result = validatedDateRangeQuery(undefined, '', '');
expect(result).toEqual({ value: '1h' });
});
});
describe('createIssueUrlWithDetails', () => {
it('returns the create issue urls with params', () => {
expect(
createIssueUrlWithDetails('http://gdk.test:3443/?foo=bar', { a: 'b', c: 'd' }, 'my_param'),
).toBe(
'http://gdk.test:3443/?foo=bar&my_param=%7B%22a%22%3A%22b%22%2C%22c%22%3A%22d%22%7D&issue%5Bconfidential%5D=true',
);
});
});
describe('parseGraphQLIssueLinksToRelatedIssues', () => {
it('converts a graphql issue object to a related issue', () => {
expect(parseGraphQLIssueLinksToRelatedIssues(mockGraphQlIssueLinks)).toEqual(mockRelatedIssues);
});
});