mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
78991: Clean up SearchOptions.toRestUrl
* Extract "selective encoding" ops into separate methods * Add comments to clarify regex * Use hasValue() instead of just checking on 'match' * Leave only the last comma of filter values unencoded
This commit is contained in:
@@ -10,10 +10,10 @@ describe('PaginatedSearchOptions', () => {
|
|||||||
const pageOptions = Object.assign(new PaginationComponentOptions(), { pageSize: 40, page: 1 });
|
const pageOptions = Object.assign(new PaginationComponentOptions(), { pageSize: 40, page: 1 });
|
||||||
const filters = [
|
const filters = [
|
||||||
new SearchFilter('f.test', ['value']),
|
new SearchFilter('f.test', ['value']),
|
||||||
new SearchFilter('f.example', ['another value', 'second value']),
|
new SearchFilter('f.example', ['another value', 'second value']), // should be split into two arguments, spaces should be URI-encoded
|
||||||
new SearchFilter('f.range', ['[2002 TO 2021]'], 'equals'),
|
new SearchFilter('f.range', ['[2002 TO 2021]'], 'equals'), // value should be URI-encoded, ',equals' should not
|
||||||
];
|
];
|
||||||
const fixedFilter = 'f.fixed=1234 5678,equals';
|
const fixedFilter = 'f.fixed=1234,5678,equals'; // '=' and ',equals' should not be URI-encoded
|
||||||
const query = 'search query';
|
const query = 'search query';
|
||||||
const scope = '0fde1ecb-82cc-425a-b600-ac3576d76b47';
|
const scope = '0fde1ecb-82cc-425a-b600-ac3576d76b47';
|
||||||
const baseUrl = 'www.rest.com';
|
const baseUrl = 'www.rest.com';
|
||||||
@@ -37,7 +37,7 @@ describe('PaginatedSearchOptions', () => {
|
|||||||
'sort=test.field,DESC&' +
|
'sort=test.field,DESC&' +
|
||||||
'page=0&' +
|
'page=0&' +
|
||||||
'size=40&' +
|
'size=40&' +
|
||||||
'f.fixed=1234%205678,equals&' +
|
'f.fixed=1234%2C5678,equals&' +
|
||||||
'query=search%20query&' +
|
'query=search%20query&' +
|
||||||
'scope=0fde1ecb-82cc-425a-b600-ac3576d76b47&' +
|
'scope=0fde1ecb-82cc-425a-b600-ac3576d76b47&' +
|
||||||
'dsoType=ITEM&' +
|
'dsoType=ITEM&' +
|
||||||
|
@@ -8,10 +8,10 @@ describe('SearchOptions', () => {
|
|||||||
|
|
||||||
const filters = [
|
const filters = [
|
||||||
new SearchFilter('f.test', ['value']),
|
new SearchFilter('f.test', ['value']),
|
||||||
new SearchFilter('f.example', ['another value', 'second value']),
|
new SearchFilter('f.example', ['another value', 'second value']), // should be split into two arguments, spaces should be URI-encoded
|
||||||
new SearchFilter('f.range', ['[2002 TO 2021]'], 'equals'),
|
new SearchFilter('f.range', ['[2002 TO 2021]'], 'equals'), // value should be URI-encoded, ',equals' should not
|
||||||
];
|
];
|
||||||
const fixedFilter = 'f.fixed=1234 5678,equals';
|
const fixedFilter = 'f.fixed=1234,5678,equals'; // '=' and ',equals' should not be URI-encoded
|
||||||
const query = 'search query';
|
const query = 'search query';
|
||||||
const scope = '0fde1ecb-82cc-425a-b600-ac3576d76b47';
|
const scope = '0fde1ecb-82cc-425a-b600-ac3576d76b47';
|
||||||
const baseUrl = 'www.rest.com';
|
const baseUrl = 'www.rest.com';
|
||||||
@@ -30,7 +30,7 @@ describe('SearchOptions', () => {
|
|||||||
it('should generate a string with all parameters that are present', () => {
|
it('should generate a string with all parameters that are present', () => {
|
||||||
const outcome = options.toRestUrl(baseUrl);
|
const outcome = options.toRestUrl(baseUrl);
|
||||||
expect(outcome).toEqual('www.rest.com?' +
|
expect(outcome).toEqual('www.rest.com?' +
|
||||||
'f.fixed=1234%205678,equals&' +
|
'f.fixed=1234%2C5678,equals&' +
|
||||||
'query=search%20query&' +
|
'query=search%20query&' +
|
||||||
'scope=0fde1ecb-82cc-425a-b600-ac3576d76b47&' +
|
'scope=0fde1ecb-82cc-425a-b600-ac3576d76b47&' +
|
||||||
'dsoType=ITEM&' +
|
'dsoType=ITEM&' +
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { isNotEmpty } from '../empty.util';
|
import { hasValue, isNotEmpty } from '../empty.util';
|
||||||
import { URLCombiner } from '../../core/url-combiner/url-combiner';
|
import { URLCombiner } from '../../core/url-combiner/url-combiner';
|
||||||
import { SearchFilter } from './search-filter.model';
|
import { SearchFilter } from './search-filter.model';
|
||||||
import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model';
|
import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model';
|
||||||
@@ -41,16 +41,7 @@ export class SearchOptions {
|
|||||||
args.push(`configuration=${encodeURIComponent(this.configuration)}`);
|
args.push(`configuration=${encodeURIComponent(this.configuration)}`);
|
||||||
}
|
}
|
||||||
if (isNotEmpty(this.fixedFilter)) {
|
if (isNotEmpty(this.fixedFilter)) {
|
||||||
let fixedFilter: string;
|
args.push(this.encodedFixedFilter);
|
||||||
const match = this.fixedFilter.match(/^([^=]+=)(.+)$/);
|
|
||||||
|
|
||||||
if (match) {
|
|
||||||
fixedFilter = match[1] + encodeURIComponent(match[2]).replace(/%2C/g, ',');
|
|
||||||
} else {
|
|
||||||
fixedFilter = encodeURIComponent(this.fixedFilter);
|
|
||||||
}
|
|
||||||
|
|
||||||
args.push(fixedFilter);
|
|
||||||
}
|
}
|
||||||
if (isNotEmpty(this.query)) {
|
if (isNotEmpty(this.query)) {
|
||||||
args.push(`query=${encodeURIComponent(this.query)}`);
|
args.push(`query=${encodeURIComponent(this.query)}`);
|
||||||
@@ -67,9 +58,7 @@ export class SearchOptions {
|
|||||||
this.filters.forEach((filter: SearchFilter) => {
|
this.filters.forEach((filter: SearchFilter) => {
|
||||||
filter.values.forEach((value) => {
|
filter.values.forEach((value) => {
|
||||||
const filterValue = value.includes(',') ? `${value}` : value + (filter.operator ? ',' + filter.operator : '');
|
const filterValue = value.includes(',') ? `${value}` : value + (filter.operator ? ',' + filter.operator : '');
|
||||||
|
args.push(`${filter.key}=${this.encodeFilterQueryValue(filterValue)}`);
|
||||||
// we don't want commas to get URI-encoded
|
|
||||||
args.push(`${filter.key}=${encodeURIComponent(filterValue).replace(/%2C/g, ',')}`);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -78,4 +67,28 @@ export class SearchOptions {
|
|||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get encodedFixedFilter(): string {
|
||||||
|
// expected format: 'arg=value'
|
||||||
|
// -> split the query agument into (arg=)(value) and only encode 'value'
|
||||||
|
const match = this.fixedFilter.match(/^([^=]+=)(.+)$/);
|
||||||
|
|
||||||
|
if (hasValue(match)) {
|
||||||
|
return match[1] + this.encodeFilterQueryValue(match[2]);
|
||||||
|
} else {
|
||||||
|
return this.encodeFilterQueryValue(this.fixedFilter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
encodeFilterQueryValue(filterQueryValue: string): string {
|
||||||
|
// expected format: 'value' or 'value,operator'
|
||||||
|
// -> split into (value)(,operator) and only encode 'value'
|
||||||
|
const match = filterQueryValue.match(/^(.*)(,\w+)$/);
|
||||||
|
|
||||||
|
if (hasValue(match)) {
|
||||||
|
return encodeURIComponent(match[1]) + match[2];
|
||||||
|
} else {
|
||||||
|
return encodeURIComponent(filterQueryValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user