172 lines
6.6 KiB
TypeScript
172 lines
6.6 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
import {describe, expect, it} from '@angular/core/testing/src/testing_internal';
|
|
import {URLSearchParams} from '../src/url_search_params';
|
|
|
|
export function main() {
|
|
describe('URLSearchParams', () => {
|
|
it('should conform to spec', () => {
|
|
const paramsString = 'q=URLUtils.searchParams&topic=api';
|
|
const searchParams = new URLSearchParams(paramsString);
|
|
|
|
// Tests borrowed from example at
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
|
|
// Compliant with spec described at https://url.spec.whatwg.org/#urlsearchparams
|
|
expect(searchParams.has('topic')).toBe(true);
|
|
expect(searchParams.has('foo')).toBe(false);
|
|
expect(searchParams.get('topic')).toEqual('api');
|
|
expect(searchParams.getAll('topic')).toEqual(['api']);
|
|
expect(searchParams.get('foo')).toBe(null);
|
|
searchParams.append('topic', 'webdev');
|
|
expect(searchParams.getAll('topic')).toEqual(['api', 'webdev']);
|
|
expect(searchParams.toString()).toEqual('q=URLUtils.searchParams&topic=api&topic=webdev');
|
|
searchParams.delete('topic');
|
|
expect(searchParams.toString()).toEqual('q=URLUtils.searchParams');
|
|
|
|
// Test default constructor
|
|
expect(new URLSearchParams().toString()).toBe('');
|
|
});
|
|
|
|
|
|
it('should optionally accept a custom parser', () => {
|
|
const fooEveryThingParser = {
|
|
encodeKey() { return 'I AM KEY'; },
|
|
encodeValue() { return 'I AM VALUE'; }
|
|
};
|
|
const params = new URLSearchParams('', fooEveryThingParser);
|
|
params.set('myKey', 'myValue');
|
|
expect(params.toString()).toBe('I AM KEY=I AM VALUE');
|
|
});
|
|
|
|
|
|
it('should encode special characters in params', () => {
|
|
const searchParams = new URLSearchParams();
|
|
searchParams.append('a', '1+1');
|
|
searchParams.append('b c', '2');
|
|
searchParams.append('d%', '3$');
|
|
expect(searchParams.toString()).toEqual('a=1+1&b%20c=2&d%25=3$');
|
|
});
|
|
|
|
|
|
it('should not encode allowed characters', () => {
|
|
/*
|
|
* https://tools.ietf.org/html/rfc3986#section-3.4
|
|
* Allowed: ( pchar / "/" / "?" )
|
|
* pchar: unreserved / pct-encoded / sub-delims / ":" / "@"
|
|
* unreserved: ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
* pct-encoded: "%" HEXDIG HEXDIG
|
|
* sub-delims: "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
|
*
|
|
* & and = are excluded and should be encoded inside keys and values
|
|
* because URLSearchParams is responsible for inserting this.
|
|
**/
|
|
|
|
let params = new URLSearchParams();
|
|
'! $ \' ( ) * + , ; A 9 - . _ ~ ? / ='.split(' ').forEach(
|
|
(char, idx) => { params.set(`a${idx}`, char); });
|
|
expect(params.toString())
|
|
.toBe(
|
|
`a0=!&a1=$&a2=\'&a3=(&a4=)&a5=*&a6=+&a7=,&a8=;&a9=A&a10=9&a11=-&a12=.&a13=_&a14=~&a15=?&a16=/&a17==`
|
|
.replace(/\s/g, ''));
|
|
|
|
|
|
// Original example from https://github.com/angular/angular/issues/9348 for posterity
|
|
params = new URLSearchParams();
|
|
params.set('q', 'repo:janbaer/howcani+type:issue');
|
|
params.set('sort', 'created');
|
|
params.set('order', 'desc');
|
|
params.set('page', '1');
|
|
expect(params.toString())
|
|
.toBe('q=repo:janbaer/howcani+type:issue&sort=created&order=desc&page=1');
|
|
});
|
|
|
|
|
|
it('should support map-like merging operation via setAll()', () => {
|
|
const mapA = new URLSearchParams('a=1&a=2&a=3&c=8');
|
|
const mapB = new URLSearchParams('a=4&a=5&a=6&b=7');
|
|
mapA.setAll(mapB);
|
|
expect(mapA.has('a')).toBe(true);
|
|
expect(mapA.has('b')).toBe(true);
|
|
expect(mapA.has('c')).toBe(true);
|
|
expect(mapA.getAll('a')).toEqual(['4']);
|
|
expect(mapA.getAll('b')).toEqual(['7']);
|
|
expect(mapA.getAll('c')).toEqual(['8']);
|
|
expect(mapA.toString()).toEqual('a=4&c=8&b=7');
|
|
});
|
|
|
|
|
|
it('should support multimap-like merging operation via appendAll()', () => {
|
|
const mapA = new URLSearchParams('a=1&a=2&a=3&c=8');
|
|
const mapB = new URLSearchParams('a=4&a=5&a=6&b=7');
|
|
mapA.appendAll(mapB);
|
|
expect(mapA.has('a')).toBe(true);
|
|
expect(mapA.has('b')).toBe(true);
|
|
expect(mapA.has('c')).toBe(true);
|
|
expect(mapA.getAll('a')).toEqual(['1', '2', '3', '4', '5', '6']);
|
|
expect(mapA.getAll('b')).toEqual(['7']);
|
|
expect(mapA.getAll('c')).toEqual(['8']);
|
|
expect(mapA.toString()).toEqual('a=1&a=2&a=3&a=4&a=5&a=6&c=8&b=7');
|
|
});
|
|
|
|
|
|
it('should support multimap-like merging operation via replaceAll()', () => {
|
|
const mapA = new URLSearchParams('a=1&a=2&a=3&c=8');
|
|
const mapB = new URLSearchParams('a=4&a=5&a=6&b=7');
|
|
mapA.replaceAll(mapB);
|
|
expect(mapA.has('a')).toBe(true);
|
|
expect(mapA.has('b')).toBe(true);
|
|
expect(mapA.has('c')).toBe(true);
|
|
expect(mapA.getAll('a')).toEqual(['4', '5', '6']);
|
|
expect(mapA.getAll('b')).toEqual(['7']);
|
|
expect(mapA.getAll('c')).toEqual(['8']);
|
|
expect(mapA.toString()).toEqual('a=4&a=5&a=6&c=8&b=7');
|
|
});
|
|
|
|
it('should support a clone operation via clone()', () => {
|
|
const fooQueryEncoder = {
|
|
encodeKey(k: string) { return encodeURIComponent(k); },
|
|
encodeValue(v: string) { return encodeURIComponent(v); }
|
|
};
|
|
const paramsA = new URLSearchParams('', fooQueryEncoder);
|
|
paramsA.set('a', '2');
|
|
paramsA.set('q', '4+');
|
|
paramsA.set('c', '8');
|
|
const paramsB = new URLSearchParams();
|
|
paramsB.set('a', '2');
|
|
paramsB.set('q', '4+');
|
|
paramsB.set('c', '8');
|
|
expect(paramsB.toString()).toEqual('a=2&q=4+&c=8');
|
|
const paramsC = paramsA.clone();
|
|
expect(paramsC.has('a')).toBe(true);
|
|
expect(paramsC.has('b')).toBe(false);
|
|
expect(paramsC.has('c')).toBe(true);
|
|
expect(paramsC.toString()).toEqual('a=2&q=4%2B&c=8');
|
|
});
|
|
|
|
it('should remove the parameter when set to undefined or null', () => {
|
|
const params = new URLSearchParams('q=Q');
|
|
params.set('q', undefined !);
|
|
expect(params.has('q')).toBe(false);
|
|
expect(params.toString()).toEqual('');
|
|
params.set('q', null !);
|
|
expect(params.has('q')).toBe(false);
|
|
expect(params.toString()).toEqual('');
|
|
});
|
|
|
|
it('should ignore the value when append undefined or null', () => {
|
|
const params = new URLSearchParams('q=Q');
|
|
params.append('q', undefined !);
|
|
expect(params.toString()).toEqual('q=Q');
|
|
params.append('q', null !);
|
|
expect(params.toString()).toEqual('q=Q');
|
|
});
|
|
|
|
});
|
|
}
|