diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-20 11:43:02 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-20 11:43:02 +0300 |
commit | d9ab72d6080f594d0b3cae15f14b3ef2c6c638cb (patch) | |
tree | 2341ef426af70ad1e289c38036737e04b0aa5007 /spec/frontend/lib | |
parent | d6e514dd13db8947884cd58fe2a9c2a063400a9b (diff) |
Add latest changes from gitlab-org/gitlab@14-4-stable-eev14.4.0-rc42
Diffstat (limited to 'spec/frontend/lib')
-rw-r--r-- | spec/frontend/lib/apollo/suppress_network_errors_during_navigation_link_spec.js | 155 | ||||
-rw-r--r-- | spec/frontend/lib/logger/__snapshots__/hello_spec.js.snap | 21 | ||||
-rw-r--r-- | spec/frontend/lib/logger/hello_spec.js | 28 | ||||
-rw-r--r-- | spec/frontend/lib/utils/color_utils_spec.js | 18 | ||||
-rw-r--r-- | spec/frontend/lib/utils/datetime/date_format_utility_spec.js | 15 | ||||
-rw-r--r-- | spec/frontend/lib/utils/is_navigating_away_spec.js | 23 | ||||
-rw-r--r-- | spec/frontend/lib/utils/text_utility_spec.js | 21 | ||||
-rw-r--r-- | spec/frontend/lib/utils/url_utility_spec.js | 35 |
8 files changed, 310 insertions, 6 deletions
diff --git a/spec/frontend/lib/apollo/suppress_network_errors_during_navigation_link_spec.js b/spec/frontend/lib/apollo/suppress_network_errors_during_navigation_link_spec.js new file mode 100644 index 00000000000..852106db44e --- /dev/null +++ b/spec/frontend/lib/apollo/suppress_network_errors_during_navigation_link_spec.js @@ -0,0 +1,155 @@ +import { ApolloLink, Observable } from 'apollo-link'; +import waitForPromises from 'helpers/wait_for_promises'; +import { getSuppressNetworkErrorsDuringNavigationLink } from '~/lib/apollo/suppress_network_errors_during_navigation_link'; +import { isNavigatingAway } from '~/lib/utils/is_navigating_away'; + +jest.mock('~/lib/utils/is_navigating_away'); + +describe('getSuppressNetworkErrorsDuringNavigationLink', () => { + const originalGon = window.gon; + let subscription; + + beforeEach(() => { + window.gon = originalGon; + }); + + afterEach(() => { + if (subscription) { + subscription.unsubscribe(); + } + }); + + const makeMockGraphQLErrorLink = () => + new ApolloLink(() => + Observable.of({ + errors: [ + { + message: 'foo', + }, + ], + }), + ); + + const makeMockNetworkErrorLink = () => + new ApolloLink( + () => + new Observable(() => { + throw new Error('NetworkError'); + }), + ); + + const makeMockSuccessLink = () => + new ApolloLink(() => Observable.of({ data: { foo: { id: 1 } } })); + + const createSubscription = (otherLink, observer) => { + const mockOperation = { operationName: 'foo' }; + const link = getSuppressNetworkErrorsDuringNavigationLink().concat(otherLink); + subscription = link.request(mockOperation).subscribe(observer); + }; + + describe('when disabled', () => { + it('returns null', () => { + expect(getSuppressNetworkErrorsDuringNavigationLink()).toBe(null); + }); + }); + + describe('when enabled', () => { + beforeEach(() => { + window.gon = { features: { suppressApolloErrorsDuringNavigation: true } }; + }); + + it('returns an ApolloLink', () => { + expect(getSuppressNetworkErrorsDuringNavigationLink()).toEqual(expect.any(ApolloLink)); + }); + + describe('suppression case', () => { + describe('when navigating away', () => { + beforeEach(() => { + isNavigatingAway.mockReturnValue(true); + }); + + describe('given a network error', () => { + it('does not forward the error', async () => { + const spy = jest.fn(); + + createSubscription(makeMockNetworkErrorLink(), { + next: spy, + error: spy, + complete: spy, + }); + + // It's hard to test for something _not_ happening. The best we can + // do is wait a bit to make sure nothing happens. + await waitForPromises(); + expect(spy).not.toHaveBeenCalled(); + }); + }); + }); + }); + + describe('non-suppression cases', () => { + describe('when not navigating away', () => { + beforeEach(() => { + isNavigatingAway.mockReturnValue(false); + }); + + it('forwards successful requests', (done) => { + createSubscription(makeMockSuccessLink(), { + next({ data }) { + expect(data).toEqual({ foo: { id: 1 } }); + }, + error: () => done.fail('Should not happen'), + complete: () => done(), + }); + }); + + it('forwards GraphQL errors', (done) => { + createSubscription(makeMockGraphQLErrorLink(), { + next({ errors }) { + expect(errors).toEqual([{ message: 'foo' }]); + }, + error: () => done.fail('Should not happen'), + complete: () => done(), + }); + }); + + it('forwards network errors', (done) => { + createSubscription(makeMockNetworkErrorLink(), { + next: () => done.fail('Should not happen'), + error: (error) => { + expect(error.message).toBe('NetworkError'); + done(); + }, + complete: () => done.fail('Should not happen'), + }); + }); + }); + + describe('when navigating away', () => { + beforeEach(() => { + isNavigatingAway.mockReturnValue(true); + }); + + it('forwards successful requests', (done) => { + createSubscription(makeMockSuccessLink(), { + next({ data }) { + expect(data).toEqual({ foo: { id: 1 } }); + }, + error: () => done.fail('Should not happen'), + complete: () => done(), + }); + }); + + it('forwards GraphQL errors', (done) => { + createSubscription(makeMockGraphQLErrorLink(), { + next({ errors }) { + expect(errors).toEqual([{ message: 'foo' }]); + }, + error: () => done.fail('Should not happen'), + complete: () => done(), + }); + }); + }); + }); + }); +}); diff --git a/spec/frontend/lib/logger/__snapshots__/hello_spec.js.snap b/spec/frontend/lib/logger/__snapshots__/hello_spec.js.snap index 791ec05befd..0b156049dab 100644 --- a/spec/frontend/lib/logger/__snapshots__/hello_spec.js.snap +++ b/spec/frontend/lib/logger/__snapshots__/hello_spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`~/lib/logger/hello logHello console logs a friendly hello message 1`] = ` +exports[`~/lib/logger/hello logHello when on dot_com console logs a friendly hello message including the careers page 1`] = ` Array [ Array [ "%cWelcome to GitLab!%c @@ -8,7 +8,24 @@ Array [ Does this page need fixes or improvements? Open an issue or contribute a merge request to help make GitLab more lovable. At GitLab, everyone can contribute! 🤝 Contribute to GitLab: https://about.gitlab.com/community/contribute/ -🔎 Create a new GitLab issue: https://gitlab.com/gitlab-org/gitlab/-/issues/new", +🔎 Create a new GitLab issue: https://gitlab.com/gitlab-org/gitlab/-/issues/new +🚀 We like your curiosity! Help us improve GitLab by joining the team: https://about.gitlab.com/jobs/", + "padding-top: 0.5em; font-size: 2em;", + "padding-bottom: 0.5em;", + ], +] +`; + +exports[`~/lib/logger/hello logHello when on self managed console logs a friendly hello message without including the careers page 1`] = ` +Array [ + Array [ + "%cWelcome to GitLab!%c + +Does this page need fixes or improvements? Open an issue or contribute a merge request to help make GitLab more lovable. At GitLab, everyone can contribute! + +🤝 Contribute to GitLab: https://about.gitlab.com/community/contribute/ +🔎 Create a new GitLab issue: https://gitlab.com/gitlab-org/gitlab/-/issues/new +", "padding-top: 0.5em; font-size: 2em;", "padding-bottom: 0.5em;", ], diff --git a/spec/frontend/lib/logger/hello_spec.js b/spec/frontend/lib/logger/hello_spec.js index 39abe0e0dd0..39c1b55313b 100644 --- a/spec/frontend/lib/logger/hello_spec.js +++ b/spec/frontend/lib/logger/hello_spec.js @@ -9,12 +9,32 @@ describe('~/lib/logger/hello', () => { }); describe('logHello', () => { - it('console logs a friendly hello message', () => { - expect(consoleLogSpy).not.toHaveBeenCalled(); + describe('when on dot_com', () => { + beforeEach(() => { + gon.dot_com = true; + }); - logHello(); + it('console logs a friendly hello message including the careers page', () => { + expect(consoleLogSpy).not.toHaveBeenCalled(); - expect(consoleLogSpy.mock.calls).toMatchSnapshot(); + logHello(); + + expect(consoleLogSpy.mock.calls).toMatchSnapshot(); + }); + }); + + describe('when on self managed', () => { + beforeEach(() => { + gon.dot_com = false; + }); + + it('console logs a friendly hello message without including the careers page', () => { + expect(consoleLogSpy).not.toHaveBeenCalled(); + + logHello(); + + expect(consoleLogSpy.mock.calls).toMatchSnapshot(); + }); }); }); }); diff --git a/spec/frontend/lib/utils/color_utils_spec.js b/spec/frontend/lib/utils/color_utils_spec.js index c6b88b2957c..87966cf9fba 100644 --- a/spec/frontend/lib/utils/color_utils_spec.js +++ b/spec/frontend/lib/utils/color_utils_spec.js @@ -1,4 +1,5 @@ import { + isValidColorExpression, textColorForBackground, hexToRgb, validateHexColor, @@ -72,4 +73,21 @@ describe('Color utils', () => { }, ); }); + + describe('isValidColorExpression', () => { + it.each` + colorExpression | valid | desc + ${'#F00'} | ${true} | ${'valid'} + ${'rgba(0,0,0,0)'} | ${true} | ${'valid'} + ${'hsl(540,70%,50%)'} | ${true} | ${'valid'} + ${'red'} | ${true} | ${'valid'} + ${'F00'} | ${false} | ${'invalid'} + ${'F00'} | ${false} | ${'invalid'} + ${'gba(0,0,0,0)'} | ${false} | ${'invalid'} + ${'hls(540,70%,50%)'} | ${false} | ${'invalid'} + ${'hello'} | ${false} | ${'invalid'} + `('color expression $colorExpression is $desc', ({ colorExpression, valid }) => { + expect(isValidColorExpression(colorExpression)).toBe(valid); + }); + }); }); diff --git a/spec/frontend/lib/utils/datetime/date_format_utility_spec.js b/spec/frontend/lib/utils/datetime/date_format_utility_spec.js index 942ba56196e..1adc70450e8 100644 --- a/spec/frontend/lib/utils/datetime/date_format_utility_spec.js +++ b/spec/frontend/lib/utils/datetime/date_format_utility_spec.js @@ -118,3 +118,18 @@ describe('date_format_utility.js', () => { }); }); }); + +describe('formatTimeAsSummary', () => { + it.each` + unit | value | result + ${'months'} | ${1.5} | ${'1.5M'} + ${'weeks'} | ${1.25} | ${'1.5w'} + ${'days'} | ${2} | ${'2d'} + ${'hours'} | ${10} | ${'10h'} + ${'minutes'} | ${20} | ${'20m'} + ${'seconds'} | ${10} | ${'<1m'} + ${'seconds'} | ${0} | ${'-'} + `('will format $value $unit to $result', ({ unit, value, result }) => { + expect(utils.formatTimeAsSummary({ [unit]: value })).toBe(result); + }); +}); diff --git a/spec/frontend/lib/utils/is_navigating_away_spec.js b/spec/frontend/lib/utils/is_navigating_away_spec.js new file mode 100644 index 00000000000..e1230fe96bf --- /dev/null +++ b/spec/frontend/lib/utils/is_navigating_away_spec.js @@ -0,0 +1,23 @@ +import { isNavigatingAway, setNavigatingForTestsOnly } from '~/lib/utils/is_navigating_away'; + +describe('isNavigatingAway', () => { + beforeEach(() => { + // Make sure each test starts with the same state + setNavigatingForTestsOnly(false); + }); + + it.each([false, true])('it returns the navigation flag with value %s', (flag) => { + setNavigatingForTestsOnly(flag); + expect(isNavigatingAway()).toEqual(flag); + }); + + describe('when the browser starts navigating away', () => { + it('returns true', () => { + expect(isNavigatingAway()).toEqual(false); + + window.dispatchEvent(new Event('beforeunload')); + + expect(isNavigatingAway()).toEqual(true); + }); + }); +}); diff --git a/spec/frontend/lib/utils/text_utility_spec.js b/spec/frontend/lib/utils/text_utility_spec.js index 1f3659b5c76..9570d2a831c 100644 --- a/spec/frontend/lib/utils/text_utility_spec.js +++ b/spec/frontend/lib/utils/text_utility_spec.js @@ -363,4 +363,25 @@ describe('text_utility', () => { expect(textUtils.insertFinalNewline(input, '\r\n')).toBe(output); }); }); + + describe('escapeShellString', () => { + it.each` + character | input | output + ${'"'} | ${'";echo "you_shouldnt_run_this'} | ${'\'";echo "you_shouldnt_run_this\''} + ${'$'} | ${'$IFS'} | ${"'$IFS'"} + ${'\\'} | ${'evil-branch-name\\'} | ${"'evil-branch-name\\'"} + ${'!'} | ${'!event'} | ${"'!event'"} + `( + 'should not escape the $character character but wrap in single-quotes', + ({ input, output }) => { + expect(textUtils.escapeShellString(input)).toBe(output); + }, + ); + + it("should escape the ' character and wrap in single-quotes", () => { + expect(textUtils.escapeShellString("fix-'bug-behavior'")).toBe( + "'fix-'\\''bug-behavior'\\'''", + ); + }); + }); }); diff --git a/spec/frontend/lib/utils/url_utility_spec.js b/spec/frontend/lib/utils/url_utility_spec.js index 6f186ba3227..18b68d91e01 100644 --- a/spec/frontend/lib/utils/url_utility_spec.js +++ b/spec/frontend/lib/utils/url_utility_spec.js @@ -1004,4 +1004,39 @@ describe('URL utility', () => { expect(urlUtils.isSameOriginUrl(url)).toBe(expected); }); }); + + describe('constructWebIDEPath', () => { + let originalGl; + const projectIDEPath = '/foo/bar'; + const sourceProj = 'my_-fancy-proj/boo'; + const targetProj = 'boo/another-fancy-proj'; + const mrIid = '7'; + + beforeEach(() => { + originalGl = window.gl; + window.gl = { webIDEPath: projectIDEPath }; + }); + + afterEach(() => { + window.gl = originalGl; + }); + + it.each` + sourceProjectFullPath | targetProjectFullPath | iid | expectedPath + ${undefined} | ${undefined} | ${undefined} | ${projectIDEPath} + ${undefined} | ${undefined} | ${mrIid} | ${projectIDEPath} + ${undefined} | ${targetProj} | ${undefined} | ${projectIDEPath} + ${undefined} | ${targetProj} | ${mrIid} | ${projectIDEPath} + ${sourceProj} | ${undefined} | ${undefined} | ${projectIDEPath} + ${sourceProj} | ${targetProj} | ${undefined} | ${projectIDEPath} + ${sourceProj} | ${undefined} | ${mrIid} | ${`/-/ide/project/${sourceProj}/merge_requests/${mrIid}?target_project=`} + ${sourceProj} | ${sourceProj} | ${mrIid} | ${`/-/ide/project/${sourceProj}/merge_requests/${mrIid}?target_project=`} + ${sourceProj} | ${targetProj} | ${mrIid} | ${`/-/ide/project/${sourceProj}/merge_requests/${mrIid}?target_project=${encodeURIComponent(targetProj)}`} + `( + 'returns $expectedPath for "$sourceProjectFullPath + $targetProjectFullPath + $iid"', + ({ expectedPath, ...args } = {}) => { + expect(urlUtils.constructWebIDEPath(args)).toBe(expectedPath); + }, + ); + }); }); |