tridactyl/src/url_util.test.ts
2018-04-13 19:28:03 +01:00

328 lines
9.8 KiB
TypeScript

/** Some tests for URL utilities */
import * as UrlUtil from "./url_util"
function test_increment() {
let cases = [
// simple increment
[1, "http://example.com/item/1", "http://example.com/item/2"],
// test non-1 increment
[2, "http://example.com/item/1", "http://example.com/item/3"],
// test negative
[-1, "http://example.com/item/3", "http://example.com/item/2"],
// test other numbers unaffected
[1, "http://www1.example.com/1", "http://www1.example.com/2"],
// test numbers as part of words work
[1, "http://example.com/book1", "http://example.com/book2"],
// test urls with no incrementable parts return null
[1, "http://example.com", null],
]
for (let [step, input, output] of cases) {
test(`${input} + ${step} --> ${output}`, () =>
expect(UrlUtil.incrementUrl(input, step)).toEqual(output))
}
}
function test_root() {
let cases = [
// simple URL
["http://example.com/dir/page.html", "http://example.com/"],
// already root, with subdir
["http://www.example.com/", "http://www.example.com/"],
// unsupported protocol
["about:config", null],
]
for (let [url, exp_root] of cases) {
let root = UrlUtil.getUrlRoot(new URL(url))
test(`root of ${url} --> ${exp_root}`, () =>
expect(root ? root.href : root).toEqual(exp_root))
}
}
function test_parent() {
let cases = [
// root URL, nothing to do!
["http://example.com", null],
// URL with query string
["http://example.com?key=value", "http://example.com/"],
// url with hash/anchor - strip the fragment
["http://example.com#anchor", "http://example.com/"],
// query + hash: lose the hash only
["http://example.com?key=val#hash", "http://example.com/?key=val"],
// single level path
["http://example.com/path", "http://example.com/"],
// multi-level path
["http://example.com/path1/path2", "http://example.com/path1/"],
[
"http://example.com/path1/path2/path3",
"http://example.com/path1/path2/",
],
// subdomains
["http://sub.example.com", "http://example.com/"],
// subdom with path, leave subdom
["http://sub.example.com/path", "http://sub.example.com/"],
// trailing slash
["http://sub.example.com/path/", "http://sub.example.com/"],
["http://sub.example.com/path/to/", "http://sub.example.com/path/"],
// repeated slash
["http://example.com/path//", "http://example.com/"],
["http://example.com//path//", "http://example.com//"],
["http://example.com//path//", "http://example.com//"],
]
for (let [url, exp_parent] of cases) {
let parent = UrlUtil.getUrlParent(new URL(url))
test(`parent of ${url} --> ${exp_parent}`, () =>
expect(parent ? parent.href : parent).toEqual(exp_parent))
}
}
function test_download_filename() {
let cases = [
// simple domain only
["http://example.com", "example.com"],
["http://example.com/", "example.com"],
["http://sub.example.com/", "sub.example.com"],
// simple paths
["http://example.com/path", "path"],
["http://example.com/path.ext", "path.ext"],
["http://example.com/path/more", "more"],
// ends in /
["http://example.com/path/", "path"],
// ignore query strings
["http://example.com/page?q=v", "page"],
["http://example.com/page/?q=v", "page"],
// Data urls
// base 64 with mime
["data:image/png;base64,dat", "base64-dat.png"],
[
"data:image/png;base64,data/data/data/data",
"base64-data_data_data_.png",
],
// non-base64
["data:image/png,dat", "dat.png"],
// unknown mime
["data:something/wierd,data", "data"],
]
for (let [url, exp_fn] of cases) {
let fn = UrlUtil.getDownloadFilenameForUrl(new URL(url))
test(`filename for ${url} --> ${exp_fn}`, () =>
expect(fn).toEqual(exp_fn))
}
}
function test_query_delete() {
let cases = [
// no query
["http://example.com/", "query", "http://example.com/"],
// single query=val, removed
["http://example.com/?query=val", "query", "http://example.com/"],
// single query (no val), removed
["http://example.com/?query", "query", "http://example.com/"],
// single query=val, not removed
[
"http://example.com/?query=val",
"nomatch",
"http://example.com/?query=val",
],
// single query (no val), not removed
["http://example.com/?query", "nomatch", "http://example.com/?query"],
// multiple queries, first removed
[
"http://example.com/?query=val&another=val2",
"query",
"http://example.com/?another=val2",
],
// multiple queries, second removed
[
"http://example.com/?query=val&another=val2",
"another",
"http://example.com/?query=val",
],
// multiple queries, repeated removed
[
"http://example.com/?query=val&another=val2&query=val3",
"query",
"http://example.com/?another=val2",
],
]
for (let [url, q, exp_res] of cases) {
let modified = UrlUtil.deleteQuery(new URL(url), q)
test(`delete query ${q} of ${url} --> ${exp_res}`, () =>
expect(modified.href).toEqual(exp_res))
}
}
function test_query_replace() {
let cases = [
// no query
["http://example.com/", "query", "val", "http://example.com/"],
// single query
[
"http://example.com/?query=val",
"query",
"newval",
"http://example.com/?query=newval",
],
// single query, no replacement value
[
"http://example.com/?query=val",
"query",
"",
"http://example.com/?query",
],
// multiple, replace first
[
"http://example.com/?query1=val1&query2=val2",
"query1",
"newval1",
"http://example.com/?query1=newval1&query2=val2",
],
// multiple, replace last
[
"http://example.com/?query1=val1&query2=val2",
"query2",
"newval2",
"http://example.com/?query1=val1&query2=newval2",
],
]
for (let [url, q, v, exp_res] of cases) {
let modified = UrlUtil.replaceQueryValue(new URL(url), q, v)
test(`change query ${q} of ${url} --> ${exp_res}`, () =>
expect(modified.href).toEqual(exp_res))
}
}
function test_url_graft_path() {
let cases = [
// FROM LEFT
[
// complete replacement
"http://example.com/foo/bar/quux",
"0",
"frob",
"http://example.com/frob",
],
[
// one level down
"http://example.com/foo/bar/quux",
"1",
"frob",
"http://example.com/foo/frob",
],
[
// at last level
"http://example.com/foo/bar/quux",
"3",
"frob",
"http://example.com/foo/bar/quux/frob",
],
// FROM RIGHT
[
// test of extend-only
"http://example.com/test",
"-1",
"newchild",
"http://example.com/test/newchild",
],
[
// test of one level up graft (i.e. sibling)
"http://example.com/test",
"-2",
"newsibling",
"http://example.com/newsibling",
],
[
// test of multi level up graft (i.e. cousin)
"http://example.com/shop/by-id/42",
"-3",
"by-name/foobar",
"http://example.com/shop/by-name/foobar",
],
// ERRORS
[
// test of level too large and positive
"http://example.com/foo",
"2",
"dummy",
null,
],
[
// test of level too large and negative
"http://example.com/foo",
"-3",
"dummy",
null,
],
]
for (let [url, level, tail, exp_res] of cases) {
let modified = UrlUtil.graftUrlPath(new URL(url), tail, Number(level))
test(`graft ${tail} onto ${url} at level ${level} --> ${exp_res}`, () =>
expect(modified ? modified.href : modified).toEqual(exp_res))
}
}
function test_url_query_interpolation() {
let cases = [
[
// not percent-encoded and appended
"http://example.com",
"a/query",
"http://example.com/a/query",
],
[
// not percent-encoded and interpolated
"http://example.com/%s/path",
"a/query",
"http://example.com/a/query/path",
],
[
// percent-encoded and appended
"http://example.com/?query=",
"a/query",
"http://example.com/?query=a%2Fquery",
],
[
// percent-encoded and interpolated
"http://example.com/?query=%s&q2=v2",
"a/query",
"http://example.com/?query=a%2Fquery&q2=v2",
],
]
for (let [url, qy, exp_res] of cases) {
let modified = UrlUtil.interpolateSearchItem(new URL(url), qy)
test(`interpolate ${qy} into ${url} --> ${exp_res}`, () =>
expect(modified.href).toEqual(exp_res))
}
}
test_increment()
test_root()
test_parent()
test_download_filename()
test_query_delete()
test_query_replace()
test_url_graft_path()
test_url_query_interpolation()