Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Filter by Stock and Filter by Rating: Fix the potential endless redirection loop when used on a search results page #8784

Merged
merged 5 commits into from
Mar 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions assets/js/blocks/rating-filter/block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -144,7 +144,7 @@ const RatingFilterBlock = ( {
QUERY_PARAM_KEY
);

if ( url !== window.location.href ) {
if ( url !== normalizeQueryParams( window.location.href ) ) {
changeUrl( url );
}

Expand All @@ -155,7 +155,7 @@ const RatingFilterBlock = ( {
[ QUERY_PARAM_KEY ]: checkedRatings.join( ',' ),
} );

if ( newUrl === window.location.href ) {
if ( newUrl === normalizeQueryParams( window.location.href ) ) {
return;
}

Expand Down
10 changes: 7 additions & 3 deletions assets/js/blocks/stock-filter/block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -224,7 +228,7 @@ const StockStatusFilterBlock = ( {
QUERY_PARAM_KEY
);

if ( url !== window.location.href ) {
if ( url !== normalizeQueryParams( window.location.href ) ) {
changeUrl( url );
}

Expand All @@ -235,7 +239,7 @@ const StockStatusFilterBlock = ( {
[ QUERY_PARAM_KEY ]: checkedOptions.join( ',' ),
} );

if ( newUrl === window.location.href ) {
if ( newUrl === normalizeQueryParams( window.location.href ) ) {
return;
}

Expand Down
12 changes: 11 additions & 1 deletion assets/js/utils/filters.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -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 );
};
27 changes: 27 additions & 0 deletions assets/js/utils/test/filters.js
Original file line number Diff line number Diff line change
@@ -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 );
} );
} );