diff options
Diffstat (limited to 'spec/frontend/lib')
-rw-r--r-- | spec/frontend/lib/utils/ajax_cache_spec.js | 2 | ||||
-rw-r--r-- | spec/frontend/lib/utils/array_utility_spec.js | 32 | ||||
-rw-r--r-- | spec/frontend/lib/utils/color_utils_spec.js | 17 | ||||
-rw-r--r-- | spec/frontend/lib/utils/common_utils_spec.js | 8 | ||||
-rw-r--r-- | spec/frontend/lib/utils/datetime_utility_spec.js | 345 | ||||
-rw-r--r-- | spec/frontend/lib/utils/poll_spec.js | 2 | ||||
-rw-r--r-- | spec/frontend/lib/utils/poll_until_complete_spec.js | 2 | ||||
-rw-r--r-- | spec/frontend/lib/utils/unit_format/formatter_factory_spec.js | 21 | ||||
-rw-r--r-- | spec/frontend/lib/utils/url_utility_spec.js | 55 |
9 files changed, 382 insertions, 102 deletions
diff --git a/spec/frontend/lib/utils/ajax_cache_spec.js b/spec/frontend/lib/utils/ajax_cache_spec.js index 641dd3684fa..d4b95172d18 100644 --- a/spec/frontend/lib/utils/ajax_cache_spec.js +++ b/spec/frontend/lib/utils/ajax_cache_spec.js @@ -1,6 +1,6 @@ import MockAdapter from 'axios-mock-adapter'; -import axios from '~/lib/utils/axios_utils'; import AjaxCache from '~/lib/utils/ajax_cache'; +import axios from '~/lib/utils/axios_utils'; describe('AjaxCache', () => { const dummyEndpoint = '/AjaxCache/dummyEndpoint'; diff --git a/spec/frontend/lib/utils/array_utility_spec.js b/spec/frontend/lib/utils/array_utility_spec.js new file mode 100644 index 00000000000..b95286ff254 --- /dev/null +++ b/spec/frontend/lib/utils/array_utility_spec.js @@ -0,0 +1,32 @@ +import * as arrayUtils from '~/lib/utils/array_utility'; + +describe('array_utility', () => { + describe('swapArrayItems', () => { + it.each` + array | leftIndex | rightIndex | result + ${[]} | ${0} | ${0} | ${[]} + ${[1]} | ${0} | ${1} | ${[1]} + ${[1, 2]} | ${0} | ${0} | ${[1, 2]} + ${[1, 2]} | ${0} | ${1} | ${[2, 1]} + ${[1, 2]} | ${1} | ${2} | ${[1, 2]} + ${[1, 2]} | ${2} | ${1} | ${[1, 2]} + ${[1, 2]} | ${1} | ${10} | ${[1, 2]} + ${[1, 2]} | ${10} | ${1} | ${[1, 2]} + ${[1, 2]} | ${1} | ${-1} | ${[1, 2]} + ${[1, 2]} | ${-1} | ${1} | ${[1, 2]} + ${[1, 2, 3]} | ${1} | ${1} | ${[1, 2, 3]} + ${[1, 2, 3]} | ${0} | ${2} | ${[3, 2, 1]} + ${[1, 2, 3, 4]} | ${0} | ${2} | ${[3, 2, 1, 4]} + ${[1, 2, 3, 4, 5]} | ${0} | ${4} | ${[5, 2, 3, 4, 1]} + ${[1, 2, 3, 4, 5]} | ${1} | ${2} | ${[1, 3, 2, 4, 5]} + ${[1, 2, 3, 4, 5]} | ${2} | ${1} | ${[1, 3, 2, 4, 5]} + `( + 'given $array with index $leftIndex and $rightIndex will return $result', + ({ array, leftIndex, rightIndex, result }) => { + const actual = arrayUtils.swapArrayItems(array, leftIndex, rightIndex); + expect(actual).toEqual(result); + expect(actual).not.toBe(array); + }, + ); + }); +}); diff --git a/spec/frontend/lib/utils/color_utils_spec.js b/spec/frontend/lib/utils/color_utils_spec.js index 433e9d5a85e..8c846abd77f 100644 --- a/spec/frontend/lib/utils/color_utils_spec.js +++ b/spec/frontend/lib/utils/color_utils_spec.js @@ -1,4 +1,4 @@ -import { textColorForBackground, hexToRgb } from '~/lib/utils/color_utils'; +import { textColorForBackground, hexToRgb, validateHexColor } from '~/lib/utils/color_utils'; describe('Color utils', () => { describe('Converting hex code to rgb', () => { @@ -32,4 +32,19 @@ describe('Color utils', () => { expect(textColorForBackground('#000')).toEqual('#FFFFFF'); }); }); + + describe('Validate hex color', () => { + it.each` + color | output + ${undefined} | ${null} + ${null} | ${null} + ${''} | ${null} + ${'ABC123'} | ${false} + ${'#ZZZ'} | ${false} + ${'#FF0'} | ${true} + ${'#FF0000'} | ${true} + `('returns $output when $color is given', ({ color, output }) => { + expect(validateHexColor(color)).toEqual(output); + }); + }); }); diff --git a/spec/frontend/lib/utils/common_utils_spec.js b/spec/frontend/lib/utils/common_utils_spec.js index 90222f0f718..18be88a0b8b 100644 --- a/spec/frontend/lib/utils/common_utils_spec.js +++ b/spec/frontend/lib/utils/common_utils_spec.js @@ -1045,4 +1045,12 @@ describe('common_utils', () => { expect(commonUtils.getDashPath('/some/url')).toEqual(null); }); }); + + describe('convertArrayToCamelCase', () => { + it('returns a new array with snake_case string elements converted camelCase', () => { + const result = commonUtils.convertArrayToCamelCase(['hello', 'hello_world']); + + expect(result).toEqual(['hello', 'helloWorld']); + }); + }); }); diff --git a/spec/frontend/lib/utils/datetime_utility_spec.js b/spec/frontend/lib/utils/datetime_utility_spec.js index 66efd43262b..32a24227cbd 100644 --- a/spec/frontend/lib/utils/datetime_utility_spec.js +++ b/spec/frontend/lib/utils/datetime_utility_spec.js @@ -1,8 +1,8 @@ import $ from 'jquery'; import timezoneMock from 'timezone-mock'; +import * as datetimeUtility from '~/lib/utils/datetime_utility'; import { __, s__ } from '~/locale'; import '~/commons/bootstrap'; -import * as datetimeUtility from '~/lib/utils/datetime_utility'; describe('Date time utils', () => { describe('timeFor', () => { @@ -584,22 +584,6 @@ describe('secondsToMilliseconds', () => { }); }); -describe('dayAfter', () => { - const date = new Date('2019-07-16T00:00:00.000Z'); - - it('returns the following date', () => { - const nextDay = datetimeUtility.dayAfter(date); - const expectedNextDate = new Date('2019-07-17T00:00:00.000Z'); - - expect(nextDay).toStrictEqual(expectedNextDate); - }); - - it('does not modifiy the original date', () => { - datetimeUtility.dayAfter(date); - expect(date).toStrictEqual(new Date('2019-07-16T00:00:00.000Z')); - }); -}); - describe('secondsToDays', () => { it('converts seconds to days correctly', () => { expect(datetimeUtility.secondsToDays(0)).toBe(0); @@ -608,90 +592,214 @@ describe('secondsToDays', () => { }); }); -describe('nDaysAfter', () => { - const date = new Date('2019-07-16T00:00:00.000Z'); +describe('date addition/subtraction methods', () => { + beforeEach(() => { + timezoneMock.register('US/Eastern'); + }); - it.each` - numberOfDays | expectedResult - ${1} | ${new Date('2019-07-17T00:00:00.000Z').valueOf()} - ${90} | ${new Date('2019-10-14T00:00:00.000Z').valueOf()} - ${-1} | ${new Date('2019-07-15T00:00:00.000Z').valueOf()} - ${0} | ${date.valueOf()} - ${0.9} | ${date.valueOf()} - `('returns $numberOfDays day(s) after the provided date', ({ numberOfDays, expectedResult }) => { - expect(datetimeUtility.nDaysAfter(date, numberOfDays)).toBe(expectedResult); + afterEach(() => { + timezoneMock.unregister(); }); -}); -describe('nDaysBefore', () => { - const date = new Date('2019-07-16T00:00:00.000Z'); + describe('dayAfter', () => { + const input = '2019-03-10T00:00:00.000Z'; + const expectedLocalResult = '2019-03-10T23:00:00.000Z'; + const expectedUTCResult = '2019-03-11T00:00:00.000Z'; + + it.each` + inputAsString | options | expectedAsString + ${input} | ${undefined} | ${expectedLocalResult} + ${input} | ${{}} | ${expectedLocalResult} + ${input} | ${{ utc: false }} | ${expectedLocalResult} + ${input} | ${{ utc: true }} | ${expectedUTCResult} + `( + 'when the provided date is $inputAsString and the options parameter is $options, returns $expectedAsString', + ({ inputAsString, options, expectedAsString }) => { + const inputDate = new Date(inputAsString); + const actual = datetimeUtility.dayAfter(inputDate, options); + + expect(actual.toISOString()).toBe(expectedAsString); + }, + ); + + it('does not modifiy the original date', () => { + const inputDate = new Date(input); + datetimeUtility.dayAfter(inputDate); + expect(inputDate.toISOString()).toBe(input); + }); + }); - it.each` - numberOfDays | expectedResult - ${1} | ${new Date('2019-07-15T00:00:00.000Z').valueOf()} - ${90} | ${new Date('2019-04-17T00:00:00.000Z').valueOf()} - ${-1} | ${new Date('2019-07-17T00:00:00.000Z').valueOf()} - ${0} | ${date.valueOf()} - ${0.9} | ${new Date('2019-07-15T00:00:00.000Z').valueOf()} - `('returns $numberOfDays day(s) before the provided date', ({ numberOfDays, expectedResult }) => { - expect(datetimeUtility.nDaysBefore(date, numberOfDays)).toBe(expectedResult); + describe('nDaysAfter', () => { + const input = '2019-07-16T00:00:00.000Z'; + + it.each` + inputAsString | numberOfDays | options | expectedAsString + ${input} | ${1} | ${undefined} | ${'2019-07-17T00:00:00.000Z'} + ${input} | ${-1} | ${undefined} | ${'2019-07-15T00:00:00.000Z'} + ${input} | ${0} | ${undefined} | ${'2019-07-16T00:00:00.000Z'} + ${input} | ${0.9} | ${undefined} | ${'2019-07-16T00:00:00.000Z'} + ${input} | ${120} | ${undefined} | ${'2019-11-13T01:00:00.000Z'} + ${input} | ${120} | ${{}} | ${'2019-11-13T01:00:00.000Z'} + ${input} | ${120} | ${{ utc: false }} | ${'2019-11-13T01:00:00.000Z'} + ${input} | ${120} | ${{ utc: true }} | ${'2019-11-13T00:00:00.000Z'} + `( + 'when the provided date is $inputAsString, numberOfDays is $numberOfDays, and the options parameter is $options, returns $expectedAsString', + ({ inputAsString, numberOfDays, options, expectedAsString }) => { + const inputDate = new Date(inputAsString); + const actual = datetimeUtility.nDaysAfter(inputDate, numberOfDays, options); + + expect(actual.toISOString()).toBe(expectedAsString); + }, + ); }); -}); -describe('nMonthsAfter', () => { - // February has 28 days - const feb2019 = new Date('2019-02-15T00:00:00.000Z'); - // Except in 2020, it had 29 days - const feb2020 = new Date('2020-02-15T00:00:00.000Z'); - // April has 30 days - const apr2020 = new Date('2020-04-15T00:00:00.000Z'); - // May has 31 days - const may2020 = new Date('2020-05-15T00:00:00.000Z'); + describe('nDaysBefore', () => { + const input = '2019-07-16T00:00:00.000Z'; + + it.each` + inputAsString | numberOfDays | options | expectedAsString + ${input} | ${1} | ${undefined} | ${'2019-07-15T00:00:00.000Z'} + ${input} | ${-1} | ${undefined} | ${'2019-07-17T00:00:00.000Z'} + ${input} | ${0} | ${undefined} | ${'2019-07-16T00:00:00.000Z'} + ${input} | ${0.9} | ${undefined} | ${'2019-07-15T00:00:00.000Z'} + ${input} | ${180} | ${undefined} | ${'2019-01-17T01:00:00.000Z'} + ${input} | ${180} | ${{}} | ${'2019-01-17T01:00:00.000Z'} + ${input} | ${180} | ${{ utc: false }} | ${'2019-01-17T01:00:00.000Z'} + ${input} | ${180} | ${{ utc: true }} | ${'2019-01-17T00:00:00.000Z'} + `( + 'when the provided date is $inputAsString, numberOfDays is $numberOfDays, and the options parameter is $options, returns $expectedAsString', + ({ inputAsString, numberOfDays, options, expectedAsString }) => { + const inputDate = new Date(inputAsString); + const actual = datetimeUtility.nDaysBefore(inputDate, numberOfDays, options); + + expect(actual.toISOString()).toBe(expectedAsString); + }, + ); + }); - it.each` - date | numberOfMonths | expectedResult - ${feb2019} | ${1} | ${new Date('2019-03-15T00:00:00.000Z').valueOf()} - ${feb2020} | ${1} | ${new Date('2020-03-15T00:00:00.000Z').valueOf()} - ${apr2020} | ${1} | ${new Date('2020-05-15T00:00:00.000Z').valueOf()} - ${may2020} | ${1} | ${new Date('2020-06-15T00:00:00.000Z').valueOf()} - ${may2020} | ${12} | ${new Date('2021-05-15T00:00:00.000Z').valueOf()} - ${may2020} | ${-1} | ${new Date('2020-04-15T00:00:00.000Z').valueOf()} - ${may2020} | ${0} | ${may2020.valueOf()} - ${may2020} | ${0.9} | ${may2020.valueOf()} - `( - 'returns $numberOfMonths month(s) after the provided date', - ({ date, numberOfMonths, expectedResult }) => { - expect(datetimeUtility.nMonthsAfter(date, numberOfMonths)).toBe(expectedResult); - }, - ); -}); + describe('nWeeksAfter', () => { + const input = '2021-07-16T00:00:00.000Z'; + + it.each` + inputAsString | numberOfWeeks | options | expectedAsString + ${input} | ${1} | ${undefined} | ${'2021-07-23T00:00:00.000Z'} + ${input} | ${3} | ${undefined} | ${'2021-08-06T00:00:00.000Z'} + ${input} | ${-1} | ${undefined} | ${'2021-07-09T00:00:00.000Z'} + ${input} | ${0} | ${undefined} | ${'2021-07-16T00:00:00.000Z'} + ${input} | ${0.6} | ${undefined} | ${'2021-07-20T00:00:00.000Z'} + ${input} | ${18} | ${undefined} | ${'2021-11-19T01:00:00.000Z'} + ${input} | ${18} | ${{}} | ${'2021-11-19T01:00:00.000Z'} + ${input} | ${18} | ${{ utc: false }} | ${'2021-11-19T01:00:00.000Z'} + ${input} | ${18} | ${{ utc: true }} | ${'2021-11-19T00:00:00.000Z'} + `( + 'when the provided date is $inputAsString, numberOfWeeks is $numberOfWeeks, and the options parameter is $options, returns $expectedAsString', + ({ inputAsString, numberOfWeeks, options, expectedAsString }) => { + const inputDate = new Date(inputAsString); + const actual = datetimeUtility.nWeeksAfter(inputDate, numberOfWeeks, options); + + expect(actual.toISOString()).toBe(expectedAsString); + }, + ); + }); -describe('nMonthsBefore', () => { - // The previous month (February) has 28 days - const march2019 = new Date('2019-03-15T00:00:00.000Z'); - // Except in 2020, it had 29 days - const march2020 = new Date('2020-03-15T00:00:00.000Z'); - // The previous month (April) has 30 days - const may2020 = new Date('2020-05-15T00:00:00.000Z'); - // The previous month (May) has 31 days - const june2020 = new Date('2020-06-15T00:00:00.000Z'); + describe('nWeeksBefore', () => { + const input = '2021-07-16T00:00:00.000Z'; + + it.each` + inputAsString | numberOfWeeks | options | expectedAsString + ${input} | ${1} | ${undefined} | ${'2021-07-09T00:00:00.000Z'} + ${input} | ${3} | ${undefined} | ${'2021-06-25T00:00:00.000Z'} + ${input} | ${-1} | ${undefined} | ${'2021-07-23T00:00:00.000Z'} + ${input} | ${0} | ${undefined} | ${'2021-07-16T00:00:00.000Z'} + ${input} | ${0.6} | ${undefined} | ${'2021-07-11T00:00:00.000Z'} + ${input} | ${20} | ${undefined} | ${'2021-02-26T01:00:00.000Z'} + ${input} | ${20} | ${{}} | ${'2021-02-26T01:00:00.000Z'} + ${input} | ${20} | ${{ utc: false }} | ${'2021-02-26T01:00:00.000Z'} + ${input} | ${20} | ${{ utc: true }} | ${'2021-02-26T00:00:00.000Z'} + `( + 'when the provided date is $inputAsString, numberOfWeeks is $numberOfWeeks, and the options parameter is $options, returns $expectedAsString', + ({ inputAsString, numberOfWeeks, options, expectedAsString }) => { + const inputDate = new Date(inputAsString); + const actual = datetimeUtility.nWeeksBefore(inputDate, numberOfWeeks, options); + + expect(actual.toISOString()).toBe(expectedAsString); + }, + ); + }); - it.each` - date | numberOfMonths | expectedResult - ${march2019} | ${1} | ${new Date('2019-02-15T00:00:00.000Z').valueOf()} - ${march2020} | ${1} | ${new Date('2020-02-15T00:00:00.000Z').valueOf()} - ${may2020} | ${1} | ${new Date('2020-04-15T00:00:00.000Z').valueOf()} - ${june2020} | ${1} | ${new Date('2020-05-15T00:00:00.000Z').valueOf()} - ${june2020} | ${12} | ${new Date('2019-06-15T00:00:00.000Z').valueOf()} - ${june2020} | ${-1} | ${new Date('2020-07-15T00:00:00.000Z').valueOf()} - ${june2020} | ${0} | ${june2020.valueOf()} - ${june2020} | ${0.9} | ${new Date('2020-05-15T00:00:00.000Z').valueOf()} - `( - 'returns $numberOfMonths month(s) before the provided date', - ({ date, numberOfMonths, expectedResult }) => { - expect(datetimeUtility.nMonthsBefore(date, numberOfMonths)).toBe(expectedResult); - }, - ); + describe('nMonthsAfter', () => { + // February has 28 days + const feb2019 = '2019-02-15T00:00:00.000Z'; + // Except in 2020, it had 29 days + const feb2020 = '2020-02-15T00:00:00.000Z'; + // April has 30 days + const apr2020 = '2020-04-15T00:00:00.000Z'; + // May has 31 days + const may2020 = '2020-05-15T00:00:00.000Z'; + // November 1, 2020 was the day Daylight Saving Time ended in 2020 (in the US) + const oct2020 = '2020-10-15T00:00:00.000Z'; + + it.each` + inputAsString | numberOfMonths | options | expectedAsString + ${feb2019} | ${1} | ${undefined} | ${'2019-03-14T23:00:00.000Z'} + ${feb2020} | ${1} | ${undefined} | ${'2020-03-14T23:00:00.000Z'} + ${apr2020} | ${1} | ${undefined} | ${'2020-05-15T00:00:00.000Z'} + ${may2020} | ${1} | ${undefined} | ${'2020-06-15T00:00:00.000Z'} + ${may2020} | ${12} | ${undefined} | ${'2021-05-15T00:00:00.000Z'} + ${may2020} | ${-1} | ${undefined} | ${'2020-04-15T00:00:00.000Z'} + ${may2020} | ${0} | ${undefined} | ${may2020} + ${may2020} | ${0.9} | ${undefined} | ${may2020} + ${oct2020} | ${1} | ${undefined} | ${'2020-11-15T01:00:00.000Z'} + ${oct2020} | ${1} | ${{}} | ${'2020-11-15T01:00:00.000Z'} + ${oct2020} | ${1} | ${{ utc: false }} | ${'2020-11-15T01:00:00.000Z'} + ${oct2020} | ${1} | ${{ utc: true }} | ${'2020-11-15T00:00:00.000Z'} + `( + 'when the provided date is $inputAsString, numberOfMonths is $numberOfMonths, and the options parameter is $options, returns $expectedAsString', + ({ inputAsString, numberOfMonths, options, expectedAsString }) => { + const inputDate = new Date(inputAsString); + const actual = datetimeUtility.nMonthsAfter(inputDate, numberOfMonths, options); + + expect(actual.toISOString()).toBe(expectedAsString); + }, + ); + }); + + describe('nMonthsBefore', () => { + // The previous month (February) has 28 days + const march2019 = '2019-03-15T00:00:00.000Z'; + // Except in 2020, it had 29 days + const march2020 = '2020-03-15T00:00:00.000Z'; + // The previous month (April) has 30 days + const may2020 = '2020-05-15T00:00:00.000Z'; + // The previous month (May) has 31 days + const june2020 = '2020-06-15T00:00:00.000Z'; + // November 1, 2020 was the day Daylight Saving Time ended in 2020 (in the US) + const nov2020 = '2020-11-15T00:00:00.000Z'; + + it.each` + inputAsString | numberOfMonths | options | expectedAsString + ${march2019} | ${1} | ${undefined} | ${'2019-02-15T01:00:00.000Z'} + ${march2020} | ${1} | ${undefined} | ${'2020-02-15T01:00:00.000Z'} + ${may2020} | ${1} | ${undefined} | ${'2020-04-15T00:00:00.000Z'} + ${june2020} | ${1} | ${undefined} | ${'2020-05-15T00:00:00.000Z'} + ${june2020} | ${12} | ${undefined} | ${'2019-06-15T00:00:00.000Z'} + ${june2020} | ${-1} | ${undefined} | ${'2020-07-15T00:00:00.000Z'} + ${june2020} | ${0} | ${undefined} | ${june2020} + ${june2020} | ${0.9} | ${undefined} | ${'2020-05-15T00:00:00.000Z'} + ${nov2020} | ${1} | ${undefined} | ${'2020-10-14T23:00:00.000Z'} + ${nov2020} | ${1} | ${{}} | ${'2020-10-14T23:00:00.000Z'} + ${nov2020} | ${1} | ${{ utc: false }} | ${'2020-10-14T23:00:00.000Z'} + ${nov2020} | ${1} | ${{ utc: true }} | ${'2020-10-15T00:00:00.000Z'} + `( + 'when the provided date is $inputAsString, numberOfMonths is $numberOfMonths, and the options parameter is $options, returns $expectedAsString', + ({ inputAsString, numberOfMonths, options, expectedAsString }) => { + const inputDate = new Date(inputAsString); + const actual = datetimeUtility.nMonthsBefore(inputDate, numberOfMonths, options); + + expect(actual.toISOString()).toBe(expectedAsString); + }, + ); + }); }); describe('approximateDuration', () => { @@ -843,7 +951,7 @@ describe('format24HourTimeStringFromInt', () => { }); }); -describe('getOverlappingDaysInPeriods', () => { +describe('getOverlapDateInPeriods', () => { const start = new Date(2021, 0, 11); const end = new Date(2021, 0, 13); @@ -851,14 +959,15 @@ describe('getOverlappingDaysInPeriods', () => { const givenPeriodLeft = new Date(2021, 0, 11); const givenPeriodRight = new Date(2021, 0, 14); - it('returns an overlap object that contains the amount of days overlapping, start date of overlap and end date of overlap', () => { + it('returns an overlap object that contains the amount of days overlapping, the amount of hours overlapping, start date of overlap and end date of overlap', () => { expect( - datetimeUtility.getOverlappingDaysInPeriods( + datetimeUtility.getOverlapDateInPeriods( { start, end }, { start: givenPeriodLeft, end: givenPeriodRight }, ), ).toEqual({ daysOverlap: 2, + hoursOverlap: 48, overlapStartDate: givenPeriodLeft.getTime(), overlapEndDate: end.getTime(), }); @@ -871,7 +980,7 @@ describe('getOverlappingDaysInPeriods', () => { it('returns an overlap object that contains a 0 value for days overlapping', () => { expect( - datetimeUtility.getOverlappingDaysInPeriods( + datetimeUtility.getOverlapDateInPeriods( { start, end }, { start: givenPeriodLeft, end: givenPeriodRight }, ), @@ -886,14 +995,54 @@ describe('getOverlappingDaysInPeriods', () => { it('throws an exception when the left period contains an invalid date', () => { expect(() => - datetimeUtility.getOverlappingDaysInPeriods({ start, end }, { start: startInvalid, end }), + datetimeUtility.getOverlapDateInPeriods({ start, end }, { start: startInvalid, end }), ).toThrow(error); }); it('throws an exception when the right period contains an invalid date', () => { expect(() => - datetimeUtility.getOverlappingDaysInPeriods({ start, end }, { start, end: endInvalid }), + datetimeUtility.getOverlapDateInPeriods({ start, end }, { start, end: endInvalid }), ).toThrow(error); }); }); }); + +describe('isToday', () => { + const today = new Date(); + it.each` + date | expected | negation + ${today} | ${true} | ${'is'} + ${new Date('2021-01-21T12:00:00.000Z')} | ${false} | ${'is NOT'} + `('returns $expected as $date $negation today', ({ date, expected }) => { + expect(datetimeUtility.isToday(date)).toBe(expected); + }); +}); + +describe('getStartOfDay', () => { + beforeEach(() => { + timezoneMock.register('US/Eastern'); + }); + + afterEach(() => { + timezoneMock.unregister(); + }); + + it.each` + inputAsString | options | expectedAsString + ${'2021-01-29T18:08:23.014Z'} | ${undefined} | ${'2021-01-29T05:00:00.000Z'} + ${'2021-01-29T13:08:23.014-05:00'} | ${undefined} | ${'2021-01-29T05:00:00.000Z'} + ${'2021-01-30T03:08:23.014+09:00'} | ${undefined} | ${'2021-01-29T05:00:00.000Z'} + ${'2021-01-28T18:08:23.014-10:00'} | ${undefined} | ${'2021-01-28T05:00:00.000Z'} + ${'2021-01-28T18:08:23.014-10:00'} | ${{}} | ${'2021-01-28T05:00:00.000Z'} + ${'2021-01-28T18:08:23.014-10:00'} | ${{ utc: false }} | ${'2021-01-28T05:00:00.000Z'} + ${'2021-01-28T18:08:23.014-10:00'} | ${{ utc: true }} | ${'2021-01-29T00:00:00.000Z'} + `( + 'when the provided date is $inputAsString and the options parameter is $options, returns $expectedAsString', + ({ inputAsString, options, expectedAsString }) => { + const inputDate = new Date(inputAsString); + const actual = datetimeUtility.getStartOfDay(inputDate, options); + + expect(actual.toISOString()).toEqual(expectedAsString); + }, + ); +}); diff --git a/spec/frontend/lib/utils/poll_spec.js b/spec/frontend/lib/utils/poll_spec.js index f2ca5df3672..861808e3ad8 100644 --- a/spec/frontend/lib/utils/poll_spec.js +++ b/spec/frontend/lib/utils/poll_spec.js @@ -1,6 +1,6 @@ import waitForPromises from 'helpers/wait_for_promises'; -import Poll from '~/lib/utils/poll'; import { successCodes } from '~/lib/utils/http_status'; +import Poll from '~/lib/utils/poll'; describe('Poll', () => { let callbacks; diff --git a/spec/frontend/lib/utils/poll_until_complete_spec.js b/spec/frontend/lib/utils/poll_until_complete_spec.js index 38203c460e3..7509f954a84 100644 --- a/spec/frontend/lib/utils/poll_until_complete_spec.js +++ b/spec/frontend/lib/utils/poll_until_complete_spec.js @@ -1,8 +1,8 @@ import AxiosMockAdapter from 'axios-mock-adapter'; import { TEST_HOST } from 'helpers/test_constants'; import axios from '~/lib/utils/axios_utils'; -import pollUntilComplete from '~/lib/utils/poll_until_complete'; import httpStatusCodes from '~/lib/utils/http_status'; +import pollUntilComplete from '~/lib/utils/poll_until_complete'; const endpoint = `${TEST_HOST}/foo`; const mockData = 'mockData'; diff --git a/spec/frontend/lib/utils/unit_format/formatter_factory_spec.js b/spec/frontend/lib/utils/unit_format/formatter_factory_spec.js index 26b942c3567..0ca70e0a77e 100644 --- a/spec/frontend/lib/utils/unit_format/formatter_factory_spec.js +++ b/spec/frontend/lib/utils/unit_format/formatter_factory_spec.js @@ -36,6 +36,27 @@ describe('unit_format/formatter_factory', () => { expect(formatNumber(10 ** 7, undefined, 9)).toBe('1.00e+7'); expect(formatNumber(10 ** 7, undefined, 10)).toBe('10,000,000'); }); + + describe('formats with a different locale', () => { + let originalLang; + + beforeAll(() => { + originalLang = document.documentElement.lang; + document.documentElement.lang = 'es'; + }); + + afterAll(() => { + document.documentElement.lang = originalLang; + }); + + it('formats a using the correct thousands separator', () => { + expect(formatNumber(1000000)).toBe('1.000.000'); + }); + + it('formats a using the correct decimal separator', () => { + expect(formatNumber(12.345)).toBe('12,345'); + }); + }); }); describe('suffixFormatter', () => { diff --git a/spec/frontend/lib/utils/url_utility_spec.js b/spec/frontend/lib/utils/url_utility_spec.js index 5846acbdb79..b60ddea81ee 100644 --- a/spec/frontend/lib/utils/url_utility_spec.js +++ b/spec/frontend/lib/utils/url_utility_spec.js @@ -492,6 +492,28 @@ describe('URL utility', () => { }); }); + describe('isExternal', () => { + const gitlabUrl = 'https://gitlab.com/'; + + beforeEach(() => { + gon.gitlab_url = gitlabUrl; + }); + + afterEach(() => { + gon.gitlab_url = ''; + }); + + it.each` + url | urlType | external + ${'/gitlab-org/gitlab-test/-/issues/2'} | ${'relative'} | ${false} + ${gitlabUrl} | ${'absolute and internal'} | ${false} + ${`${gitlabUrl}/gitlab-org/gitlab-test`} | ${'absolute and internal'} | ${false} + ${'http://jira.atlassian.net/browse/IG-1'} | ${'absolute and external'} | ${true} + `('returns $external for $url ($urlType)', ({ url, external }) => { + expect(urlUtils.isExternal(url)).toBe(external); + }); + }); + describe('isBase64DataUrl', () => { it.each` url | valid @@ -858,4 +880,37 @@ describe('URL utility', () => { expect(urlUtils.getURLOrigin(url)).toBe(expectation); }); }); + + describe('encodeSaferUrl', () => { + it.each` + character | input | output + ${' '} | ${'/url/hello 1.jpg'} | ${'/url/hello%201.jpg'} + ${'#'} | ${'/url/hello#1.jpg'} | ${'/url/hello%231.jpg'} + ${'!'} | ${'/url/hello!.jpg'} | ${'/url/hello%21.jpg'} + ${'~'} | ${'/url/hello~.jpg'} | ${'/url/hello%7E.jpg'} + ${'*'} | ${'/url/hello*.jpg'} | ${'/url/hello%2A.jpg'} + ${"'"} | ${"/url/hello'.jpg"} | ${'/url/hello%27.jpg'} + ${'('} | ${'/url/hello(.jpg'} | ${'/url/hello%28.jpg'} + ${')'} | ${'/url/hello).jpg'} | ${'/url/hello%29.jpg'} + ${'?'} | ${'/url/hello?.jpg'} | ${'/url/hello%3F.jpg'} + ${'='} | ${'/url/hello=.jpg'} | ${'/url/hello%3D.jpg'} + ${'+'} | ${'/url/hello+.jpg'} | ${'/url/hello%2B.jpg'} + ${'&'} | ${'/url/hello&.jpg'} | ${'/url/hello%26.jpg'} + `( + 'properly escapes `$character` characters while retaining the integrity of the URL', + ({ input, output }) => { + expect(urlUtils.encodeSaferUrl(input)).toBe(output); + }, + ); + + it.each` + character | input + ${'/, .'} | ${'/url/hello.png'} + ${'\\d'} | ${'/url/hello123.png'} + ${'-'} | ${'/url/hello-123.png'} + ${'_'} | ${'/url/hello_123.png'} + `('makes no changes to unproblematic characters ($character)', ({ input }) => { + expect(urlUtils.encodeSaferUrl(input)).toBe(input); + }); + }); }); |