diff options
author | Robert Speicher <rspeicher@gmail.com> | 2021-01-20 13:34:23 -0600 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2021-01-20 13:34:23 -0600 |
commit | 6438df3a1e0fb944485cebf07976160184697d72 (patch) | |
tree | 00b09bfd170e77ae9391b1a2f5a93ef6839f2597 /spec/frontend/lib | |
parent | 42bcd54d971da7ef2854b896a7b34f4ef8601067 (diff) | |
download | gitlab-ce-6438df3a1e0fb944485cebf07976160184697d72.tar.gz |
Add latest changes from gitlab-org/gitlab@13-8-stable-eev13.8.0-rc42
Diffstat (limited to 'spec/frontend/lib')
19 files changed, 448 insertions, 182 deletions
diff --git a/spec/frontend/lib/dompurify_spec.js b/spec/frontend/lib/dompurify_spec.js index ee1971a4931..a01f86678e9 100644 --- a/spec/frontend/lib/dompurify_spec.js +++ b/spec/frontend/lib/dompurify_spec.js @@ -15,8 +15,8 @@ const absoluteGon = { const expectedSanitized = '<svg><use></use></svg>'; const safeUrls = { - root: Object.values(rootGon).map(url => `${url}#ellipsis_h`), - absolute: Object.values(absoluteGon).map(url => `${url}#ellipsis_h`), + root: Object.values(rootGon).map((url) => `${url}#ellipsis_h`), + absolute: Object.values(absoluteGon).map((url) => `${url}#ellipsis_h`), }; const unsafeUrls = [ @@ -60,7 +60,7 @@ describe('~/lib/dompurify', () => { expect(sanitize(htmlHref)).toBe(htmlHref); }); - it.each(safeUrls[type])('allows safe URL %s', url => { + it.each(safeUrls[type])('allows safe URL %s', (url) => { const htmlHref = `<svg><use href="${url}"></use></svg>`; expect(sanitize(htmlHref)).toBe(htmlHref); @@ -68,7 +68,7 @@ describe('~/lib/dompurify', () => { expect(sanitize(htmlXlink)).toBe(htmlXlink); }); - it.each(unsafeUrls)('sanitizes unsafe URL %s', url => { + it.each(unsafeUrls)('sanitizes unsafe URL %s', (url) => { const htmlHref = `<svg><use href="${url}"></use></svg>`; const htmlXlink = `<svg><use xlink:href="${url}"></use></svg>`; @@ -87,7 +87,7 @@ describe('~/lib/dompurify', () => { window.gon = originalGon; }); - it.each([...safeUrls.root, ...safeUrls.absolute, ...unsafeUrls])('sanitizes URL %s', url => { + it.each([...safeUrls.root, ...safeUrls.absolute, ...unsafeUrls])('sanitizes URL %s', (url) => { const htmlHref = `<svg><use href="${url}"></use></svg>`; const htmlXlink = `<svg><use xlink:href="${url}"></use></svg>`; diff --git a/spec/frontend/lib/utils/ajax_cache_spec.js b/spec/frontend/lib/utils/ajax_cache_spec.js index e2ee70b9d69..641dd3684fa 100644 --- a/spec/frontend/lib/utils/ajax_cache_spec.js +++ b/spec/frontend/lib/utils/ajax_cache_spec.js @@ -104,7 +104,7 @@ describe('AjaxCache', () => { it('stores and returns data from Ajax call if cache is empty', () => { mock.onGet(dummyEndpoint).reply(200, dummyResponse); - return AjaxCache.retrieve(dummyEndpoint).then(data => { + return AjaxCache.retrieve(dummyEndpoint).then((data) => { expect(data).toEqual(dummyResponse); expect(AjaxCache.internalStorage[dummyEndpoint]).toEqual(dummyResponse); }); @@ -126,7 +126,7 @@ describe('AjaxCache', () => { mock.onGet(dummyEndpoint).networkError(); expect.assertions(2); - return AjaxCache.retrieve(dummyEndpoint).catch(error => { + return AjaxCache.retrieve(dummyEndpoint).catch((error) => { expect(error.message).toBe(`${dummyEndpoint}: ${errorMessage}`); expect(error.textStatus).toBe(errorMessage); }); @@ -135,7 +135,7 @@ describe('AjaxCache', () => { it('makes no Ajax call if matching data exists', () => { AjaxCache.internalStorage[dummyEndpoint] = dummyResponse; - return AjaxCache.retrieve(dummyEndpoint).then(data => { + return AjaxCache.retrieve(dummyEndpoint).then((data) => { expect(data).toBe(dummyResponse); expect(axios.get).not.toHaveBeenCalled(); }); @@ -153,7 +153,7 @@ describe('AjaxCache', () => { return Promise.all([ AjaxCache.retrieve(dummyEndpoint), AjaxCache.retrieve(dummyEndpoint, true), - ]).then(data => { + ]).then((data) => { expect(data).toEqual([oldDummyResponse, dummyResponse]); }); }); diff --git a/spec/frontend/lib/utils/apollo_startup_js_link_spec.js b/spec/frontend/lib/utils/apollo_startup_js_link_spec.js index faead3ff8fe..c0e5b06651f 100644 --- a/spec/frontend/lib/utils/apollo_startup_js_link_spec.js +++ b/spec/frontend/lib/utils/apollo_startup_js_link_spec.js @@ -58,9 +58,9 @@ describe('StartupJSLink', () => { link = ApolloLink.from([startupLink, new ApolloLink(() => Observable.of(FORWARDED_RESPONSE))]); }; - it('forwards requests if no calls are set up', done => { + it('forwards requests if no calls are set up', (done) => { setupLink(); - link.request(mockOperation()).subscribe(result => { + link.request(mockOperation()).subscribe((result) => { expect(result).toEqual(FORWARDED_RESPONSE); expect(startupLink.startupCalls).toBe(null); expect(startupLink.request).toEqual(StartupJSLink.noopRequest); @@ -68,7 +68,7 @@ describe('StartupJSLink', () => { }); }); - it('forwards requests if the operation is not pre-loaded', done => { + it('forwards requests if the operation is not pre-loaded', (done) => { window.gl = { startup_graphql_calls: [ { @@ -79,7 +79,7 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation({ operationName: 'notLoaded' })).subscribe(result => { + link.request(mockOperation({ operationName: 'notLoaded' })).subscribe((result) => { expect(result).toEqual(FORWARDED_RESPONSE); expect(startupLink.startupCalls.size).toBe(1); done(); @@ -87,7 +87,7 @@ describe('StartupJSLink', () => { }); describe('variable match errors: ', () => { - it('forwards requests if the variables are not matching', done => { + it('forwards requests if the variables are not matching', (done) => { window.gl = { startup_graphql_calls: [ { @@ -98,14 +98,14 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation()).subscribe(result => { + link.request(mockOperation()).subscribe((result) => { expect(result).toEqual(FORWARDED_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); }); }); - it('forwards requests if more variables are set in the operation', done => { + it('forwards requests if more variables are set in the operation', (done) => { window.gl = { startup_graphql_calls: [ { @@ -115,14 +115,14 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation()).subscribe(result => { + link.request(mockOperation()).subscribe((result) => { expect(result).toEqual(FORWARDED_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); }); }); - it('forwards requests if less variables are set in the operation', done => { + it('forwards requests if less variables are set in the operation', (done) => { window.gl = { startup_graphql_calls: [ { @@ -133,14 +133,14 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation({ variables: { id: 3 } })).subscribe(result => { + link.request(mockOperation({ variables: { id: 3 } })).subscribe((result) => { expect(result).toEqual(FORWARDED_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); }); }); - it('forwards requests if different variables are set', done => { + it('forwards requests if different variables are set', (done) => { window.gl = { startup_graphql_calls: [ { @@ -151,14 +151,14 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation({ variables: { id: 3 } })).subscribe(result => { + link.request(mockOperation({ variables: { id: 3 } })).subscribe((result) => { expect(result).toEqual(FORWARDED_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); }); }); - it('forwards requests if array variables have a different order', done => { + it('forwards requests if array variables have a different order', (done) => { window.gl = { startup_graphql_calls: [ { @@ -169,7 +169,7 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation({ variables: { id: [4, 3] } })).subscribe(result => { + link.request(mockOperation({ variables: { id: [4, 3] } })).subscribe((result) => { expect(result).toEqual(FORWARDED_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); @@ -178,7 +178,7 @@ describe('StartupJSLink', () => { }); describe('error handling', () => { - it('forwards the call if the fetchCall is failing with a HTTP Error', done => { + it('forwards the call if the fetchCall is failing with a HTTP Error', (done) => { window.gl = { startup_graphql_calls: [ { @@ -189,14 +189,14 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation()).subscribe(result => { + link.request(mockOperation()).subscribe((result) => { expect(result).toEqual(FORWARDED_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); }); }); - it('forwards the call if it errors (e.g. failing JSON)', done => { + it('forwards the call if it errors (e.g. failing JSON)', (done) => { window.gl = { startup_graphql_calls: [ { @@ -207,14 +207,14 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation()).subscribe(result => { + link.request(mockOperation()).subscribe((result) => { expect(result).toEqual(FORWARDED_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); }); }); - it('forwards the call if the response contains an error', done => { + it('forwards the call if the response contains an error', (done) => { window.gl = { startup_graphql_calls: [ { @@ -225,14 +225,14 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation()).subscribe(result => { + link.request(mockOperation()).subscribe((result) => { expect(result).toEqual(FORWARDED_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); }); }); - it("forwards the call if the response doesn't contain a data object", done => { + it("forwards the call if the response doesn't contain a data object", (done) => { window.gl = { startup_graphql_calls: [ { @@ -243,7 +243,7 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation()).subscribe(result => { + link.request(mockOperation()).subscribe((result) => { expect(result).toEqual(FORWARDED_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); @@ -251,7 +251,7 @@ describe('StartupJSLink', () => { }); }); - it('resolves the request if the operation is matching', done => { + it('resolves the request if the operation is matching', (done) => { window.gl = { startup_graphql_calls: [ { @@ -262,14 +262,14 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation()).subscribe(result => { + link.request(mockOperation()).subscribe((result) => { expect(result).toEqual(STARTUP_JS_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); }); }); - it('resolves the request exactly once', done => { + it('resolves the request exactly once', (done) => { window.gl = { startup_graphql_calls: [ { @@ -280,17 +280,17 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation()).subscribe(result => { + link.request(mockOperation()).subscribe((result) => { expect(result).toEqual(STARTUP_JS_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); - link.request(mockOperation()).subscribe(result2 => { + link.request(mockOperation()).subscribe((result2) => { expect(result2).toEqual(FORWARDED_RESPONSE); done(); }); }); }); - it('resolves the request if the variables have a different order', done => { + it('resolves the request if the variables have a different order', (done) => { window.gl = { startup_graphql_calls: [ { @@ -301,14 +301,14 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation({ variables: { name: 'foo', id: 3 } })).subscribe(result => { + link.request(mockOperation({ variables: { name: 'foo', id: 3 } })).subscribe((result) => { expect(result).toEqual(STARTUP_JS_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); }); }); - it('resolves the request if the variables have undefined values', done => { + it('resolves the request if the variables have undefined values', (done) => { window.gl = { startup_graphql_calls: [ { @@ -321,14 +321,14 @@ describe('StartupJSLink', () => { setupLink(); link .request(mockOperation({ variables: { name: 'foo', undef: undefined } })) - .subscribe(result => { + .subscribe((result) => { expect(result).toEqual(STARTUP_JS_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); }); }); - it('resolves the request if the variables are of an array format', done => { + it('resolves the request if the variables are of an array format', (done) => { window.gl = { startup_graphql_calls: [ { @@ -339,14 +339,14 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation({ variables: { id: [3, 4] } })).subscribe(result => { + link.request(mockOperation({ variables: { id: [3, 4] } })).subscribe((result) => { expect(result).toEqual(STARTUP_JS_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); }); }); - it('resolves multiple requests correctly', done => { + it('resolves multiple requests correctly', (done) => { window.gl = { startup_graphql_calls: [ { @@ -362,10 +362,10 @@ describe('StartupJSLink', () => { ], }; setupLink(); - link.request(mockOperation({ operationName: OPERATION_NAME_TWO })).subscribe(result => { + link.request(mockOperation({ operationName: OPERATION_NAME_TWO })).subscribe((result) => { expect(result).toEqual(STARTUP_JS_RESPONSE_TWO); expect(startupLink.startupCalls.size).toBe(1); - link.request(mockOperation({ operationName: OPERATION_NAME })).subscribe(result2 => { + link.request(mockOperation({ operationName: OPERATION_NAME })).subscribe((result2) => { expect(result2).toEqual(STARTUP_JS_RESPONSE); expect(startupLink.startupCalls.size).toBe(0); done(); diff --git a/spec/frontend/lib/utils/chart_utils_spec.js b/spec/frontend/lib/utils/chart_utils_spec.js index e811b8405fb..65bb68c5017 100644 --- a/spec/frontend/lib/utils/chart_utils_spec.js +++ b/spec/frontend/lib/utils/chart_utils_spec.js @@ -3,7 +3,11 @@ import { firstAndLastY } from '~/lib/utils/chart_utils'; describe('Chart utils', () => { describe('firstAndLastY', () => { it('returns the first and last y-values of a given data set as an array', () => { - const data = [['', 1], ['', 2], ['', 3]]; + const data = [ + ['', 1], + ['', 2], + ['', 3], + ]; expect(firstAndLastY(data)).toEqual([1, 3]); }); diff --git a/spec/frontend/lib/utils/common_utils_spec.js b/spec/frontend/lib/utils/common_utils_spec.js index 433fb368f55..90222f0f718 100644 --- a/spec/frontend/lib/utils/common_utils_spec.js +++ b/spec/frontend/lib/utils/common_utils_spec.js @@ -1,4 +1,3 @@ -import $ from 'jquery'; import * as commonUtils from '~/lib/utils/common_utils'; describe('common_utils', () => { @@ -214,60 +213,90 @@ describe('common_utils', () => { describe('scrollToElement*', () => { let elem; - const windowHeight = 1000; + const windowHeight = 550; const elemTop = 100; + const id = 'scroll_test'; beforeEach(() => { elem = document.createElement('div'); + elem.id = id; + document.body.appendChild(elem); window.innerHeight = windowHeight; window.mrTabs = { currentAction: 'show' }; - jest.spyOn($.fn, 'animate'); - jest.spyOn($.fn, 'offset').mockReturnValue({ top: elemTop }); + jest.spyOn(window, 'scrollTo').mockImplementation(() => {}); + jest.spyOn(Element.prototype, 'getBoundingClientRect').mockReturnValue({ top: elemTop }); }); afterEach(() => { - $.fn.animate.mockRestore(); - $.fn.offset.mockRestore(); + window.scrollTo.mockRestore(); + Element.prototype.getBoundingClientRect.mockRestore(); + elem.remove(); }); - describe('scrollToElement', () => { + describe('scrollToElement with HTMLElement', () => { it('scrolls to element', () => { commonUtils.scrollToElement(elem); - expect($.fn.animate).toHaveBeenCalledWith( - { - scrollTop: elemTop, - }, - expect.any(Number), - ); + expect(window.scrollTo).toHaveBeenCalledWith({ + behavior: 'smooth', + top: elemTop, + }); }); it('scrolls to element with offset', () => { const offset = 50; commonUtils.scrollToElement(elem, { offset }); - expect($.fn.animate).toHaveBeenCalledWith( - { - scrollTop: elemTop + offset, - }, - expect.any(Number), - ); + expect(window.scrollTo).toHaveBeenCalledWith({ + behavior: 'smooth', + top: elemTop + offset, + }); + }); + }); + + describe('scrollToElement with Selector', () => { + it('scrolls to element', () => { + commonUtils.scrollToElement(`#${id}`); + expect(window.scrollTo).toHaveBeenCalledWith({ + behavior: 'smooth', + top: elemTop, + }); + }); + + it('scrolls to element with offset', () => { + const offset = 50; + commonUtils.scrollToElement(`#${id}`, { offset }); + expect(window.scrollTo).toHaveBeenCalledWith({ + behavior: 'smooth', + top: elemTop + offset, + }); }); }); describe('scrollToElementWithContext', () => { - it('scrolls with context', () => { - commonUtils.scrollToElementWithContext(); - expect($.fn.animate).toHaveBeenCalledWith( - { - scrollTop: elemTop - windowHeight * 0.1, - }, - expect.any(Number), - ); + // This is what the implementation of scrollToElementWithContext + // scrolls to, in case we change tha implementation + // it needs to be adjusted + const elementTopWithContext = elemTop - windowHeight * 0.1; + + it('with HTMLElement scrolls with context', () => { + commonUtils.scrollToElementWithContext(elem); + expect(window.scrollTo).toHaveBeenCalledWith({ + behavior: 'smooth', + top: elementTopWithContext, + }); + }); + + it('with Selector scrolls with context', () => { + commonUtils.scrollToElementWithContext(`#${id}`); + expect(window.scrollTo).toHaveBeenCalledWith({ + behavior: 'smooth', + top: elementTopWithContext, + }); }); }); }); describe('debounceByAnimationFrame', () => { - it('debounces a function to allow a maximum of one call per animation frame', done => { + it('debounces a function to allow a maximum of one call per animation frame', (done) => { const spy = jest.fn(); const debouncedSpy = commonUtils.debounceByAnimationFrame(spy); window.requestAnimationFrame(() => { @@ -404,54 +433,54 @@ describe('common_utils', () => { describe('backOff', () => { beforeEach(() => { // shortcut our timeouts otherwise these tests will take a long time to finish - jest.spyOn(window, 'setTimeout').mockImplementation(cb => setImmediate(cb, 0)); + jest.spyOn(window, 'setTimeout').mockImplementation((cb) => setImmediate(cb, 0)); }); - it('solves the promise from the callback', done => { + it('solves the promise from the callback', (done) => { const expectedResponseValue = 'Success!'; commonUtils .backOff((next, stop) => - new Promise(resolve => { + new Promise((resolve) => { resolve(expectedResponseValue); }) - .then(resp => { + .then((resp) => { stop(resp); }) .catch(done.fail), ) - .then(respBackoff => { + .then((respBackoff) => { expect(respBackoff).toBe(expectedResponseValue); done(); }) .catch(done.fail); }); - it('catches the rejected promise from the callback ', done => { + it('catches the rejected promise from the callback ', (done) => { const errorMessage = 'Mistakes were made!'; commonUtils .backOff((next, stop) => { new Promise((resolve, reject) => { reject(new Error(errorMessage)); }) - .then(resp => { + .then((resp) => { stop(resp); }) - .catch(err => stop(err)); + .catch((err) => stop(err)); }) - .catch(errBackoffResp => { + .catch((errBackoffResp) => { expect(errBackoffResp instanceof Error).toBe(true); expect(errBackoffResp.message).toBe(errorMessage); done(); }); }); - it('solves the promise correctly after retrying a third time', done => { + it('solves the promise correctly after retrying a third time', (done) => { let numberOfCalls = 1; const expectedResponseValue = 'Success!'; commonUtils .backOff((next, stop) => Promise.resolve(expectedResponseValue) - .then(resp => { + .then((resp) => { if (numberOfCalls < 3) { numberOfCalls += 1; next(); @@ -461,7 +490,7 @@ describe('common_utils', () => { }) .catch(done.fail), ) - .then(respBackoff => { + .then((respBackoff) => { const timeouts = window.setTimeout.mock.calls.map(([, timeout]) => timeout); expect(timeouts).toEqual([2000, 4000]); @@ -471,10 +500,10 @@ describe('common_utils', () => { .catch(done.fail); }); - it('rejects the backOff promise after timing out', done => { + it('rejects the backOff promise after timing out', (done) => { commonUtils - .backOff(next => next(), 64000) - .catch(errBackoffResp => { + .backOff((next) => next(), 64000) + .catch((errBackoffResp) => { const timeouts = window.setTimeout.mock.calls.map(([, timeout]) => timeout); expect(timeouts).toEqual([2000, 4000, 8000, 16000, 32000, 32000]); @@ -485,27 +514,6 @@ describe('common_utils', () => { }); }); - describe('resetFavicon', () => { - beforeEach(() => { - const favicon = document.createElement('link'); - favicon.setAttribute('id', 'favicon'); - favicon.setAttribute('data-original-href', 'default/favicon'); - document.body.appendChild(favicon); - }); - - afterEach(() => { - document.body.removeChild(document.getElementById('favicon')); - }); - - it('should reset page favicon to the default icon', () => { - const favicon = document.getElementById('favicon'); - favicon.setAttribute('href', 'new/favicon'); - commonUtils.resetFavicon(); - - expect(document.getElementById('favicon').getAttribute('href')).toEqual('default/favicon'); - }); - }); - describe('spriteIcon', () => { let beforeGon; @@ -533,8 +541,8 @@ describe('common_utils', () => { }); describe('convertObjectProps*', () => { - const mockConversionFunction = prop => `${prop}_converted`; - const isEmptyObject = obj => + const mockConversionFunction = (prop) => `${prop}_converted`; + const isEmptyObject = (obj) => typeof obj === 'object' && obj !== null && Object.keys(obj).length === 0; const mockObjects = { diff --git a/spec/frontend/lib/utils/datetime_range_spec.js b/spec/frontend/lib/utils/datetime_range_spec.js index 8b1f284615d..996a8e2e47b 100644 --- a/spec/frontend/lib/utils/datetime_range_spec.js +++ b/spec/frontend/lib/utils/datetime_range_spec.js @@ -64,7 +64,7 @@ describe('Date time range utils', () => { }; Object.entries(rangeTypes).forEach(([type, examples]) => { - examples.forEach(example => expect(getRangeType(example)).toEqual(type)); + examples.forEach((example) => expect(getRangeType(example)).toEqual(type)); }); }); }); diff --git a/spec/frontend/lib/utils/datetime_utility_spec.js b/spec/frontend/lib/utils/datetime_utility_spec.js index 6092b44720f..66efd43262b 100644 --- a/spec/frontend/lib/utils/datetime_utility_spec.js +++ b/spec/frontend/lib/utils/datetime_utility_spec.js @@ -566,7 +566,7 @@ describe('getDatesInRange', () => { it('applies mapper function if provided fro each item in range', () => { const d1 = new Date('2019-01-01'); const d2 = new Date('2019-01-31'); - const formatter = date => date.getDate(); + const formatter = (date) => date.getDate(); const range = datetimeUtility.getDatesInRange(d1, d2, formatter); @@ -608,6 +608,92 @@ describe('secondsToDays', () => { }); }); +describe('nDaysAfter', () => { + const date = new Date('2019-07-16T00:00:00.000Z'); + + 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); + }); +}); + +describe('nDaysBefore', () => { + const date = new Date('2019-07-16T00:00:00.000Z'); + + 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('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'); + + 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('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'); + + 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('approximateDuration', () => { it.each` seconds @@ -731,3 +817,83 @@ describe('datesMatch', () => { expect(datetimeUtility.datesMatch(date1, date2)).toBe(expected); }); }); + +describe('format24HourTimeStringFromInt', () => { + const expectedFormattedTimes = [ + [0, '00:00'], + [2, '02:00'], + [6, '06:00'], + [9, '09:00'], + [10, '10:00'], + [16, '16:00'], + [22, '22:00'], + [32, ''], + [NaN, ''], + ['Invalid Int', ''], + [null, ''], + [undefined, ''], + ]; + + expectedFormattedTimes.forEach(([timeInt, expectedTimeStringIn24HourNotation]) => { + it(`formats ${timeInt} as ${expectedTimeStringIn24HourNotation}`, () => { + expect(datetimeUtility.format24HourTimeStringFromInt(timeInt)).toBe( + expectedTimeStringIn24HourNotation, + ); + }); + }); +}); + +describe('getOverlappingDaysInPeriods', () => { + const start = new Date(2021, 0, 11); + const end = new Date(2021, 0, 13); + + describe('when date periods overlap', () => { + 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', () => { + expect( + datetimeUtility.getOverlappingDaysInPeriods( + { start, end }, + { start: givenPeriodLeft, end: givenPeriodRight }, + ), + ).toEqual({ + daysOverlap: 2, + overlapStartDate: givenPeriodLeft.getTime(), + overlapEndDate: end.getTime(), + }); + }); + }); + + describe('when date periods do not overlap', () => { + const givenPeriodLeft = new Date(2021, 0, 9); + const givenPeriodRight = new Date(2021, 0, 10); + + it('returns an overlap object that contains a 0 value for days overlapping', () => { + expect( + datetimeUtility.getOverlappingDaysInPeriods( + { start, end }, + { start: givenPeriodLeft, end: givenPeriodRight }, + ), + ).toEqual({ daysOverlap: 0 }); + }); + }); + + describe('when date periods contain an invalid Date', () => { + const startInvalid = new Date(NaN); + const endInvalid = new Date(NaN); + const error = __('Invalid period'); + + it('throws an exception when the left period contains an invalid date', () => { + expect(() => + datetimeUtility.getOverlappingDaysInPeriods({ 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 }), + ).toThrow(error); + }); + }); +}); diff --git a/spec/frontend/lib/utils/dom_utils_spec.js b/spec/frontend/lib/utils/dom_utils_spec.js index f5c2a797df5..7c4c20e651f 100644 --- a/spec/frontend/lib/utils/dom_utils_spec.js +++ b/spec/frontend/lib/utils/dom_utils_spec.js @@ -45,7 +45,7 @@ describe('DOM Utils', () => { }); describe('canScrollUp', () => { - [1, 100].forEach(scrollTop => { + [1, 100].forEach((scrollTop) => { it(`is true if scrollTop is > 0 (${scrollTop})`, () => { expect( canScrollUp({ @@ -55,7 +55,7 @@ describe('DOM Utils', () => { }); }); - [0, -10].forEach(scrollTop => { + [0, -10].forEach((scrollTop) => { it(`is false if scrollTop is <= 0 (${scrollTop})`, () => { expect( canScrollUp({ diff --git a/spec/frontend/lib/utils/favicon_ci_spec.js b/spec/frontend/lib/utils/favicon_ci_spec.js new file mode 100644 index 00000000000..e35b008b862 --- /dev/null +++ b/spec/frontend/lib/utils/favicon_ci_spec.js @@ -0,0 +1,50 @@ +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import { setFaviconOverlay, resetFavicon } from '~/lib/utils/favicon'; +import { setCiStatusFavicon } from '~/lib/utils/favicon_ci'; + +jest.mock('~/lib/utils/favicon'); + +const TEST_URL = '/test/pipelinable/1'; +const TEST_FAVICON = '/favicon.test.ico'; + +describe('~/lib/utils/favicon_ci', () => { + let mock; + + beforeEach(() => { + mock = new MockAdapter(axios); + }); + + afterEach(() => { + mock.restore(); + mock = null; + }); + + describe('setCiStatusFavicon', () => { + it.each` + response | setFaviconOverlayCalls | resetFaviconCalls + ${{}} | ${[]} | ${[[]]} + ${{ favicon: TEST_FAVICON }} | ${[[TEST_FAVICON]]} | ${[]} + `( + 'with response=$response', + async ({ response, setFaviconOverlayCalls, resetFaviconCalls }) => { + mock.onGet(TEST_URL).replyOnce(200, response); + + expect(setFaviconOverlay).not.toHaveBeenCalled(); + expect(resetFavicon).not.toHaveBeenCalled(); + + await setCiStatusFavicon(TEST_URL); + + expect(setFaviconOverlay.mock.calls).toEqual(setFaviconOverlayCalls); + expect(resetFavicon.mock.calls).toEqual(resetFaviconCalls); + }, + ); + + it('with error', async () => { + mock.onGet(TEST_URL).replyOnce(500); + + await expect(setCiStatusFavicon(TEST_URL)).rejects.toEqual(expect.any(Error)); + expect(resetFavicon).toHaveBeenCalled(); + }); + }); +}); diff --git a/spec/frontend/lib/utils/favicon_spec.js b/spec/frontend/lib/utils/favicon_spec.js new file mode 100644 index 00000000000..1b986432b8a --- /dev/null +++ b/spec/frontend/lib/utils/favicon_spec.js @@ -0,0 +1,39 @@ +import { FaviconOverlayManager } from '@gitlab/favicon-overlay'; +import * as faviconUtils from '~/lib/utils/favicon'; + +jest.mock('@gitlab/favicon-overlay'); + +describe('~/lib/utils/favicon', () => { + afterEach(() => { + faviconUtils.clearMemoizeCache(); + }); + + describe.each` + fnName | managerFn | args + ${'setFaviconOverlay'} | ${FaviconOverlayManager.setFaviconOverlay} | ${['test']} + ${'resetFavicon'} | ${FaviconOverlayManager.resetFaviconOverlay} | ${[]} + `('$fnName', ({ fnName, managerFn, args }) => { + const call = () => faviconUtils[fnName](...args); + + it('initializes only once when called', async () => { + expect(FaviconOverlayManager.initialize).not.toHaveBeenCalled(); + + // Call twice so we can make sure initialize is only called once + await call(); + await call(); + + expect(FaviconOverlayManager.initialize).toHaveBeenCalledWith({ + faviconSelector: '#favicon', + }); + expect(FaviconOverlayManager.initialize).toHaveBeenCalledTimes(1); + }); + + it('passes call to manager', async () => { + expect(managerFn).not.toHaveBeenCalled(); + + await call(); + + expect(managerFn).toHaveBeenCalledWith(...args); + }); + }); +}); diff --git a/spec/frontend/lib/utils/forms_spec.js b/spec/frontend/lib/utils/forms_spec.js index a69be99ab98..f65bd8ffe0c 100644 --- a/spec/frontend/lib/utils/forms_spec.js +++ b/spec/frontend/lib/utils/forms_spec.js @@ -1,7 +1,7 @@ import { serializeForm, serializeFormObject, isEmptyValue } from '~/lib/utils/forms'; describe('lib/utils/forms', () => { - const createDummyForm = inputs => { + const createDummyForm = (inputs) => { const form = document.createElement('form'); form.innerHTML = inputs @@ -9,7 +9,7 @@ describe('lib/utils/forms', () => { let str = ``; if (type === 'select') { str = `<select name="${name}">`; - value.forEach(v => { + value.forEach((v) => { if (v.length > 0) { str += `<option value="${v}"></option> `; } @@ -81,8 +81,8 @@ describe('lib/utils/forms', () => { jest .spyOn(FormData.prototype, 'getAll') - .mockImplementation(name => - formData.map(elem => (elem.name === name ? elem.value : undefined)), + .mockImplementation((name) => + formData.map((elem) => (elem.name === name ? elem.value : undefined)), ); const data = serializeForm(form); diff --git a/spec/frontend/lib/utils/highlight_spec.js b/spec/frontend/lib/utils/highlight_spec.js index 638bbf65ae9..f34e203f9a4 100644 --- a/spec/frontend/lib/utils/highlight_spec.js +++ b/spec/frontend/lib/utils/highlight_spec.js @@ -8,13 +8,13 @@ describe('highlight', () => { }); it(`should return an empty string in the case of invalid inputs`, () => { - [null, undefined].forEach(input => { + [null, undefined].forEach((input) => { expect(highlight(input, 'match')).toBe(''); }); }); it(`should return the original value if match is null, undefined, or ''`, () => { - [null, undefined].forEach(match => { + [null, undefined].forEach((match) => { expect(highlight('gitlab', match)).toBe('gitlab'); }); }); diff --git a/spec/frontend/lib/utils/icon_utils_spec.js b/spec/frontend/lib/utils/icon_utils_spec.js index f798dc6744d..db1f174703b 100644 --- a/spec/frontend/lib/utils/icon_utils_spec.js +++ b/spec/frontend/lib/utils/icon_utils_spec.js @@ -34,13 +34,13 @@ describe('Icon utils', () => { }); it('extracts svg icon path content from sprite icons', () => { - return getSvgIconPathContent(mockName).then(path => { + return getSvgIconPathContent(mockName).then((path) => { expect(path).toBe(mockPath); }); }); it('returns null if icon path content does not exist', () => { - return getSvgIconPathContent('missing-icon').then(path => { + return getSvgIconPathContent('missing-icon').then((path) => { expect(path).toBe(null); }); }); @@ -58,22 +58,22 @@ describe('Icon utils', () => { }); it('returns null', () => { - return getSvgIconPathContent(mockName).then(path => { + return getSvgIconPathContent(mockName).then((path) => { expect(path).toBe(null); }); }); it('extracts svg icon path content, after 2 attempts', () => { return getSvgIconPathContent(mockName) - .then(path1 => { + .then((path1) => { expect(path1).toBe(null); return getSvgIconPathContent(mockName); }) - .then(path2 => { + .then((path2) => { expect(path2).toBe(null); return getSvgIconPathContent(mockName); }) - .then(path3 => { + .then((path3) => { expect(path3).toBe(mockPath); }); }); diff --git a/spec/frontend/lib/utils/mock_data.js b/spec/frontend/lib/utils/mock_data.js index c466b0cd1ed..df1f79529e7 100644 --- a/spec/frontend/lib/utils/mock_data.js +++ b/spec/frontend/lib/utils/mock_data.js @@ -3,6 +3,3 @@ export const faviconDataUrl = export const overlayDataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAA85JREFUWAntVllIVGEUPv/9b46O41KplYN7PeRkti8TjQlhCUGh3MmeQugpIsGKAi2soIcIooiohxYKK2daqDAlIpIiWwxtQaJcaHE0d5tMrbn37z9XRqfR0TvVW56Hudf//uec72zfEWBCJjIwkYGJDPzvGSD/KgExN3Oi2Q+2DJgSDYQEMwItVGH1iZGmJw/Si1y+/PwVAMYYib22MYc/8hVQFgKDEfYoId0KYzagAQebsos/ewMZoeB9wdffcTYpQSaCTWHKoqSQaDk7zkIt0+aCUR8BelEHrf3dUNv9AcqbnsHtT5UKB/hTASh0SLYjnjb/CIDRJi0XiFAaJOpCD8zLpdb4NB66b1OfelthX815dtdRRfiti2aAXLvVLiMQ6olGyztGDkSo4JGGXk8/QFdGpYzpHG2GBQTDhtgVhPEaVbbVpvI6GJz22rv4TcAfrYI1x7Rj5MWWAppomKFVVb2302SFzUkZHAbkG+0b1+Gh77yNYjrmqnWTrLBLRxdvBWv8qlFujH/kYjJYyvLkj71t78zAUvzMAMnHhpN4zf9UREJhd8omyssxu1IgazQDwDnHUcNuH6vhPIE1fmuBzHt74Hn7W89jWGtcAjoaIDOFrdcMYJBkgOCoaRF0Lj0oglddDbCj6tRvKjphEpgjkzEQs2YAKsNxMzjn3nKurhzK+Ly7xe28ua8TwgMMcHJZnvvT0BPtEEKM4tDJ+C8GvIIk4ylINIXVZ0EUKJxYuh3mhCeokbudl6TtVc88dfBdLwbyaWB6zQCYQJpBYSrDGQxBQ/ZWRM2B+VNmQnVnHWx7elyNuL2/R336co7KyJR8CL9oLgEuFlREevWUkEl6uGwpVEG4FBm0OEf9N10NMgPlvWYAuNVwsWDKvcUNYsHUWTCZ13ysyFEXe6TO6aC8CUr9IiK+A05TQrc8yjwmxARHeeMAPlfQJw+AQRwu0YhL/GDXi9NwufG+S8dYkuYMqIb4SsWthotlNMOUCOM6r+G9cqXxPmd1dqrBav/o1zJy2l5/NUjJA/VORwYuFnOUaTQcPs9wMqwV++Xv8oADxKAcZ8nLPr8AoGW+xR6HSqYk3GodAz2QNj0V+Gr26dT9ASNH5239Pf0gktVNWZca8ZvfAFBprWS6hSu1pqt++Y0PD+WIwDAhIWQGtzvSHDbcodfFUFB9hg1Gjs5LXqIdFL+acFBl+FddqYwdxsWC3I70OvgfUaA65zhq2O2c8VxYcyIGFTVlXegYtvCXANCQZJMobjVcLMjtSK/IcEgyOOe8Ve5w7ryKDefp2P3+C/5ohv8HZmVLAAAAAElFTkSuQmCC'; - -export const faviconWithOverlayDataUrl = - 'data:image/png;base64,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'; diff --git a/spec/frontend/lib/utils/poll_spec.js b/spec/frontend/lib/utils/poll_spec.js index 135c752b5cb..f2ca5df3672 100644 --- a/spec/frontend/lib/utils/poll_spec.js +++ b/spec/frontend/lib/utils/poll_spec.js @@ -50,7 +50,7 @@ describe('Poll', () => { }; }); - it('calls the success callback when no header for interval is provided', done => { + it('calls the success callback when no header for interval is provided', (done) => { mockServiceCall({ status: 200 }); setup(); @@ -62,7 +62,7 @@ describe('Poll', () => { }); }); - it('calls the error callback when the http request returns an error', done => { + it('calls the error callback when the http request returns an error', (done) => { mockServiceCall({ status: 500 }, true); setup(); @@ -74,7 +74,7 @@ describe('Poll', () => { }); }); - it('skips the error callback when request is aborted', done => { + it('skips the error callback when request is aborted', (done) => { mockServiceCall({ status: 0 }, true); setup(); @@ -87,7 +87,7 @@ describe('Poll', () => { }); }); - it('should call the success callback when the interval header is -1', done => { + it('should call the success callback when the interval header is -1', (done) => { mockServiceCall({ status: 200, headers: { 'poll-interval': -1 } }); setup() .then(() => { @@ -100,8 +100,8 @@ describe('Poll', () => { }); describe('for 2xx status code', () => { - successCodes.forEach(httpCode => { - it(`starts polling when http status is ${httpCode} and interval header is provided`, done => { + successCodes.forEach((httpCode) => { + it(`starts polling when http status is ${httpCode} and interval header is provided`, (done) => { mockServiceCall({ status: httpCode, headers: { 'poll-interval': 1 } }); const Polling = new Poll({ @@ -129,7 +129,7 @@ describe('Poll', () => { }); describe('with delayed initial request', () => { - it('delays the first request', async done => { + it('delays the first request', async (done) => { mockServiceCall({ status: 200, headers: { 'poll-interval': 1 } }); const Polling = new Poll({ @@ -158,7 +158,7 @@ describe('Poll', () => { }); describe('stop', () => { - it('stops polling when method is called', done => { + it('stops polling when method is called', (done) => { mockServiceCall({ status: 200, headers: { 'poll-interval': 1 } }); const Polling = new Poll({ @@ -186,7 +186,7 @@ describe('Poll', () => { }); describe('enable', () => { - it('should enable polling upon a response', done => { + it('should enable polling upon a response', (done) => { mockServiceCall({ status: 200 }); const Polling = new Poll({ resource: service, @@ -212,7 +212,7 @@ describe('Poll', () => { }); describe('restart', () => { - it('should restart polling when its called', done => { + it('should restart polling when its called', (done) => { mockServiceCall({ status: 200, headers: { 'poll-interval': 1 } }); const Polling = new Poll({ diff --git a/spec/frontend/lib/utils/poll_until_complete_spec.js b/spec/frontend/lib/utils/poll_until_complete_spec.js index c1df30756fd..38203c460e3 100644 --- a/spec/frontend/lib/utils/poll_until_complete_spec.js +++ b/spec/frontend/lib/utils/poll_until_complete_spec.js @@ -70,7 +70,7 @@ describe('pollUntilComplete', () => { }); it('rejects with the error response', () => - pollUntilComplete(endpoint).catch(error => { + pollUntilComplete(endpoint).catch((error) => { expect(error.response.data).toBe(errorMessage); })); }); diff --git a/spec/frontend/lib/utils/text_utility_spec.js b/spec/frontend/lib/utils/text_utility_spec.js index 9c50bf577dc..1f3659b5c76 100644 --- a/spec/frontend/lib/utils/text_utility_spec.js +++ b/spec/frontend/lib/utils/text_utility_spec.js @@ -300,13 +300,13 @@ describe('text_utility', () => { }); it(`should return an empty string for invalid inputs`, () => { - [undefined, null, 4, {}, true, new Date()].forEach(input => { + [undefined, null, 4, {}, true, new Date()].forEach((input) => { expect(textUtils.truncateNamespace(input)).toBe(''); }); }); it(`should not alter strings that aren't formatted as namespaces`, () => { - ['', ' ', '\t', 'a', 'a \\ b'].forEach(input => { + ['', ' ', '\t', 'a', 'a \\ b'].forEach((input) => { expect(textUtils.truncateNamespace(input)).toBe(input); }); }); diff --git a/spec/frontend/lib/utils/url_utility_spec.js b/spec/frontend/lib/utils/url_utility_spec.js index 0f9290e36b5..5846acbdb79 100644 --- a/spec/frontend/lib/utils/url_utility_spec.js +++ b/spec/frontend/lib/utils/url_utility_spec.js @@ -15,7 +15,7 @@ const shas = { ], }; -const setWindowLocation = value => { +const setWindowLocation = (value) => { Object.defineProperty(window, 'location', { writable: true, value, @@ -337,7 +337,7 @@ describe('URL utility', () => { describe('urlContainsSha', () => { it('returns true when there is a valid 40-character SHA1 hash in the URL', () => { - shas.valid.forEach(sha => { + shas.valid.forEach((sha) => { expect( urlUtils.urlContainsSha({ url: `http://urlstuff/${sha}/moreurlstuff` }), ).toBeTruthy(); @@ -345,7 +345,7 @@ describe('URL utility', () => { }); it('returns false when there is not a valid 40-character SHA1 hash in the URL', () => { - shas.invalid.forEach(str => { + shas.invalid.forEach((str) => { expect(urlUtils.urlContainsSha({ url: `http://urlstuff/${str}/moreurlstuff` })).toBeFalsy(); }); }); @@ -356,8 +356,8 @@ describe('URL utility', () => { let invalidUrls = []; beforeAll(() => { - validUrls = shas.valid.map(sha => `http://urlstuff/${sha}/moreurlstuff`); - invalidUrls = shas.invalid.map(str => `http://urlstuff/${str}/moreurlstuff`); + validUrls = shas.valid.map((sha) => `http://urlstuff/${sha}/moreurlstuff`); + invalidUrls = shas.invalid.map((str) => `http://urlstuff/${str}/moreurlstuff`); }); it('returns the valid 40-character SHA1 hash from the URL', () => { @@ -367,7 +367,7 @@ describe('URL utility', () => { }); it('returns null from a URL with no valid 40-character SHA1 hash', () => { - invalidUrls.forEach(url => { + invalidUrls.forEach((url) => { expect(urlUtils.getShaFromUrl({ url })).toBeNull(); }); }); @@ -589,11 +589,11 @@ describe('URL utility', () => { ]; describe('with URL constructor support', () => { - it.each(safeUrls)('returns true for %s', url => { + it.each(safeUrls)('returns true for %s', (url) => { expect(urlUtils.isSafeURL(url)).toBe(true); }); - it.each(unsafeUrls)('returns false for %s', url => { + it.each(unsafeUrls)('returns false for %s', (url) => { expect(urlUtils.isSafeURL(url)).toBe(false); }); }); @@ -807,7 +807,7 @@ describe('URL utility', () => { it.each([[httpProtocol], [httpsProtocol]])( 'when no url passed, returns correct protocol for %i from window location', - protocol => { + (protocol) => { setWindowLocation({ protocol, }); diff --git a/spec/frontend/lib/utils/users_cache_spec.js b/spec/frontend/lib/utils/users_cache_spec.js index 7ed87123482..4034f39ee9c 100644 --- a/spec/frontend/lib/utils/users_cache_spec.js +++ b/spec/frontend/lib/utils/users_cache_spec.js @@ -1,4 +1,4 @@ -import Api from '~/api'; +import * as UserApi from '~/api/user_api'; import UsersCache from '~/lib/utils/users_cache'; describe('UsersCache', () => { @@ -88,10 +88,12 @@ describe('UsersCache', () => { let apiSpy; beforeEach(() => { - jest.spyOn(Api, 'users').mockImplementation((query, options) => apiSpy(query, options)); + jest + .spyOn(UserApi, 'getUsers') + .mockImplementation((query, options) => apiSpy(query, options)); }); - it('stores and returns data from API call if cache is empty', done => { + it('stores and returns data from API call if cache is empty', (done) => { apiSpy = (query, options) => { expect(query).toBe(''); expect(options).toEqual({ @@ -104,7 +106,7 @@ describe('UsersCache', () => { }; UsersCache.retrieve(dummyUsername) - .then(user => { + .then((user) => { expect(user).toBe(dummyUser); expect(UsersCache.internalStorage[dummyUsername]).toBe(dummyUser); }) @@ -112,7 +114,7 @@ describe('UsersCache', () => { .catch(done.fail); }); - it('returns undefined if Ajax call fails and cache is empty', done => { + it('returns undefined if Ajax call fails and cache is empty', (done) => { const dummyError = new Error('server exploded'); apiSpy = (query, options) => { @@ -125,21 +127,21 @@ describe('UsersCache', () => { }; UsersCache.retrieve(dummyUsername) - .then(user => done.fail(`Received unexpected user: ${JSON.stringify(user)}`)) - .catch(error => { + .then((user) => done.fail(`Received unexpected user: ${JSON.stringify(user)}`)) + .catch((error) => { expect(error).toBe(dummyError); }) .then(done) .catch(done.fail); }); - it('makes no Ajax call if matching data exists', done => { + it('makes no Ajax call if matching data exists', (done) => { UsersCache.internalStorage[dummyUsername] = dummyUser; apiSpy = () => done.fail(new Error('expected no Ajax call!')); UsersCache.retrieve(dummyUsername) - .then(user => { + .then((user) => { expect(user).toBe(dummyUser); }) .then(done) @@ -151,11 +153,11 @@ describe('UsersCache', () => { let apiSpy; beforeEach(() => { - jest.spyOn(Api, 'user').mockImplementation(id => apiSpy(id)); + jest.spyOn(UserApi, 'getUser').mockImplementation((id) => apiSpy(id)); }); - it('stores and returns data from API call if cache is empty', done => { - apiSpy = id => { + it('stores and returns data from API call if cache is empty', (done) => { + apiSpy = (id) => { expect(id).toBe(dummyUserId); return Promise.resolve({ @@ -164,7 +166,7 @@ describe('UsersCache', () => { }; UsersCache.retrieveById(dummyUserId) - .then(user => { + .then((user) => { expect(user).toBe(dummyUser); expect(UsersCache.internalStorage[dummyUserId]).toBe(dummyUser); }) @@ -172,31 +174,31 @@ describe('UsersCache', () => { .catch(done.fail); }); - it('returns undefined if Ajax call fails and cache is empty', done => { + it('returns undefined if Ajax call fails and cache is empty', (done) => { const dummyError = new Error('server exploded'); - apiSpy = id => { + apiSpy = (id) => { expect(id).toBe(dummyUserId); return Promise.reject(dummyError); }; UsersCache.retrieveById(dummyUserId) - .then(user => done.fail(`Received unexpected user: ${JSON.stringify(user)}`)) - .catch(error => { + .then((user) => done.fail(`Received unexpected user: ${JSON.stringify(user)}`)) + .catch((error) => { expect(error).toBe(dummyError); }) .then(done) .catch(done.fail); }); - it('makes no Ajax call if matching data exists', done => { + it('makes no Ajax call if matching data exists', (done) => { UsersCache.internalStorage[dummyUserId] = dummyUser; apiSpy = () => done.fail(new Error('expected no Ajax call!')); UsersCache.retrieveById(dummyUserId) - .then(user => { + .then((user) => { expect(user).toBe(dummyUser); }) .then(done) @@ -208,11 +210,11 @@ describe('UsersCache', () => { let apiSpy; beforeEach(() => { - jest.spyOn(Api, 'userStatus').mockImplementation(id => apiSpy(id)); + jest.spyOn(UserApi, 'getUserStatus').mockImplementation((id) => apiSpy(id)); }); - it('stores and returns data from API call if cache is empty', done => { - apiSpy = id => { + it('stores and returns data from API call if cache is empty', (done) => { + apiSpy = (id) => { expect(id).toBe(dummyUserId); return Promise.resolve({ @@ -221,7 +223,7 @@ describe('UsersCache', () => { }; UsersCache.retrieveStatusById(dummyUserId) - .then(userStatus => { + .then((userStatus) => { expect(userStatus).toBe(dummyUserStatus); expect(UsersCache.internalStorage[dummyUserId].status).toBe(dummyUserStatus); }) @@ -229,25 +231,25 @@ describe('UsersCache', () => { .catch(done.fail); }); - it('returns undefined if Ajax call fails and cache is empty', done => { + it('returns undefined if Ajax call fails and cache is empty', (done) => { const dummyError = new Error('server exploded'); - apiSpy = id => { + apiSpy = (id) => { expect(id).toBe(dummyUserId); return Promise.reject(dummyError); }; UsersCache.retrieveStatusById(dummyUserId) - .then(userStatus => done.fail(`Received unexpected user: ${JSON.stringify(userStatus)}`)) - .catch(error => { + .then((userStatus) => done.fail(`Received unexpected user: ${JSON.stringify(userStatus)}`)) + .catch((error) => { expect(error).toBe(dummyError); }) .then(done) .catch(done.fail); }); - it('makes no Ajax call if matching data exists', done => { + it('makes no Ajax call if matching data exists', (done) => { UsersCache.internalStorage[dummyUserId] = { status: dummyUserStatus, }; @@ -255,7 +257,7 @@ describe('UsersCache', () => { apiSpy = () => done.fail(new Error('expected no Ajax call!')); UsersCache.retrieveStatusById(dummyUserId) - .then(userStatus => { + .then((userStatus) => { expect(userStatus).toBe(dummyUserStatus); }) .then(done) |