Commit 3f016fe7 authored by Simon Knox's avatar Simon Knox

move similar querystring parsing functions to common utils

parent 91795547
<script>
/* global ListIssue */
import queryData from '~/boards/utils/query_data';
import { urlParamsToObject } from '~/lib/utils/common_utils';
import loadingIcon from '~/vue_shared/components/loading_icon.vue';
import ModalHeader from './header.vue';
import ModalList from './list.vue';
......@@ -111,10 +111,13 @@
return gl.boardService
.getBacklog(
queryData(this.filter.path, {
page: this.page,
per: this.perPage,
}),
Object.assign(
urlParamsToObject(this.filter.path),
{
page: this.page,
per: this.perPage,
},
),
)
.then(res => res.data)
.then(data => {
......
......@@ -3,7 +3,7 @@
import ListLabel from '~/vue_shared/models/label';
import ListAssignee from '~/vue_shared/models/assignee';
import queryData from '../utils/query_data';
import { urlParamsToObject } from '~/lib/utils/common_utils';
import ListMilestone from './milestone';
const PER_PAGE = 20;
......@@ -120,7 +120,10 @@ class List {
}
getIssues(emptyIssues = true) {
const data = queryData(gl.issueBoards.BoardsStore.filter.path, { page: this.page });
const data = Object.assign(
urlParamsToObject(gl.issueBoards.BoardsStore.filter.path),
{ page: this.page },
);
if (this.label && data.label_name) {
data.label_name = data.label_name.filter(label => label !== this.label.title);
......
export default (path, extraData) => path.split('&').reduce((dataParam, filterParam) => {
if (filterParam === '') return dataParam;
const data = dataParam;
const paramSplit = filterParam.split('=');
const paramKeyNormalized = paramSplit[0].replace('[]', '');
const isArray = paramSplit[0].indexOf('[]');
const value = decodeURIComponent(paramSplit[1].replace(/\+/g, ' '));
if (isArray !== -1) {
if (!data[paramKeyNormalized]) {
data[paramKeyNormalized] = [];
}
data[paramKeyNormalized].push(value);
} else {
data[paramKeyNormalized] = value;
}
return data;
}, extraData);
......@@ -132,17 +132,42 @@ export const parseUrlPathname = url => {
return parsedUrl.pathname.charAt(0) === '/' ? parsedUrl.pathname : `/${parsedUrl.pathname}`;
};
// We can trust that each param has one & since values containing & will be encoded
// Remove the first character of search as it is always ?
export const getUrlParamsArray = () =>
window.location.search
.slice(1)
export const urlParamsToArray = (path = '') => {
return path
.slice(1) // Remove the first character of search as it is always ?
.split('&')
.filter(param => param.length > 0)
.map(param => {
const split = param.split('=');
return [decodeURI(split[0]), split[1]].join('=');
});
};
export const getUrlParamsArray = () => urlParamsToArray(window.location.search);
export const urlParamsToObject = (path = '') => {
return path.split('&').reduce((dataParam, filterParam) => {
if (filterParam === '') return dataParam;
const data = dataParam;
const paramSplit = filterParam.split('=');
const paramKeyNormalized = paramSplit[0].replace('[]', '');
const isArray = paramSplit[0].indexOf('[]');
const value = decodeURIComponent(paramSplit[1].replace(/\+/g, ' '));
if (isArray !== -1) {
if (!data[paramKeyNormalized]) {
data[paramKeyNormalized] = [];
}
data[paramKeyNormalized].push(value);
} else {
data[paramKeyNormalized] = value;
}
return data;
}, {});
};
export const isMetaKey = e => e.metaKey || e.ctrlKey || e.altKey || e.shiftKey;
......
......@@ -34,7 +34,7 @@ export const listObjDuplicate = {
export const BoardsMockData = {
GET: {
'/test/-/boards/1/lists/300/issues?id=300&page=1&=': {
'/test/-/boards/1/lists/300/issues?id=300&page=1': {
issues: [
{
title: 'Testing',
......
import queryData from '~/boards/utils/query_data';
describe('queryData', () => {
it('parses path for label with trailing +', () => {
expect(
queryData('label_name[]=label%2B', {}),
).toEqual({
label_name: ['label+'],
});
});
it('parses path for milestone with trailing +', () => {
expect(
queryData('milestone_title=A%2B', {}),
).toEqual({
milestone_title: 'A+',
});
});
it('parses path for search terms with spaces', () => {
expect(
queryData('search=two+words', {}),
).toEqual({
search: 'two words',
});
});
});
......@@ -29,26 +29,46 @@ describe('common_utils', () => {
});
});
describe('getUrlParamsArray', () => {
describe('urlParamsToArray', () => {
it('returns empty array for empty querystring', () => {
expect(commonUtils.urlParamsToArray('')).toEqual([]);
});
it('should decode params', () => {
expect(
commonUtils.getUrlParamsArray()
).toEqual([]);
commonUtils.urlParamsToArray('?label_name%5B%5D=test')[0],
).toBe('label_name[]=test');
});
it('should remove the question mark from the search params', () => {
const paramsArray = commonUtils.getUrlParamsArray();
const paramsArray = commonUtils.urlParamsToArray('?test=thing');
expect(paramsArray[0][0] !== '?').toBe(true);
});
});
it('should decode params', () => {
window.history.pushState('', '', '?label_name%5B%5D=test');
describe('urlParamsToObject', () => {
it('parses path for label with trailing +', () => {
expect(
commonUtils.urlParamsToObject('label_name[]=label%2B', {}),
).toEqual({
label_name: ['label+'],
});
});
it('parses path for milestone with trailing +', () => {
expect(
commonUtils.getUrlParamsArray()[0],
).toBe('label_name[]=test');
commonUtils.urlParamsToObject('milestone_title=A%2B', {}),
).toEqual({
milestone_title: 'A+',
});
});
window.history.pushState('', '', '?');
it('parses path for search terms with spaces', () => {
expect(
commonUtils.urlParamsToObject('search=two+words', {}),
).toEqual({
search: 'two words',
});
});
});
......
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