Commit 4965a720 authored by Tom Quirk's avatar Tom Quirk

Jira Connect: consolidate sign in link update logic

We have logic that adds a `return_to` parameter
to sign-in links in the JIra Connect app. This code
was previously duplicated.

This commit consolidates the code into a single helper
function.

There are no user facing changes.
parent d7bba2c7
<script> <script>
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { getLocation } from '~/jira_connect/subscriptions/utils'; import { getGitlabSignInURL } from '~/jira_connect/subscriptions/utils';
import { objectToQuery } from '~/lib/utils/url_utility';
export default { export default {
components: { components: {
...@@ -15,34 +14,21 @@ export default { ...@@ -15,34 +14,21 @@ export default {
}, },
data() { data() {
return { return {
location: '', signInURL: '',
}; };
}, },
computed: {
usersPathWithReturnTo() {
if (this.location) {
const queryParams = {
return_to: this.location,
};
return `${this.usersPath}?${objectToQuery(queryParams)}`;
}
return this.usersPath;
},
},
created() { created() {
this.setLocation(); this.setSignInURL();
}, },
methods: { methods: {
async setLocation() { async setSignInURL() {
this.location = await getLocation(); this.signInURL = await getGitlabSignInURL(this.usersPath);
}, },
}, },
}; };
</script> </script>
<template> <template>
<gl-button category="primary" variant="info" :href="usersPathWithReturnTo" target="_blank"> <gl-button category="primary" variant="info" :href="signInURL" target="_blank">
<slot> <slot>
{{ s__('Integrations|Sign in to add namespaces') }} {{ s__('Integrations|Sign in to add namespaces') }}
</slot> </slot>
......
...@@ -7,7 +7,7 @@ import Translate from '~/vue_shared/translate'; ...@@ -7,7 +7,7 @@ import Translate from '~/vue_shared/translate';
import JiraConnectApp from './components/app.vue'; import JiraConnectApp from './components/app.vue';
import createStore from './store'; import createStore from './store';
import { getLocation, sizeToParent } from './utils'; import { getGitlabSignInURL, sizeToParent } from './utils';
const store = createStore(); const store = createStore();
...@@ -15,11 +15,12 @@ const store = createStore(); ...@@ -15,11 +15,12 @@ const store = createStore();
* Add `return_to` query param to all HAML-defined GitLab sign in links. * Add `return_to` query param to all HAML-defined GitLab sign in links.
*/ */
const updateSignInLinks = async () => { const updateSignInLinks = async () => {
const location = await getLocation(); await Promise.all(
Array.from(document.querySelectorAll('.js-jira-connect-sign-in')).forEach((el) => { Array.from(document.querySelectorAll('.js-jira-connect-sign-in')).map(async (el) => {
const updatedLink = `${el.getAttribute('href')}?return_to=${location}`; const updatedLink = await getGitlabSignInURL(el.getAttribute('href'));
el.setAttribute('href', updatedLink); el.setAttribute('href', updatedLink);
}); }),
);
}; };
export async function initJiraConnect() { export async function initJiraConnect() {
......
import AccessorUtilities from '~/lib/utils/accessor'; import AccessorUtilities from '~/lib/utils/accessor';
import { objectToQuery } from '~/lib/utils/url_utility';
import { ALERT_LOCALSTORAGE_KEY } from './constants'; import { ALERT_LOCALSTORAGE_KEY } from './constants';
const isFunction = (fn) => typeof fn === 'function'; const isFunction = (fn) => typeof fn === 'function';
...@@ -71,3 +72,17 @@ export const sizeToParent = () => { ...@@ -71,3 +72,17 @@ export const sizeToParent = () => {
AP.sizeToParent(); AP.sizeToParent();
} }
}; };
export const getGitlabSignInURL = async (signInURL) => {
const location = await getLocation();
if (location) {
const queryParams = {
return_to: location,
};
return `${signInURL}?${objectToQuery(queryParams)}`;
}
return signInURL;
};
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { getLocation } from '~/jira_connect/subscriptions/utils'; import { getGitlabSignInURL } from '~/jira_connect/subscriptions/utils';
import SignInButton from '~/jira_connect/subscriptions/components/sign_in_button.vue'; import SignInButton from '~/jira_connect/subscriptions/components/sign_in_button.vue';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
...@@ -32,16 +32,14 @@ describe('SignInButton', () => { ...@@ -32,16 +32,14 @@ describe('SignInButton', () => {
}); });
describe.each` describe.each`
getLocationValue | expectedHref expectedHref
${''} | ${MOCK_USERS_PATH} ${MOCK_USERS_PATH}
${undefined} | ${MOCK_USERS_PATH} ${`${MOCK_USERS_PATH}?return_to=${encodeURIComponent('https://test.jira.com')}`}
${'https://test.jira.com'} | ${`${MOCK_USERS_PATH}?return_to=${encodeURIComponent('https://test.jira.com')}`} `('when getGitlabSignInURL resolves with `$expectedHref`', ({ expectedHref }) => {
`('when getLocation resolves with `$getLocationValue`', ({ getLocationValue, expectedHref }) => {
it(`sets button href to ${expectedHref}`, async () => { it(`sets button href to ${expectedHref}`, async () => {
getLocation.mockResolvedValue(getLocationValue); getGitlabSignInURL.mockResolvedValue(expectedHref);
createComponent(); createComponent();
expect(getLocation).toHaveBeenCalled();
await waitForPromises(); await waitForPromises();
expect(findButton().attributes('href')).toBe(expectedHref); expect(findButton().attributes('href')).toBe(expectedHref);
......
import { initJiraConnect } from '~/jira_connect/subscriptions'; import { initJiraConnect } from '~/jira_connect/subscriptions';
import { getGitlabSignInURL } from '~/jira_connect/subscriptions/utils';
jest.mock('~/jira_connect/subscriptions/utils', () => ({ jest.mock('~/jira_connect/subscriptions/utils');
getLocation: jest.fn().mockResolvedValue('test/location'),
}));
describe('initJiraConnect', () => { describe('initJiraConnect', () => {
beforeEach(async () => { const mockInitialHref = 'https://gitlab.com';
beforeEach(() => {
setFixtures(` setFixtures(`
<a class="js-jira-connect-sign-in" href="https://gitlab.com">Sign In</a> <a class="js-jira-connect-sign-in" href="${mockInitialHref}">Sign In</a>
<a class="js-jira-connect-sign-in" href="https://gitlab.com">Another Sign In</a> <a class="js-jira-connect-sign-in" href="${mockInitialHref}">Another Sign In</a>
`); `);
await initJiraConnect();
}); });
describe('Sign in links', () => { const assertSignInLinks = (expectedLink) => {
it('have `return_to` query parameter', () => {
Array.from(document.querySelectorAll('.js-jira-connect-sign-in')).forEach((el) => { Array.from(document.querySelectorAll('.js-jira-connect-sign-in')).forEach((el) => {
expect(el.href).toContain('return_to=test/location'); expect(el.getAttribute('href')).toBe(expectedLink);
}); });
};
describe('Sign in links', () => {
it('are updated on initialization', async () => {
const mockSignInLink = `https://gitlab.com?return_to=${encodeURIComponent('/test/location')}`;
getGitlabSignInURL.mockResolvedValue(mockSignInLink);
// assert the initial state
assertSignInLinks(mockInitialHref);
await initJiraConnect();
// assert the update has occurred
assertSignInLinks(mockSignInLink);
}); });
}); });
}); });
...@@ -8,6 +8,7 @@ import { ...@@ -8,6 +8,7 @@ import {
getLocation, getLocation,
reloadPage, reloadPage,
sizeToParent, sizeToParent,
getGitlabSignInURL,
} from '~/jira_connect/subscriptions/utils'; } from '~/jira_connect/subscriptions/utils';
describe('JiraConnect utils', () => { describe('JiraConnect utils', () => {
...@@ -137,4 +138,25 @@ describe('JiraConnect utils', () => { ...@@ -137,4 +138,25 @@ describe('JiraConnect utils', () => {
}); });
}); });
}); });
describe('getGitlabSignInURL', () => {
const mockSignInURL = 'https://gitlab.com/sign_in';
it.each`
returnTo | expectResult
${undefined} | ${mockSignInURL}
${''} | ${mockSignInURL}
${'/test/location'} | ${`${mockSignInURL}?return_to=${encodeURIComponent('/test/location')}`}
`(
'returns `$expectResult` when `AP.getLocation` resolves to `$returnTo`',
async ({ returnTo, expectResult }) => {
global.AP = {
getLocation: jest.fn().mockImplementation((cb) => cb(returnTo)),
};
const url = await getGitlabSignInURL(mockSignInURL);
expect(url).toBe(expectResult);
},
);
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment