Commit cf00b8e5 authored by Miguel Rincon's avatar Miguel Rincon

Move URL utils getParameterByName to url_utility

This change moves getParameterByName from `~/lib/utils/common_utils`
to `~/lib/utils/url_utility`.
parent 4bc09efd
......@@ -4,8 +4,7 @@ import { mapGetters, mapActions, mapState } from 'vuex';
import ListLabel from '~/boards/models/label';
import { TYPE_ITERATION, TYPE_MILESTONE, TYPE_USER } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { getParameterByName } from '~/lib/utils/common_utils';
import { visitUrl } from '~/lib/utils/url_utility';
import { getParameterByName, visitUrl } from '~/lib/utils/url_utility';
import { __, s__ } from '~/locale';
import { fullLabelId, fullBoardId } from '../boards_util';
import { formType } from '../constants';
......
import { TRACKING_CONTEXT_SCHEMA } from '~/experimentation/constants';
import { getExperimentData } from '~/experimentation/utils';
import { setCookie, getCookie, getParameterByName } from '~/lib/utils/common_utils';
import { setCookie, getCookie } from '~/lib/utils/common_utils';
import { getParameterByName } from '~/lib/utils/url_utility';
import Tracking from '~/tracking';
import { EXPERIMENT_NAME } from './constants';
......
<script>
import { GlButton, GlEmptyState, GlLoadingIcon, GlModal, GlLink } from '@gitlab/ui';
import { getParameterByName } from '~/lib/utils/common_utils';
import { getParameterByName } from '~/lib/utils/url_utility';
import PipelinesTableComponent from '~/pipelines/components/pipelines_list/pipelines_table.vue';
import eventHub from '~/pipelines/event_hub';
import PipelinesMixin from '~/pipelines/mixins/pipelines_mixin';
......
import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils';
import { parseBoolean } from '~/lib/utils/common_utils';
import { getParameterByName } from '~/lib/utils/url_utility';
import { __, n__, sprintf } from '~/locale';
import { DIFF_COMPARE_BASE_VERSION_INDEX, DIFF_COMPARE_HEAD_VERSION_INDEX } from '../constants';
......
......@@ -4,8 +4,8 @@
import { isEqual, isFunction, omitBy } from 'lodash';
import Visibility from 'visibilityjs';
import createFlash from '~/flash';
import { getParameterByName } from '../../lib/utils/common_utils';
import Poll from '../../lib/utils/poll';
import { getParameterByName } from '../../lib/utils/url_utility';
import { s__ } from '../../locale';
import tabs from '../../vue_shared/components/navigation_tabs.vue';
import tablePagination from '../../vue_shared/components/pagination/table_pagination.vue';
......
......@@ -3,11 +3,8 @@ import { GlAlert, GlBadge, GlButton, GlModalDirective, GlSprintf } from '@gitlab
import { isEmpty } from 'lodash';
import { mapState, mapActions } from 'vuex';
import {
buildUrlWithCurrentLocation,
getParameterByName,
historyPushState,
} from '~/lib/utils/common_utils';
import { buildUrlWithCurrentLocation, historyPushState } from '~/lib/utils/common_utils';
import { getParameterByName } from '~/lib/utils/url_utility';
import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue';
import ConfigureFeatureFlagsModal from './configure_feature_flags_modal.vue';
import EmptyState from './empty_state.vue';
......
......@@ -2,7 +2,6 @@ import { last } from 'lodash';
import recentSearchesStorageKeys from 'ee_else_ce/filtered_search/recent_searches_storage_keys';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
import createFlash from '~/flash';
import { getParameterByName } from '~/lib/utils/common_utils';
import {
ENTER_KEY_CODE,
BACKSPACE_KEY_CODE,
......@@ -12,7 +11,7 @@ import {
} from '~/lib/utils/keycodes';
import { __ } from '~/locale';
import { addClassIfElementExists } from '../lib/utils/dom_utils';
import { visitUrl, getUrlParamsArray } from '../lib/utils/url_utility';
import { visitUrl, getUrlParamsArray, getParameterByName } from '../lib/utils/url_utility';
import FilteredSearchContainer from './container';
import DropdownUtils from './dropdown_utils';
import eventHub from './event_hub';
......
<script>
import { GlLoadingIcon, GlModal } from '@gitlab/ui';
import createFlash from '~/flash';
import { getParameterByName } from '~/lib/utils/common_utils';
import { HIDDEN_CLASS } from '~/lib/utils/constants';
import { mergeUrlParams } from '~/lib/utils/url_utility';
import { mergeUrlParams, getParameterByName } from '~/lib/utils/url_utility';
import { __, s__, sprintf } from '~/locale';
import { COMMON_STR, CONTENT_LIST_CLASS } from '../constants';
......
<script>
import PaginationLinks from '~/vue_shared/components/pagination_links.vue';
import { getParameterByName } from '../../lib/utils/common_utils';
import { getParameterByName } from '../../lib/utils/url_utility';
import eventHub from '../event_hub';
export default {
......
import $ from 'jquery';
import FilterableList from '~/filterable_list';
import { normalizeHeaders, getParameterByName } from '../lib/utils/common_utils';
import { normalizeHeaders } from '../lib/utils/common_utils';
import { getParameterByName } from '../lib/utils/url_utility';
import eventHub from './event_hub';
export default class GroupFilterableList extends FilterableList {
......@@ -45,7 +46,7 @@ export default class GroupFilterableList extends FilterableList {
onFilterInput() {
const queryData = {};
const $form = $(this.form);
const archivedParam = getParameterByName('archived', window.location.href);
const archivedParam = getParameterByName('archived');
const filterGroupsParam = $form.find(`[name="${this.filterInputField}"]`).val();
if (filterGroupsParam) {
......
......@@ -8,9 +8,9 @@ import {
import { toNumber, omit } from 'lodash';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { scrollToElement, historyPushState, getParameterByName } from '~/lib/utils/common_utils';
import { scrollToElement, historyPushState } from '~/lib/utils/common_utils';
// eslint-disable-next-line import/no-deprecated
import { setUrlParams, urlParamsToObject } from '~/lib/utils/url_utility';
import { setUrlParams, urlParamsToObject, getParameterByName } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import initManualOrdering from '~/manual_ordering';
import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
......@@ -78,10 +78,7 @@ export default {
isBulkEditing: false,
issuables: [],
loading: false,
page:
getParameterByName('page', window.location.href) !== null
? toNumber(getParameterByName('page'))
: 1,
page: getParameterByName('page') !== null ? toNumber(getParameterByName('page')) : 1,
selection: {},
totalItems: 0,
};
......
......@@ -50,8 +50,8 @@ import {
getSortOptions,
} from '~/issues_list/utils';
import axios from '~/lib/utils/axios_utils';
import { getParameterByName } from '~/lib/utils/common_utils';
import { scrollUp } from '~/lib/utils/scroll_utils';
import { getParameterByName } from '~/lib/utils/url_utility';
import {
DEFAULT_NONE_ANY,
OPERATOR_IS_ONLY,
......
......@@ -254,21 +254,6 @@ export const debounceByAnimationFrame = (fn) => {
};
};
/**
this will take in the `name` of the param you want to parse in the url
if the name does not exist this function will return `null`
otherwise it will return the value of the param key provided
*/
export const getParameterByName = (name, urlToParse) => {
const url = urlToParse || window.location.href;
const parsedName = name.replace(/[[\]]/g, '\\$&');
const regex = new RegExp(`[?&]${parsedName}(=([^&#]*)|&|#|$)`);
const results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
};
const handleSelectedRange = (range, restrictToNode) => {
// Make sure this range is within the restricting container
if (restrictToNode && !range.intersectsNode(restrictToNode)) return null;
......
......@@ -107,6 +107,25 @@ export function getParameterValues(sParam, url = window.location) {
}, []);
}
/**
* This function accepts the `name` of the param to parse in the url
* if the name does not exist this function will return `null`
* otherwise it will return the value of the param key provided
*
* @param {String} name
* @param {String?} urlToParse
* @returns value of the parameter as string
*/
export const getParameterByName = (name, urlToParse) => {
const url = urlToParse || window.location.href;
const parsedName = name.replace(/[[\]]/g, '\\$&');
const regex = new RegExp(`[?&]${parsedName}(=([^&#]*)|&|#|$)`);
const results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeUrlParameter(results[2]);
};
/**
* Merges a URL to a set of params replacing value for
* those already present.
......
<script>
import { GlFilteredSearchToken } from '@gitlab/ui';
import { mapState } from 'vuex';
import { getParameterByName } from '~/lib/utils/common_utils';
// eslint-disable-next-line import/no-deprecated
import { setUrlParams, urlParamsToObject } from '~/lib/utils/url_utility';
import { getParameterByName, setUrlParams, urlParamsToObject } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
import {
SEARCH_TOKEN_TYPE,
......
import { isUndefined } from 'lodash';
import { getParameterByName, convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { setUrlParams } from '~/lib/utils/url_utility';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { getParameterByName, setUrlParams } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import {
FIELDS,
......
import createFlash from '~/flash';
import { getParameterByName } from '~/lib/utils/common_utils';
import { initRails } from '~/lib/utils/rails_ujs';
import { getParameterByName } from '~/lib/utils/url_utility';
import { __, sprintf } from '~/locale';
const PARAMETER_NAME = 'leave';
......
import $ from 'jquery';
import 'vendor/jquery.endless-scroll';
import axios from '~/lib/utils/axios_utils';
import { getParameterByName } from '~/lib/utils/common_utils';
import { removeParams } from '~/lib/utils/url_utility';
import { removeParams, getParameterByName } from '~/lib/utils/url_utility';
const ENDLESS_SCROLL_BOTTOM_PX = 400;
const ENDLESS_SCROLL_FIRE_DELAY_MS = 1000;
......
......@@ -2,7 +2,7 @@
import { GlEmptyState, GlIcon, GlLoadingIcon } from '@gitlab/ui';
import { isEqual } from 'lodash';
import createFlash from '~/flash';
import { getParameterByName } from '~/lib/utils/common_utils';
import { getParameterByName } from '~/lib/utils/url_utility';
import { __, s__ } from '~/locale';
import NavigationTabs from '~/vue_shared/components/navigation_tabs.vue';
import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue';
......
<script>
import { GlButton, GlFormInput, GlFormGroup, GlSprintf } from '@gitlab/ui';
import { mapState, mapActions, mapGetters } from 'vuex';
import { getParameterByName } from '~/lib/utils/common_utils';
import { isSameOriginUrl } from '~/lib/utils/url_utility';
import { isSameOriginUrl, getParameterByName } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import MilestoneCombobox from '~/milestones/components/milestone_combobox.vue';
import { BACK_URL_PARAM } from '~/releases/constants';
......
<script>
import { GlEmptyState, GlLink, GlButton } from '@gitlab/ui';
import { mapState, mapActions } from 'vuex';
import { getParameterByName } from '~/lib/utils/common_utils';
import { getParameterByName } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import ReleaseBlock from './release_block.vue';
import ReleaseSkeletonLoader from './release_skeleton_loader.vue';
......
......@@ -2,9 +2,9 @@
import { GlButton } from '@gitlab/ui';
import allReleasesQuery from 'shared_queries/releases/all_releases.query.graphql';
import createFlash from '~/flash';
import { historyPushState, getParameterByName } from '~/lib/utils/common_utils';
import { historyPushState } from '~/lib/utils/common_utils';
import { scrollUp } from '~/lib/utils/scroll_utils';
import { setUrlParams } from '~/lib/utils/url_utility';
import { setUrlParams, getParameterByName } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import { PAGE_SIZE, DEFAULT_SORT } from '~/releases/constants';
import { convertAllReleasesGraphQLResponse } from '~/releases/util';
......
......@@ -3,12 +3,8 @@ import { GlBadge, GlButton } from '@gitlab/ui';
import { isEmpty } from 'lodash';
import { mapState, mapActions } from 'vuex';
import EmptyState from '~/feature_flags/components/empty_state.vue';
import {
buildUrlWithCurrentLocation,
getParameterByName,
historyPushState,
} from '~/lib/utils/common_utils';
import { objectToQuery } from '~/lib/utils/url_utility';
import { buildUrlWithCurrentLocation, historyPushState } from '~/lib/utils/common_utils';
import { objectToQuery, getParameterByName } from '~/lib/utils/url_utility';
import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue';
import UserListsTable from './user_lists_table.vue';
......
......@@ -12,8 +12,8 @@ import { createStore } from '~/boards/stores';
import { visitUrl } from '~/lib/utils/url_utility';
jest.mock('~/lib/utils/url_utility', () => ({
...jest.requireActual('~/lib/utils/url_utility'),
visitUrl: jest.fn().mockName('visitUrlMock'),
stripFinalUrlSegment: jest.requireActual('~/lib/utils/url_utility').stripFinalUrlSegment,
}));
const currentBoard = {
......
......@@ -4,11 +4,11 @@ import Cookies from 'js-cookie';
import Step from '~/code_quality_walkthrough/components/step.vue';
import { EXPERIMENT_NAME, STEPS } from '~/code_quality_walkthrough/constants';
import { TRACKING_CONTEXT_SCHEMA } from '~/experimentation/constants';
import { getParameterByName } from '~/lib/utils/common_utils';
import { getParameterByName } from '~/lib/utils/url_utility';
import Tracking from '~/tracking';
jest.mock('~/lib/utils/common_utils', () => ({
...jest.requireActual('~/lib/utils/common_utils'),
jest.mock('~/lib/utils/url_utility', () => ({
...jest.requireActual('~/lib/utils/url_utility'),
getParameterByName: jest.fn(),
}));
......
......@@ -8,7 +8,7 @@ import EmptyState from '~/environments/components/empty_state.vue';
import EnableReviewAppModal from '~/environments/components/enable_review_app_modal.vue';
import EnvironmentsApp from '~/environments/components/environments_app.vue';
import axios from '~/lib/utils/axios_utils';
import * as utils from '~/lib/utils/common_utils';
import * as urlUtils from '~/lib/utils/url_utility';
import { environment, folder } from './mock_data';
describe('Environment', () => {
......@@ -271,7 +271,7 @@ describe('Environment', () => {
beforeEach(() => {
mockRequest(200, { environments: [] });
jest
.spyOn(utils, 'getParameterByName')
.spyOn(urlUtils, 'getParameterByName')
.mockImplementation((param) => (param === 'scope' ? 'stopped' : null));
return createWrapper(true);
});
......
......@@ -9,13 +9,13 @@ import RecentSearchesRoot from '~/filtered_search/recent_searches_root';
import RecentSearchesService from '~/filtered_search/services/recent_searches_service';
import RecentSearchesServiceError from '~/filtered_search/services/recent_searches_service_error';
import createFlash from '~/flash';
import * as commonUtils from '~/lib/utils/common_utils';
import { BACKSPACE_KEY_CODE, DELETE_KEY_CODE } from '~/lib/utils/keycodes';
import { visitUrl } from '~/lib/utils/url_utility';
import { visitUrl, getParameterByName } from '~/lib/utils/url_utility';
jest.mock('~/flash');
jest.mock('~/lib/utils/url_utility', () => ({
...jest.requireActual('~/lib/utils/url_utility'),
getParameterByName: jest.fn(),
visitUrl: jest.fn(),
}));
......@@ -86,9 +86,10 @@ describe('Filtered Search Manager', () => {
jest
.spyOn(FilteredSearchDropdownManager.prototype, 'updateDropdownOffset')
.mockImplementation();
jest.spyOn(commonUtils, 'getParameterByName').mockReturnValue(null);
jest.spyOn(FilteredSearchVisualTokens, 'unselectTokens');
getParameterByName.mockReturnValue(null);
input = document.querySelector('.filtered-search');
tokensContainer = document.querySelector('.tokens-container');
manager = new FilteredSearchManager({ page, useDefaultState });
......
......@@ -247,39 +247,6 @@ describe('common_utils', () => {
});
});
describe('getParameterByName', () => {
beforeEach(() => {
window.history.pushState({}, null, '?scope=all&p=2');
});
afterEach(() => {
window.history.replaceState({}, null, null);
});
it('should return valid parameter', () => {
const value = commonUtils.getParameterByName('scope');
expect(commonUtils.getParameterByName('p')).toEqual('2');
expect(value).toBe('all');
});
it('should return invalid parameter', () => {
const value = commonUtils.getParameterByName('fakeParameter');
expect(value).toBe(null);
});
it('should return valid paramentes if URL is provided', () => {
let value = commonUtils.getParameterByName('foo', 'http://cocteau.twins/?foo=bar');
expect(value).toBe('bar');
value = commonUtils.getParameterByName('manan', 'http://cocteau.twins/?foo=bar&manan=canchu');
expect(value).toBe('canchu');
});
});
describe('normalizedHeaders', () => {
it('should upperCase all the header keys to keep them consistent', () => {
const apiHeaders = {
......
......@@ -24,6 +24,16 @@ const setWindowLocation = (value) => {
};
describe('URL utility', () => {
let originalLocation;
beforeAll(() => {
originalLocation = window.location;
});
afterAll(() => {
window.location = originalLocation;
});
describe('webIDEUrl', () => {
afterEach(() => {
gon.relative_url_root = '';
......@@ -91,6 +101,48 @@ describe('URL utility', () => {
});
});
describe('getParameterByName', () => {
const { getParameterByName } = urlUtils;
it('should return valid parameter', () => {
setWindowLocation({ href: 'https://gitlab.com?scope=all&p=2' });
expect(getParameterByName('p')).toEqual('2');
expect(getParameterByName('scope')).toBe('all');
});
it('should return invalid parameter', () => {
setWindowLocation({ href: 'https://gitlab.com?scope=all&p=2' });
expect(getParameterByName('fakeParameter')).toBe(null);
});
it('should return a parameter with spaces', () => {
setWindowLocation({ href: 'https://gitlab.com?search=my terms' });
expect(getParameterByName('search')).toBe('my terms');
});
it('should return a parameter with encoded spaces', () => {
setWindowLocation({ href: 'https://gitlab.com?search=my%20terms' });
expect(getParameterByName('search')).toBe('my terms');
});
it('should return a parameter with plus signs as spaces', () => {
setWindowLocation({ href: 'https://gitlab.com?search=my+terms' });
expect(getParameterByName('search')).toBe('my terms');
});
it('should return valid parameters if URL is provided', () => {
expect(getParameterByName('foo', 'http://cocteau.twins?foo=bar')).toBe('bar');
expect(getParameterByName('manan', 'http://cocteau.twins?foo=bar&manan=canchu')).toBe(
'canchu',
);
});
});
describe('mergeUrlParams', () => {
const { mergeUrlParams } = urlUtils;
......
......@@ -6,6 +6,7 @@ import { removeParams } from '~/lib/utils/url_utility';
import Pager from '~/pager';
jest.mock('~/lib/utils/url_utility', () => ({
...jest.requireActual('~/lib/utils/url_utility'),
removeParams: jest.fn().mockName('removeParams'),
}));
......
......@@ -21,10 +21,14 @@ jest.mock('~/flash');
let mockQueryParams;
jest.mock('~/lib/utils/common_utils', () => ({
...jest.requireActual('~/lib/utils/common_utils'),
historyPushState: jest.fn(),
}));
jest.mock('~/lib/utils/url_utility', () => ({
...jest.requireActual('~/lib/utils/url_utility'),
getParameterByName: jest
.fn()
.mockImplementation((parameterName) => mockQueryParams[parameterName]),
historyPushState: jest.fn(),
}));
describe('app_index_apollo_client.vue', () => {
......
......@@ -2,14 +2,14 @@ import { shallowMount } from '@vue/test-utils';
import { merge } from 'lodash';
import Vue from 'vue';
import Vuex from 'vuex';
import { getParameterByName } from '~/lib/utils/common_utils';
import { getParameterByName } from '~/lib/utils/url_utility';
import AppIndex from '~/releases/components/app_index.vue';
import ReleaseSkeletonLoader from '~/releases/components/release_skeleton_loader.vue';
import ReleasesPagination from '~/releases/components/releases_pagination.vue';
import ReleasesSort from '~/releases/components/releases_sort.vue';
jest.mock('~/lib/utils/common_utils', () => ({
...jest.requireActual('~/lib/utils/common_utils'),
jest.mock('~/lib/utils/url_utility', () => ({
...jest.requireActual('~/lib/utils/url_utility'),
getParameterByName: jest.fn(),
}));
......
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