mirror of
https://github.com/ansible/awx.git
synced 2026-01-13 11:00:03 -03:30
Merge pull request #4787 from keithjgrant/qs-util-cleanup
QS util cleanup Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
commit
86f8d648cc
@ -9,7 +9,8 @@ import FilterTags from '@components/FilterTags';
|
||||
import {
|
||||
encodeNonDefaultQueryString,
|
||||
parseQueryString,
|
||||
addParams,
|
||||
mergeParams,
|
||||
replaceParams,
|
||||
removeParams,
|
||||
} from '@util/qs';
|
||||
import { QSConfig } from '@types';
|
||||
@ -48,7 +49,7 @@ class ListHeader extends React.Component {
|
||||
const { history, qsConfig } = this.props;
|
||||
const { search } = history.location;
|
||||
const oldParams = parseQueryString(qsConfig, search);
|
||||
this.pushHistoryState(addParams(qsConfig, oldParams, { [key]: value }));
|
||||
this.pushHistoryState(mergeParams(oldParams, { [key]: value }));
|
||||
}
|
||||
|
||||
handleRemove(key, value) {
|
||||
@ -67,7 +68,7 @@ class ListHeader extends React.Component {
|
||||
const { search } = history.location;
|
||||
const oldParams = parseQueryString(qsConfig, search);
|
||||
this.pushHistoryState(
|
||||
addParams(qsConfig, oldParams, {
|
||||
replaceParams(oldParams, {
|
||||
order_by: order === 'ascending' ? key : `-${key}`,
|
||||
page: null,
|
||||
})
|
||||
|
||||
@ -15,7 +15,7 @@ import DataListToolbar from '@components/DataListToolbar';
|
||||
import {
|
||||
encodeNonDefaultQueryString,
|
||||
parseQueryString,
|
||||
addParams,
|
||||
replaceParams,
|
||||
} from '@util/qs';
|
||||
import { pluralize, ucFirst } from '@util/strings';
|
||||
|
||||
@ -34,16 +34,14 @@ class PaginatedDataList extends React.Component {
|
||||
const { history, qsConfig } = this.props;
|
||||
const { search } = history.location;
|
||||
const oldParams = parseQueryString(qsConfig, search);
|
||||
this.pushHistoryState(addParams(qsConfig, oldParams, { page: pageNumber }));
|
||||
this.pushHistoryState(replaceParams(oldParams, { page: pageNumber }));
|
||||
}
|
||||
|
||||
handleSetPageSize(event, pageSize) {
|
||||
const { history, qsConfig } = this.props;
|
||||
const { search } = history.location;
|
||||
const oldParams = parseQueryString(qsConfig, search);
|
||||
this.pushHistoryState(
|
||||
addParams(qsConfig, oldParams, { page_size: pageSize })
|
||||
);
|
||||
this.pushHistoryState(replaceParams(oldParams, { page_size: pageSize }));
|
||||
}
|
||||
|
||||
pushHistoryState(params) {
|
||||
|
||||
@ -1,156 +1,3 @@
|
||||
/**
|
||||
* helper function used to convert from
|
||||
* Object.entries format ([ [ key, value ], ... ]) to object
|
||||
* @param {array} array in the format [ [ key, value ], ...]
|
||||
* @return {object} object in the forms { key: value, ... }
|
||||
*/
|
||||
const toObject = entriesArr =>
|
||||
entriesArr.reduce((acc, [key, value]) => {
|
||||
if (acc[key] && Array.isArray(acc[key])) {
|
||||
acc[key].push(value);
|
||||
} else if (acc[key]) {
|
||||
acc[key] = [acc[key], value];
|
||||
} else {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
/**
|
||||
* helper function to namespace params object
|
||||
* @param {string} namespace to append to params
|
||||
* @param {object} params object to append namespace to
|
||||
* @return {object} params object with namespaced keys
|
||||
*/
|
||||
const namespaceParams = (namespace, params = {}) => {
|
||||
if (!namespace) return params;
|
||||
|
||||
const namespaced = {};
|
||||
Object.keys(params).forEach(key => {
|
||||
namespaced[`${namespace}.${key}`] = params[key];
|
||||
});
|
||||
|
||||
return namespaced || {};
|
||||
};
|
||||
|
||||
/**
|
||||
* helper function to remove namespace from params object
|
||||
* @param {string} namespace to remove from params
|
||||
* @param {object} params object to append namespace to
|
||||
* @return {object} params object with non-namespaced keys
|
||||
*/
|
||||
const denamespaceParams = (namespace, params = {}) => {
|
||||
if (!namespace) return params;
|
||||
|
||||
const denamespaced = {};
|
||||
Object.keys(params).forEach(key => {
|
||||
denamespaced[key.substr(namespace.length + 1)] = params[key];
|
||||
});
|
||||
|
||||
return denamespaced;
|
||||
};
|
||||
|
||||
/**
|
||||
* helper function to check the namespace of a param is what you expec
|
||||
* @param {string} namespace to append to params
|
||||
* @param {object} params object to append namespace to
|
||||
* @return {object} params object with namespaced keys
|
||||
*/
|
||||
const namespaceMatches = (namespace, fieldname) => {
|
||||
if (!namespace) return !fieldname.includes('.');
|
||||
|
||||
return fieldname.startsWith(`${namespace}.`);
|
||||
};
|
||||
|
||||
/**
|
||||
* helper function to check the value of a param is equal to another
|
||||
* @param {string or number or array} param value one
|
||||
* @param {string or number or array} params value two
|
||||
* @return {boolean} true if values are equal
|
||||
*/
|
||||
const paramValueIsEqual = (one, two) => {
|
||||
let isEqual = false;
|
||||
|
||||
if (Array.isArray(one) && Array.isArray(two)) {
|
||||
isEqual = one.filter(val => two.indexOf(val) > -1).length === 0;
|
||||
} else if (
|
||||
(typeof one === 'string' && typeof two === 'string') ||
|
||||
(typeof one === 'number' && typeof two === 'number')
|
||||
) {
|
||||
isEqual = one === two;
|
||||
}
|
||||
|
||||
return isEqual;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert query param object to url query string
|
||||
* Used to encode params for interacting with the api
|
||||
* @param {object} qs config object for namespacing params, filtering defaults
|
||||
* @param {object} query param object
|
||||
* @return {string} url query string
|
||||
*/
|
||||
export const encodeQueryString = params => {
|
||||
if (!params) return '';
|
||||
|
||||
return Object.keys(params)
|
||||
.sort()
|
||||
.filter(key => params[key] !== null)
|
||||
.map(key => [key, params[key]])
|
||||
.map(([key, value]) => {
|
||||
// if value is array, should return more than one key value pair
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
.map(val => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`)
|
||||
.join('&');
|
||||
}
|
||||
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
||||
})
|
||||
.join('&');
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert query param object to url query string, adding namespace and removing defaults
|
||||
* Used to put into url bar after ui route
|
||||
* @param {object} qs config object for namespacing params, filtering defaults
|
||||
* @param {object} query param object
|
||||
* @return {string} url query string
|
||||
*/
|
||||
export const encodeNonDefaultQueryString = (config, params) => {
|
||||
if (!params) return '';
|
||||
|
||||
const namespacedParams = namespaceParams(config.namespace, params);
|
||||
const namespacedDefaults = namespaceParams(
|
||||
config.namespace,
|
||||
config.defaultParams
|
||||
);
|
||||
const namespacedDefaultKeys = Object.keys(namespacedDefaults);
|
||||
const namespacedParamsWithoutDefaultsKeys = Object.keys(
|
||||
namespacedParams
|
||||
).filter(
|
||||
key =>
|
||||
namespacedDefaultKeys.indexOf(key) === -1 ||
|
||||
!paramValueIsEqual(namespacedParams[key], namespacedDefaults[key])
|
||||
);
|
||||
|
||||
return namespacedParamsWithoutDefaultsKeys
|
||||
.sort()
|
||||
.filter(key => namespacedParams[key] !== null)
|
||||
.map(key => {
|
||||
return [key, namespacedParams[key]];
|
||||
})
|
||||
.map(([key, value]) => {
|
||||
// if value is array, should return more than one key value pair
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
.map(val => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`)
|
||||
.join('&');
|
||||
}
|
||||
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
||||
})
|
||||
.join('&');
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns queryset config with defaults, if needed
|
||||
* @param {string} namespace for appending to url querystring
|
||||
@ -182,171 +29,119 @@ export function getQSConfig(
|
||||
* @return {object} query param object
|
||||
*/
|
||||
export function parseQueryString(config, queryString) {
|
||||
if (!queryString) return config.defaultParams;
|
||||
if (!queryString) {
|
||||
return config.defaultParams;
|
||||
}
|
||||
const params = stringToObject(config, queryString);
|
||||
return addDefaultsToObject(config, params);
|
||||
}
|
||||
|
||||
const namespacedIntegerFields = config.integerFields.map(f =>
|
||||
config.namespace ? `${config.namespace}.${f}` : f
|
||||
);
|
||||
|
||||
const keyValuePairs = queryString
|
||||
.replace(/^\?/, '')
|
||||
function stringToObject(config, qs) {
|
||||
const params = {};
|
||||
qs.replace(/^\?/, '')
|
||||
.split('&')
|
||||
.map(s => s.split('='))
|
||||
.map(([key, value]) => {
|
||||
if (namespacedIntegerFields.includes(key)) {
|
||||
return [decodeURIComponent(key), parseInt(value, 10)];
|
||||
.forEach(([nsKey, rawValue]) => {
|
||||
if (!nsKey || !namespaceMatches(config.namespace, nsKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return [decodeURIComponent(key), decodeURIComponent(value)];
|
||||
const key = config.namespace
|
||||
? decodeURIComponent(nsKey.substr(config.namespace.length + 1))
|
||||
: decodeURIComponent(nsKey);
|
||||
const value = parseValue(config, key, rawValue);
|
||||
params[key] = mergeParam(params[key], value);
|
||||
});
|
||||
return params;
|
||||
}
|
||||
export { stringToObject as _stringToObject };
|
||||
|
||||
const keyValueObject = toObject(keyValuePairs);
|
||||
/**
|
||||
* helper function to check the namespace of a param is what you expect
|
||||
* @param {string} namespace to append to params
|
||||
* @param {object} params object to append namespace to
|
||||
* @return {object} params object with namespaced keys
|
||||
*/
|
||||
const namespaceMatches = (namespace, fieldname) => {
|
||||
if (!namespace) return !fieldname.includes('.');
|
||||
|
||||
// needs to return array for duplicate keys
|
||||
// ie [[k1, v1], [k1, v2], [k2, v3]]
|
||||
// -> [[k1, [v1, v2]], [k2, v3]]
|
||||
const dedupedKeyValuePairs = Object.keys(keyValueObject).map(key => {
|
||||
const values = keyValuePairs.filter(([k]) => k === key).map(([, v]) => v);
|
||||
return fieldname.startsWith(`${namespace}.`);
|
||||
};
|
||||
|
||||
if (values.length === 1) {
|
||||
return [key, values[0]];
|
||||
}
|
||||
function parseValue(config, key, rawValue) {
|
||||
if (config.integerFields && config.integerFields.some(v => v === key)) {
|
||||
return parseInt(rawValue, 10);
|
||||
}
|
||||
// TODO: parse dateFields into date format?
|
||||
return decodeURIComponent(rawValue);
|
||||
}
|
||||
|
||||
return [key, values];
|
||||
});
|
||||
function addDefaultsToObject(config, params) {
|
||||
return {
|
||||
...config.defaultParams,
|
||||
...params,
|
||||
};
|
||||
}
|
||||
export { addDefaultsToObject as _addDefaultsToObject };
|
||||
|
||||
const parsed = Object.assign(
|
||||
...dedupedKeyValuePairs.map(([k, v]) => ({
|
||||
[k]: v,
|
||||
}))
|
||||
);
|
||||
/**
|
||||
* Convert query param object to url query string
|
||||
* Used to encode params for interacting with the api
|
||||
* @param {object} qs config object for namespacing params, filtering defaults
|
||||
* @param {object} query param object
|
||||
* @return {string} url query string
|
||||
*/
|
||||
export const encodeQueryString = params => {
|
||||
if (!params) return '';
|
||||
|
||||
const namespacedParams = {};
|
||||
return Object.keys(params)
|
||||
.sort()
|
||||
.filter(key => params[key] !== null)
|
||||
.map(key => [key, params[key]])
|
||||
.map(([key, value]) => encodeValue(key, value))
|
||||
.join('&');
|
||||
};
|
||||
|
||||
Object.keys(parsed).forEach(field => {
|
||||
if (namespaceMatches(config.namespace, field)) {
|
||||
let fieldname = field;
|
||||
if (config.namespace) {
|
||||
fieldname = field.substr(config.namespace.length + 1);
|
||||
}
|
||||
namespacedParams[fieldname] = parsed[field];
|
||||
}
|
||||
});
|
||||
|
||||
const namespacedDefaults = namespaceParams(
|
||||
config.namespace,
|
||||
config.defaultParams
|
||||
);
|
||||
|
||||
Object.keys(namespacedDefaults)
|
||||
.filter(key => Object.keys(parsed).indexOf(key) === -1)
|
||||
.forEach(field => {
|
||||
if (namespaceMatches(config.namespace, field)) {
|
||||
let fieldname = field;
|
||||
if (config.namespace) {
|
||||
fieldname = field.substr(config.namespace.length + 1);
|
||||
}
|
||||
namespacedParams[fieldname] = namespacedDefaults[field];
|
||||
}
|
||||
});
|
||||
|
||||
return namespacedParams;
|
||||
function encodeValue(key, value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
.map(val => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`)
|
||||
.join('&');
|
||||
}
|
||||
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* helper function to get params that are defaults
|
||||
* @param {object} namespaced params object
|
||||
* @param {object} namespaced params object of default params
|
||||
* @return {object} namespaced params object of only defaults
|
||||
* Convert query param object to url query string, adding namespace and
|
||||
* removing defaults. Used to put into url bar after ui route
|
||||
* @param {object} qs config object for namespacing params, filtering defaults
|
||||
* @param {object} query param object
|
||||
* @return {string} url query string
|
||||
*/
|
||||
const getDefaultParams = (params, defaults) =>
|
||||
toObject(
|
||||
Object.keys(params)
|
||||
.filter(key => Object.keys(defaults).indexOf(key) > -1)
|
||||
.map(key => [key, params[key]])
|
||||
export const encodeNonDefaultQueryString = (config, params) => {
|
||||
if (!params) return '';
|
||||
|
||||
const paramsWithoutDefaults = removeParams({}, params, config.defaultParams);
|
||||
return encodeQueryString(
|
||||
namespaceParams(config.namespace, paramsWithoutDefaults)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* helper function to get params that are not defaults
|
||||
* @param {object} namespaced params object
|
||||
* @param {object} namespaced params object of default params
|
||||
* @return {object} namespaced params object of non-defaults
|
||||
* helper function to namespace params object
|
||||
* @param {string} namespace to append to params
|
||||
* @param {object} params object to append namespace to
|
||||
* @return {object} params object with namespaced keys
|
||||
*/
|
||||
const getNonDefaultParams = (params, defaults) =>
|
||||
toObject(
|
||||
Object.keys(params)
|
||||
.filter(key => Object.keys(defaults).indexOf(key) === -1)
|
||||
.map(key => [key, params[key]])
|
||||
);
|
||||
const namespaceParams = (namespace, params) => {
|
||||
if (!namespace) return params;
|
||||
|
||||
/**
|
||||
* helper function to merge old and new params together
|
||||
* @param {object} namespaced params object old params with defaults filtered out
|
||||
* @param {object} namespaced params object of new params
|
||||
* @return {object} merged namespaced params object
|
||||
*/
|
||||
const getMergedParams = (oldParams, newParams) =>
|
||||
toObject(
|
||||
Object.keys(oldParams).map(key => {
|
||||
let oldVal = oldParams[key];
|
||||
const newVal = newParams[key];
|
||||
if (newVal) {
|
||||
if (Array.isArray(oldVal)) {
|
||||
oldVal.push(newVal);
|
||||
} else {
|
||||
oldVal = [oldVal, newVal];
|
||||
}
|
||||
}
|
||||
return [key, oldVal];
|
||||
})
|
||||
);
|
||||
|
||||
/**
|
||||
* helper function to get new params that are not in merged params
|
||||
* @param {object} namespaced params object of merged params
|
||||
* @param {object} namespaced params object of new params
|
||||
* @return {object} remaining new namespaced params object
|
||||
*/
|
||||
const getRemainingNewParams = (mergedParams, newParams) =>
|
||||
toObject(
|
||||
Object.keys(newParams)
|
||||
.filter(key => Object.keys(mergedParams).indexOf(key) === -1)
|
||||
.map(key => [key, newParams[key]])
|
||||
);
|
||||
|
||||
/**
|
||||
* Merges existing params of search string with new ones and returns the updated list of params
|
||||
* @param {object} qs config object (used for getting defaults, current query params etc.)
|
||||
* @param {object} object with params from existing search
|
||||
* @param {object} object with new params to add
|
||||
* @return {object} query param object
|
||||
*/
|
||||
export function addParams(config, oldParams, paramsToAdd) {
|
||||
const namespacedOldParams = namespaceParams(config.namespace, oldParams);
|
||||
const namespacedParamsToAdd = namespaceParams(config.namespace, paramsToAdd);
|
||||
const namespacedDefaultParams = namespaceParams(
|
||||
config.namespace,
|
||||
config.defaultParams
|
||||
);
|
||||
|
||||
const namespacedOldParamsNotDefaults = getNonDefaultParams(
|
||||
namespacedOldParams,
|
||||
namespacedDefaultParams
|
||||
);
|
||||
const namespacedMergedParams = getMergedParams(
|
||||
namespacedOldParamsNotDefaults,
|
||||
namespacedParamsToAdd
|
||||
);
|
||||
|
||||
// return updated params.
|
||||
// If newParams includes updates to the defaults, they will be replaced,
|
||||
// not concatenated.
|
||||
return denamespaceParams(config.namespace, {
|
||||
...getDefaultParams(namespacedOldParams, namespacedDefaultParams),
|
||||
...namespacedMergedParams,
|
||||
...getRemainingNewParams(namespacedMergedParams, namespacedParamsToAdd),
|
||||
const namespaced = {};
|
||||
Object.keys(params).forEach(key => {
|
||||
namespaced[`${namespace}.${key}`] = params[key];
|
||||
});
|
||||
}
|
||||
|
||||
return namespaced;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes params from the search string and returns the updated list of params
|
||||
@ -356,30 +151,90 @@ export function addParams(config, oldParams, paramsToAdd) {
|
||||
* @return {object} query param object
|
||||
*/
|
||||
export function removeParams(config, oldParams, paramsToRemove) {
|
||||
const paramsEntries = [];
|
||||
Object.entries(oldParams).forEach(([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach(val => {
|
||||
paramsEntries.push([key, val]);
|
||||
});
|
||||
} else {
|
||||
paramsEntries.push([key, value]);
|
||||
const updated = {
|
||||
...config.defaultParams,
|
||||
};
|
||||
Object.keys(oldParams).forEach(key => {
|
||||
const value = removeParam(oldParams[key], paramsToRemove[key]);
|
||||
if (value) {
|
||||
updated[key] = value;
|
||||
}
|
||||
});
|
||||
const paramsToRemoveEntries = Object.entries(paramsToRemove);
|
||||
const remainingEntries = paramsEntries.filter(
|
||||
([key, value]) =>
|
||||
paramsToRemoveEntries.filter(
|
||||
([newKey, newValue]) => key === newKey && value === newValue
|
||||
).length === 0
|
||||
);
|
||||
const remainingObject = toObject(remainingEntries);
|
||||
const defaultEntriesLeftover = Object.entries(config.defaultParams).filter(
|
||||
([key]) => !remainingObject[key]
|
||||
);
|
||||
const finalParamsEntries = remainingEntries;
|
||||
defaultEntriesLeftover.forEach(value => {
|
||||
finalParamsEntries.push(value);
|
||||
});
|
||||
return toObject(finalParamsEntries);
|
||||
return updated;
|
||||
}
|
||||
|
||||
function removeParam(oldVal, deleteVal) {
|
||||
if (oldVal === deleteVal) {
|
||||
return null;
|
||||
}
|
||||
if (Array.isArray(deleteVal)) {
|
||||
return deleteVal.reduce(removeParam, oldVal);
|
||||
}
|
||||
if (Array.isArray(oldVal)) {
|
||||
const index = oldVal.indexOf(deleteVal);
|
||||
if (index > -1) {
|
||||
oldVal.splice(index, 1);
|
||||
}
|
||||
if (oldVal.length === 1) {
|
||||
return oldVal[0];
|
||||
}
|
||||
}
|
||||
return oldVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge old and new params together, joining values into arrays where necessary
|
||||
* @param {object} namespaced params object of old params
|
||||
* @param {object} namespaced params object of new params
|
||||
* @return {object} merged namespaced params object
|
||||
*/
|
||||
export function mergeParams(oldParams, newParams) {
|
||||
const merged = {};
|
||||
Object.keys(oldParams).forEach(key => {
|
||||
merged[key] = mergeParam(oldParams[key], newParams[key]);
|
||||
});
|
||||
Object.keys(newParams).forEach(key => {
|
||||
if (!merged[key]) {
|
||||
merged[key] = newParams[key];
|
||||
}
|
||||
});
|
||||
return merged;
|
||||
}
|
||||
|
||||
function mergeParam(oldVal, newVal) {
|
||||
if (!newVal) {
|
||||
return oldVal;
|
||||
}
|
||||
if (!oldVal) {
|
||||
return newVal;
|
||||
}
|
||||
let merged;
|
||||
if (Array.isArray(oldVal)) {
|
||||
merged = oldVal.concat(newVal);
|
||||
} else {
|
||||
merged = [oldVal].concat(newVal);
|
||||
}
|
||||
return dedupeArray(merged);
|
||||
}
|
||||
|
||||
function dedupeArray(arr) {
|
||||
const deduped = [...new Set(arr)];
|
||||
if (deduped.length === 1) {
|
||||
return deduped[0];
|
||||
}
|
||||
return deduped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Join old and new params together, replacing old values with new ones where
|
||||
* necessary
|
||||
* @param {object} namespaced params object of old params
|
||||
* @param {object} namespaced params object of new params
|
||||
* @return {object} joined namespaced params object
|
||||
*/
|
||||
export function replaceParams(oldParams, newParams) {
|
||||
return {
|
||||
...oldParams,
|
||||
...newParams,
|
||||
};
|
||||
}
|
||||
|
||||
@ -3,8 +3,11 @@ import {
|
||||
encodeNonDefaultQueryString,
|
||||
parseQueryString,
|
||||
getQSConfig,
|
||||
addParams,
|
||||
removeParams,
|
||||
_stringToObject,
|
||||
_addDefaultsToObject,
|
||||
mergeParams,
|
||||
replaceParams,
|
||||
} from './qs';
|
||||
|
||||
describe('qs (qs.js)', () => {
|
||||
@ -35,6 +38,13 @@ describe('qs (qs.js)', () => {
|
||||
};
|
||||
expect(encodeQueryString(vals)).toEqual('order_by=name');
|
||||
});
|
||||
|
||||
test('should encode array params', () => {
|
||||
const vals = {
|
||||
foo: ['one', 'two', 'three'],
|
||||
};
|
||||
expect(encodeQueryString(vals)).toEqual('foo=one&foo=two&foo=three');
|
||||
});
|
||||
});
|
||||
|
||||
describe('encodeNonDefaultQueryString', () => {
|
||||
@ -44,7 +54,7 @@ describe('qs (qs.js)', () => {
|
||||
integerFields: ['page'],
|
||||
};
|
||||
|
||||
test('encodeNonDefaultQueryString returns the expected queryString', () => {
|
||||
test('should return the expected queryString', () => {
|
||||
[
|
||||
[null, ''],
|
||||
[{}, ''],
|
||||
@ -65,22 +75,49 @@ describe('qs (qs.js)', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('encodeNonDefaultQueryString omits null values', () => {
|
||||
test('should omit null values', () => {
|
||||
const vals = {
|
||||
order_by: 'foo',
|
||||
page: null,
|
||||
};
|
||||
expect(encodeNonDefaultQueryString(config, vals)).toEqual('order_by=foo');
|
||||
});
|
||||
|
||||
test('should namespace encoded params', () => {
|
||||
const conf = {
|
||||
namespace: 'item',
|
||||
defaultParams: { page: 1 },
|
||||
};
|
||||
const params = {
|
||||
page: 1,
|
||||
foo: 'bar',
|
||||
};
|
||||
expect(encodeNonDefaultQueryString(conf, params)).toEqual('item.foo=bar');
|
||||
});
|
||||
|
||||
test('should handle array values', () => {
|
||||
const vals = {
|
||||
foo: ['one', 'two'],
|
||||
bar: ['alpha', 'beta'],
|
||||
};
|
||||
const conf = {
|
||||
defaultParams: {
|
||||
foo: ['one', 'two'],
|
||||
},
|
||||
};
|
||||
expect(encodeNonDefaultQueryString(conf, vals)).toEqual(
|
||||
'bar=alpha&bar=beta'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getQSConfig', () => {
|
||||
test('should get default QS config object', () => {
|
||||
expect(getQSConfig('organization')).toEqual({
|
||||
namespace: 'organization',
|
||||
dateFields: ['modified', 'created'],
|
||||
defaultParams: { page: 1, page_size: 5, order_by: 'name' },
|
||||
integerFields: ['page', 'page_size'],
|
||||
dateFields: ['modified', 'created'],
|
||||
});
|
||||
});
|
||||
|
||||
@ -95,9 +132,9 @@ describe('qs (qs.js)', () => {
|
||||
};
|
||||
expect(getQSConfig('inventory', defaults)).toEqual({
|
||||
namespace: 'inventory',
|
||||
dateFields: ['modified', 'created'],
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
dateFields: ['modified', 'created'],
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -105,11 +142,11 @@ describe('qs (qs.js)', () => {
|
||||
describe('parseQueryString', () => {
|
||||
test('should get query params', () => {
|
||||
const config = {
|
||||
namespace: null,
|
||||
namespace: 'item',
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const query = '?baz=bar&page=3';
|
||||
const query = '?item.baz=bar&item.page=3';
|
||||
expect(parseQueryString(config, query)).toEqual({
|
||||
baz: 'bar',
|
||||
page: 3,
|
||||
@ -132,11 +169,11 @@ describe('qs (qs.js)', () => {
|
||||
|
||||
test('should get query params with correct integer fields', () => {
|
||||
const config = {
|
||||
namespace: null,
|
||||
namespace: 'item',
|
||||
defaultParams: {},
|
||||
integerFields: ['page', 'foo'],
|
||||
};
|
||||
const query = '?foo=4&bar=5';
|
||||
const query = '?item.foo=4&item.bar=5';
|
||||
expect(parseQueryString(config, query)).toEqual({
|
||||
foo: 4,
|
||||
bar: '5',
|
||||
@ -145,16 +182,28 @@ describe('qs (qs.js)', () => {
|
||||
|
||||
test('should decode parsed params', () => {
|
||||
const config = {
|
||||
namespace: null,
|
||||
namespace: 'item',
|
||||
defaultParams: {},
|
||||
integerFields: ['page'],
|
||||
};
|
||||
const query = '?foo=bar%20baz';
|
||||
const query = '?item.foo=bar%20baz';
|
||||
expect(parseQueryString(config, query)).toEqual({
|
||||
foo: 'bar baz',
|
||||
});
|
||||
});
|
||||
|
||||
test('should decode param keys', () => {
|
||||
const config = {
|
||||
namespace: 'item',
|
||||
defaultParams: {},
|
||||
integerFields: ['page'],
|
||||
};
|
||||
const query = '?item.foo%20bar=baz';
|
||||
expect(parseQueryString(config, query)).toEqual({
|
||||
'foo bar': 'baz',
|
||||
});
|
||||
});
|
||||
|
||||
test('should get namespaced query params', () => {
|
||||
const config = {
|
||||
namespace: 'inventory',
|
||||
@ -199,11 +248,11 @@ describe('qs (qs.js)', () => {
|
||||
|
||||
test('should add duplicate non-default params as array', () => {
|
||||
const config = {
|
||||
namespace: null,
|
||||
namespace: 'item',
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const query = '?baz=bar&baz=boo&page=3';
|
||||
const query = '?item.baz=bar&item.baz=boo&item.page=3';
|
||||
expect(parseQueryString(config, query)).toEqual({
|
||||
baz: ['bar', 'boo'],
|
||||
page: 3,
|
||||
@ -224,144 +273,25 @@ describe('qs (qs.js)', () => {
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('addParams', () => {
|
||||
test('should add query params', () => {
|
||||
test('should parse long arrays', () => {
|
||||
const config = {
|
||||
namespace: 'item',
|
||||
};
|
||||
const query = '?item.baz=one&item.baz=two&item.baz=three';
|
||||
expect(parseQueryString(config, query)).toEqual({
|
||||
baz: ['one', 'two', 'three'],
|
||||
});
|
||||
});
|
||||
|
||||
test('should handle non-namespaced params', () => {
|
||||
const config = {
|
||||
namespace: null,
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: 'bar', page: 3, page_size: 15 };
|
||||
const newParams = { bag: 'boom' };
|
||||
expect(addParams(config, oldParams, newParams)).toEqual({
|
||||
baz: 'bar',
|
||||
bag: 'boom',
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
|
||||
test('should add query params with duplicates', () => {
|
||||
const config = {
|
||||
namespace: null,
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: ['bar', 'bang'], page: 3, page_size: 15 };
|
||||
const newParams = { baz: 'boom' };
|
||||
expect(addParams(config, oldParams, newParams)).toEqual({
|
||||
baz: ['bar', 'bang', 'boom'],
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
|
||||
test('should replace query params that are defaults', () => {
|
||||
const config = {
|
||||
namespace: null,
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: ['bar', 'bang'], page: 3, page_size: 15 };
|
||||
const newParams = { page: 5 };
|
||||
expect(addParams(config, oldParams, newParams)).toEqual({
|
||||
baz: ['bar', 'bang'],
|
||||
page: 5,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
|
||||
test('should add multiple params', () => {
|
||||
const config = {
|
||||
namespace: null,
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: ['bar', 'bang'], page: 3, page_size: 15 };
|
||||
const newParams = { baz: 'bust', pat: 'pal' };
|
||||
expect(addParams(config, oldParams, newParams)).toEqual({
|
||||
baz: ['bar', 'bang', 'bust'],
|
||||
pat: 'pal',
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
|
||||
test('should add namespaced query params', () => {
|
||||
const config = {
|
||||
namespace: 'item',
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: 'bar', page: 3, page_size: 15 };
|
||||
const newParams = { bag: 'boom' };
|
||||
expect(addParams(config, oldParams, newParams)).toEqual({
|
||||
baz: 'bar',
|
||||
bag: 'boom',
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
|
||||
test('should not include other namespaced query params when adding', () => {
|
||||
const config = {
|
||||
namespace: 'item',
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: 'bar', page: 1, page_size: 15 };
|
||||
const newParams = { bag: 'boom' };
|
||||
expect(addParams(config, oldParams, newParams)).toEqual({
|
||||
baz: 'bar',
|
||||
bag: 'boom',
|
||||
page: 1,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
|
||||
test('should add namespaced query params with duplicates', () => {
|
||||
const config = {
|
||||
namespace: 'item',
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: ['bar', 'bang'], page: 3, page_size: 15 };
|
||||
const newParams = { baz: 'boom' };
|
||||
expect(addParams(config, oldParams, newParams)).toEqual({
|
||||
baz: ['bar', 'bang', 'boom'],
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
|
||||
test('should replace namespaced query params that are defaults', () => {
|
||||
const config = {
|
||||
namespace: 'item',
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: ['bar', 'bang'], page: 3, page_size: 15 };
|
||||
const newParams = { page: 5 };
|
||||
expect(addParams(config, oldParams, newParams)).toEqual({
|
||||
baz: ['bar', 'bang'],
|
||||
page: 5,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
|
||||
test('should add multiple namespaced params', () => {
|
||||
const config = {
|
||||
namespace: 'item',
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: ['bar', 'bang'], page: 3, page_size: 15 };
|
||||
const newParams = { baz: 'bust', pat: 'pal' };
|
||||
expect(addParams(config, oldParams, newParams)).toEqual({
|
||||
baz: ['bar', 'bang', 'bust'],
|
||||
pat: 'pal',
|
||||
const query = '?item.baz=bar&page=3';
|
||||
expect(parseQueryString(config, query)).toEqual({
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
});
|
||||
@ -376,8 +306,8 @@ describe('qs (qs.js)', () => {
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: 'bar', page: 3, bag: 'boom', page_size: 15 };
|
||||
const newParams = { bag: 'boom' };
|
||||
expect(removeParams(config, oldParams, newParams)).toEqual({
|
||||
const toRemove = { bag: 'boom' };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
baz: 'bar',
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
@ -391,8 +321,8 @@ describe('qs (qs.js)', () => {
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: ['bar', 'bang'], page: 3, page_size: 15 };
|
||||
const newParams = { baz: 'bar' };
|
||||
expect(removeParams(config, oldParams, newParams)).toEqual({
|
||||
const toRemove = { baz: 'bar' };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
baz: 'bang',
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
@ -410,14 +340,33 @@ describe('qs (qs.js)', () => {
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
};
|
||||
const newParams = { baz: 'bar' };
|
||||
expect(removeParams(config, oldParams, newParams)).toEqual({
|
||||
const toRemove = { baz: 'bar' };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
baz: ['bang', 'bust'],
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
|
||||
test('should remove multiple values from query params (array -> smaller array)', () => {
|
||||
const config = {
|
||||
namespace: null,
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = {
|
||||
baz: ['bar', 'bang', 'bust'],
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
};
|
||||
const toRemove = { baz: ['bang', 'bar'] };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
baz: 'bust',
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
|
||||
test('should reset query params that have default keys back to default values', () => {
|
||||
const config = {
|
||||
namespace: null,
|
||||
@ -425,8 +374,8 @@ describe('qs (qs.js)', () => {
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: ['bar', 'bang'], page: 3, page_size: 15 };
|
||||
const newParams = { page: 3 };
|
||||
expect(removeParams(config, oldParams, newParams)).toEqual({
|
||||
const toRemove = { page: 3 };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
baz: ['bar', 'bang'],
|
||||
page: 1,
|
||||
page_size: 15,
|
||||
@ -445,8 +394,8 @@ describe('qs (qs.js)', () => {
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
};
|
||||
const newParams = { baz: 'bust', pat: 'pal' };
|
||||
expect(removeParams(config, oldParams, newParams)).toEqual({
|
||||
const toRemove = { baz: 'bust', pat: 'pal' };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
baz: ['bar', 'bang'],
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
@ -460,8 +409,8 @@ describe('qs (qs.js)', () => {
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: 'bar', page: 3, page_size: 15 };
|
||||
const newParams = { baz: 'bar' };
|
||||
expect(removeParams(config, oldParams, newParams)).toEqual({
|
||||
const toRemove = { baz: 'bar' };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
});
|
||||
@ -474,8 +423,8 @@ describe('qs (qs.js)', () => {
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: 'bar', page: 1, page_size: 15 };
|
||||
const newParams = { baz: 'bar' };
|
||||
expect(removeParams(config, oldParams, newParams)).toEqual({
|
||||
const toRemove = { baz: 'bar' };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
page: 1,
|
||||
page_size: 15,
|
||||
});
|
||||
@ -488,8 +437,8 @@ describe('qs (qs.js)', () => {
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: ['bar', 'bang'], page: 3, page_size: 15 };
|
||||
const newParams = { baz: 'bar' };
|
||||
expect(removeParams(config, oldParams, newParams)).toEqual({
|
||||
const toRemove = { baz: 'bar' };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
baz: 'bang',
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
@ -507,8 +456,8 @@ describe('qs (qs.js)', () => {
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
};
|
||||
const newParams = { baz: 'bar' };
|
||||
expect(removeParams(config, oldParams, newParams)).toEqual({
|
||||
const toRemove = { baz: 'bar' };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
baz: ['bang', 'bust'],
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
@ -522,14 +471,34 @@ describe('qs (qs.js)', () => {
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = { baz: ['bar', 'bang'], page: 3, page_size: 15 };
|
||||
const newParams = { page: 3 };
|
||||
expect(removeParams(config, oldParams, newParams)).toEqual({
|
||||
const toRemove = { page: 3 };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
baz: ['bar', 'bang'],
|
||||
page: 1,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
|
||||
test('should retain long array values', () => {
|
||||
const config = {
|
||||
namespace: 'item',
|
||||
defaultParams: { page: 1, page_size: 15 },
|
||||
integerFields: ['page', 'page_size'],
|
||||
};
|
||||
const oldParams = {
|
||||
baz: ['one', 'two', 'three'],
|
||||
page: 3,
|
||||
bag: 'boom',
|
||||
page_size: 15,
|
||||
};
|
||||
const toRemove = { bag: 'boom' };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
baz: ['one', 'two', 'three'],
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
|
||||
test('should remove multiple namespaced params', () => {
|
||||
const config = {
|
||||
namespace: 'item',
|
||||
@ -542,12 +511,237 @@ describe('qs (qs.js)', () => {
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
};
|
||||
const newParams = { baz: 'bust', pat: 'pal' };
|
||||
expect(removeParams(config, oldParams, newParams)).toEqual({
|
||||
const toRemove = { baz: 'bust', pat: 'pal' };
|
||||
expect(removeParams(config, oldParams, toRemove)).toEqual({
|
||||
baz: ['bar', 'bang'],
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('_stringToObject', () => {
|
||||
test('should convert to object', () => {
|
||||
const config = { namespace: 'unit' };
|
||||
expect(_stringToObject(config, '?unit.foo=bar&unit.baz=bam')).toEqual({
|
||||
foo: 'bar',
|
||||
baz: 'bam',
|
||||
});
|
||||
});
|
||||
|
||||
test('should convert duplicated keys to array', () => {
|
||||
const config = { namespace: 'unit' };
|
||||
expect(_stringToObject(config, '?unit.foo=bar&unit.foo=bam')).toEqual({
|
||||
foo: ['bar', 'bam'],
|
||||
});
|
||||
});
|
||||
|
||||
test('should omit keys from other namespaces', () => {
|
||||
const config = { namespace: 'unit' };
|
||||
expect(
|
||||
_stringToObject(config, '?unit.foo=bar&other.bar=bam&one=two')
|
||||
).toEqual({
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
|
||||
test('should convert numbers to correct type', () => {
|
||||
const config = {
|
||||
namespace: 'unit',
|
||||
integerFields: ['page'],
|
||||
};
|
||||
expect(_stringToObject(config, '?unit.page=3')).toEqual({
|
||||
page: 3,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('_addDefaultsToObject', () => {
|
||||
test('should add missing default values', () => {
|
||||
const config = {
|
||||
defaultParams: { page: 1, page_size: 5, order_by: 'name' },
|
||||
};
|
||||
expect(_addDefaultsToObject(config, {})).toEqual({
|
||||
page: 1,
|
||||
page_size: 5,
|
||||
order_by: 'name',
|
||||
});
|
||||
});
|
||||
|
||||
test('should not override existing params', () => {
|
||||
const config = {
|
||||
defaultParams: { page: 1, page_size: 5, order_by: 'name' },
|
||||
};
|
||||
const params = {
|
||||
page: 2,
|
||||
order_by: 'date_created',
|
||||
};
|
||||
expect(_addDefaultsToObject(config, params)).toEqual({
|
||||
page: 2,
|
||||
page_size: 5,
|
||||
order_by: 'date_created',
|
||||
});
|
||||
});
|
||||
|
||||
test('should handle missing defaultParams', () => {
|
||||
const params = {
|
||||
page: 2,
|
||||
order_by: 'date_created',
|
||||
};
|
||||
expect(_addDefaultsToObject({}, params)).toEqual({
|
||||
page: 2,
|
||||
order_by: 'date_created',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mergeParams', () => {
|
||||
it('should merge param into an array', () => {
|
||||
const oldParams = {
|
||||
foo: 'one',
|
||||
};
|
||||
const newParams = {
|
||||
foo: 'two',
|
||||
};
|
||||
expect(mergeParams(oldParams, newParams)).toEqual({
|
||||
foo: ['one', 'two'],
|
||||
});
|
||||
});
|
||||
|
||||
it('should retain unaltered params', () => {
|
||||
const oldParams = {
|
||||
foo: 'one',
|
||||
bar: 'baz',
|
||||
};
|
||||
const newParams = {
|
||||
foo: 'two',
|
||||
};
|
||||
expect(mergeParams(oldParams, newParams)).toEqual({
|
||||
foo: ['one', 'two'],
|
||||
bar: 'baz',
|
||||
});
|
||||
});
|
||||
|
||||
it('should gather params from both objects', () => {
|
||||
const oldParams = {
|
||||
one: 'one',
|
||||
};
|
||||
const newParams = {
|
||||
two: 'two',
|
||||
};
|
||||
expect(mergeParams(oldParams, newParams)).toEqual({
|
||||
one: 'one',
|
||||
two: 'two',
|
||||
});
|
||||
});
|
||||
|
||||
it('should append value to existing array', () => {
|
||||
const oldParams = {
|
||||
foo: ['one', 'two'],
|
||||
};
|
||||
const newParams = {
|
||||
foo: 'three',
|
||||
};
|
||||
expect(mergeParams(oldParams, newParams)).toEqual({
|
||||
foo: ['one', 'two', 'three'],
|
||||
});
|
||||
});
|
||||
|
||||
it('should append array to existing value', () => {
|
||||
const oldParams = {
|
||||
foo: 'one',
|
||||
};
|
||||
const newParams = {
|
||||
foo: ['two', 'three'],
|
||||
};
|
||||
expect(mergeParams(oldParams, newParams)).toEqual({
|
||||
foo: ['one', 'two', 'three'],
|
||||
});
|
||||
});
|
||||
|
||||
it('should merge two arrays', () => {
|
||||
const oldParams = {
|
||||
foo: ['one', 'two'],
|
||||
};
|
||||
const newParams = {
|
||||
foo: ['three', 'four'],
|
||||
};
|
||||
expect(mergeParams(oldParams, newParams)).toEqual({
|
||||
foo: ['one', 'two', 'three', 'four'],
|
||||
});
|
||||
});
|
||||
|
||||
it('should prevent exact duplicates', () => {
|
||||
const oldParams = { foo: 'one' };
|
||||
const newParams = { foo: 'one' };
|
||||
expect(mergeParams(oldParams, newParams)).toEqual({ foo: 'one' });
|
||||
});
|
||||
|
||||
it('should prevent exact duplicates in arrays', () => {
|
||||
const oldParams = { foo: ['one', 'three'] };
|
||||
const newParams = { foo: ['one', 'two'] };
|
||||
expect(mergeParams(oldParams, newParams)).toEqual({
|
||||
foo: ['one', 'three', 'two'],
|
||||
});
|
||||
});
|
||||
|
||||
it('should add multiple params', () => {
|
||||
const oldParams = { baz: ['bar', 'bang'], page: 3, page_size: 15 };
|
||||
const newParams = { baz: 'bust', pat: 'pal' };
|
||||
expect(mergeParams(oldParams, newParams)).toEqual({
|
||||
baz: ['bar', 'bang', 'bust'],
|
||||
pat: 'pal',
|
||||
page: 3,
|
||||
page_size: 15,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('replaceParams', () => {
|
||||
it('should collect params into one object', () => {
|
||||
const oldParams = { foo: 'one' };
|
||||
const newParams = { bar: 'two' };
|
||||
expect(replaceParams(oldParams, newParams)).toEqual({
|
||||
foo: 'one',
|
||||
bar: 'two',
|
||||
});
|
||||
});
|
||||
|
||||
it('should retain unaltered params', () => {
|
||||
const oldParams = {
|
||||
foo: 'one',
|
||||
bar: 'baz',
|
||||
};
|
||||
const newParams = { foo: 'two' };
|
||||
expect(replaceParams(oldParams, newParams)).toEqual({
|
||||
foo: 'two',
|
||||
bar: 'baz',
|
||||
});
|
||||
});
|
||||
|
||||
it('should override old values with new ones', () => {
|
||||
const oldParams = {
|
||||
foo: 'one',
|
||||
bar: 'three',
|
||||
};
|
||||
const newParams = {
|
||||
foo: 'two',
|
||||
baz: 'four',
|
||||
};
|
||||
expect(replaceParams(oldParams, newParams)).toEqual({
|
||||
foo: 'two',
|
||||
bar: 'three',
|
||||
baz: 'four',
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle exact duplicates', () => {
|
||||
const oldParams = { foo: 'one' };
|
||||
const newParams = { foo: 'one', bar: 'two' };
|
||||
expect(replaceParams(oldParams, newParams)).toEqual({
|
||||
foo: 'one',
|
||||
bar: 'two',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user