signal-desktop/ts/test-both/util/url_test.ts

106 lines
3.4 KiB
TypeScript
Raw Normal View History

// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import { size } from '../../util/iterables';
import {
maybeParseUrl,
setUrlSearchParams,
urlPathFromComponents,
} from '../../util/url';
describe('URL utilities', () => {
describe('maybeParseUrl', () => {
it('parses valid URLs', () => {
[
'https://example.com',
'https://example.com:123/pathname?query=string#hash',
'file:///path/to/file.txt',
].forEach(href => {
assert.deepEqual(maybeParseUrl(href), new URL(href));
});
});
it('returns undefined for invalid URLs', () => {
['', 'example.com'].forEach(href => {
assert.isUndefined(maybeParseUrl(href));
});
});
it('handles non-strings for compatibility, returning undefined', () => {
[undefined, null, 123, ['https://example.com']].forEach(value => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
assert.isUndefined(maybeParseUrl(value as any));
});
});
});
describe('setUrlSearchParams', () => {
it('returns a new URL with updated search params', () => {
const params = {
normal_string: 'foo',
empty_string: '',
number: 123,
true_bool: true,
false_bool: false,
null_value: null,
undefined_value: undefined,
array: ['ok', 'wow'],
stringified: { toString: () => 'bar' },
};
const newUrl = setUrlSearchParams(
new URL('https://example.com/path?should_be=overwritten#hash'),
params
);
assert(newUrl.href.startsWith('https://example.com/path?'));
assert.strictEqual(newUrl.hash, '#hash');
assert.strictEqual(
size(newUrl.searchParams.entries()),
Object.keys(params).length
);
assert.strictEqual(newUrl.searchParams.get('normal_string'), 'foo');
assert.strictEqual(newUrl.searchParams.get('empty_string'), '');
assert.strictEqual(newUrl.searchParams.get('number'), '123');
assert.strictEqual(newUrl.searchParams.get('true_bool'), 'true');
assert.strictEqual(newUrl.searchParams.get('false_bool'), 'false');
assert.strictEqual(newUrl.searchParams.get('null_value'), '');
assert.strictEqual(newUrl.searchParams.get('undefined_value'), '');
assert.strictEqual(newUrl.searchParams.get('array'), 'ok,wow');
assert.strictEqual(newUrl.searchParams.get('stringified'), 'bar');
});
it("doesn't touch the original URL or its params", () => {
const originalHref = 'https://example.com/path?query=string';
const originalUrl = new URL(originalHref);
const params = { foo: 'bar' };
const newUrl = setUrlSearchParams(originalUrl, params);
assert.notStrictEqual(originalUrl, newUrl);
assert.strictEqual(originalUrl.href, originalHref);
params.foo = 'should be ignored';
assert.strictEqual(newUrl.search, '?foo=bar');
});
});
describe('urlPathFromComponents', () => {
it('returns / if no components are provided', () => {
assert.strictEqual(urlPathFromComponents([]), '/');
});
it('joins components, percent-encoding them and removing empty components', () => {
const components = ['foo', '', '~', 'bar / baz qúx'];
assert.strictEqual(
urlPathFromComponents(components),
'/foo/~/bar%20%2F%20baz%20q%C3%BAx'
);
});
});
});