Normalise the search param for comparison to avoid endless redirections (https://github.com/woocommerce/woocommerce-blocks/pull/8784)
* Replace single quote with the encoded version %27 for URL comparison This is required as as removeQueryArgs() function uses decodeURIcomponent method which doesn't encode single quotes (') while it was still encoded in the original URL (%27). So when the single quote was in a query param, for example as a search term, it caused endless redirection loop. * Replace single quote with the encoded version %27 for URL comparison in Filter by Rating * refactor the solution so it encodes the href rather than decode the newly created URL * Refactor the normalisation * Add tests to normalisation function
This commit is contained in:
parent
f29954abbc
commit
a06f4fbd91
|
@ -26,7 +26,7 @@ import FilterSubmitButton from '@woocommerce/base-components/filter-submit-butto
|
|||
import FilterResetButton from '@woocommerce/base-components/filter-reset-button';
|
||||
import FormTokenField from '@woocommerce/base-components/form-token-field';
|
||||
import { addQueryArgs, removeQueryArgs } from '@wordpress/url';
|
||||
import { changeUrl } from '@woocommerce/utils';
|
||||
import { changeUrl, normalizeQueryParams } from '@woocommerce/utils';
|
||||
import classnames from 'classnames';
|
||||
import { difference } from 'lodash';
|
||||
import type { ReactElement } from 'react';
|
||||
|
@ -144,7 +144,7 @@ const RatingFilterBlock = ( {
|
|||
QUERY_PARAM_KEY
|
||||
);
|
||||
|
||||
if ( url !== window.location.href ) {
|
||||
if ( url !== normalizeQueryParams( window.location.href ) ) {
|
||||
changeUrl( url );
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ const RatingFilterBlock = ( {
|
|||
[ QUERY_PARAM_KEY ]: checkedRatings.join( ',' ),
|
||||
} );
|
||||
|
||||
if ( newUrl === window.location.href ) {
|
||||
if ( newUrl === normalizeQueryParams( window.location.href ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,11 @@ import isShallowEqual from '@wordpress/is-shallow-equal';
|
|||
import { decodeEntities } from '@wordpress/html-entities';
|
||||
import { isBoolean, objectHasProp } from '@woocommerce/types';
|
||||
import { addQueryArgs, removeQueryArgs } from '@wordpress/url';
|
||||
import { changeUrl, PREFIX_QUERY_ARG_FILTER_TYPE } from '@woocommerce/utils';
|
||||
import {
|
||||
changeUrl,
|
||||
PREFIX_QUERY_ARG_FILTER_TYPE,
|
||||
normalizeQueryParams,
|
||||
} from '@woocommerce/utils';
|
||||
import { difference } from 'lodash';
|
||||
import classnames from 'classnames';
|
||||
|
||||
|
@ -224,7 +228,7 @@ const StockStatusFilterBlock = ( {
|
|||
QUERY_PARAM_KEY
|
||||
);
|
||||
|
||||
if ( url !== window.location.href ) {
|
||||
if ( url !== normalizeQueryParams( window.location.href ) ) {
|
||||
changeUrl( url );
|
||||
}
|
||||
|
||||
|
@ -235,7 +239,7 @@ const StockStatusFilterBlock = ( {
|
|||
[ QUERY_PARAM_KEY ]: checkedOptions.join( ',' ),
|
||||
} );
|
||||
|
||||
if ( newUrl === window.location.href ) {
|
||||
if ( newUrl === normalizeQueryParams( window.location.href ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { getQueryArg } from '@wordpress/url';
|
||||
import { getQueryArg, getQueryArgs, addQueryArgs } from '@wordpress/url';
|
||||
import { getSettingWithCoercion } from '@woocommerce/settings';
|
||||
import { isBoolean } from '@woocommerce/types';
|
||||
|
||||
|
@ -39,3 +39,13 @@ export function changeUrl( newUrl: string ) {
|
|||
window.history.replaceState( {}, '', newUrl );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the query params through buildQueryString to normalise the params.
|
||||
*
|
||||
* @param {string} url URL to encode the search param from.
|
||||
*/
|
||||
export const normalizeQueryParams = ( url: string ) => {
|
||||
const queryArgs = getQueryArgs( url );
|
||||
return addQueryArgs( url, queryArgs );
|
||||
};
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { normalizeQueryParams } from '../filters';
|
||||
|
||||
describe( 'normalizeQueryParams', () => {
|
||||
test( 'does not change url if there is no query params', () => {
|
||||
const input = 'https://example.com';
|
||||
const expected = 'https://example.com';
|
||||
|
||||
expect( normalizeQueryParams( input ) ).toBe( expected );
|
||||
} );
|
||||
|
||||
test( 'does not change search term if there is no special character', () => {
|
||||
const input = 'https://example.com?foo=bar&s=asdf1234&baz=qux';
|
||||
const expected = 'https://example.com?foo=bar&s=asdf1234&baz=qux';
|
||||
|
||||
expect( normalizeQueryParams( input ) ).toBe( expected );
|
||||
} );
|
||||
|
||||
test( 'decodes single quote characters', () => {
|
||||
const input = 'https://example.com?foo=bar%27&s=asd%27f1234&baz=qux%27';
|
||||
const expected = "https://example.com?foo=bar'&s=asd'f1234&baz=qux'";
|
||||
|
||||
expect( normalizeQueryParams( input ) ).toBe( expected );
|
||||
} );
|
||||
} );
|
Loading…
Reference in New Issue