Skip to content

Commit

Permalink
test(smartredirects): add tests for the meat of the code
Browse files Browse the repository at this point in the history
  • Loading branch information
trieloff committed Oct 14, 2024
1 parent a2eacf2 commit 449387b
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 10 deletions.
27 changes: 17 additions & 10 deletions scripts/redirects.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function activateRedirects(data) {
replacements.shift();
const result = v.replace(/(\$\d+|\*)/g, (matched) => {
if (matched.startsWith('$')) {
return replacements[matched.slice(1)];
return replacements[matched.slice(1) - 1];
}
if (matched === '*') {
return replacements.shift();
Expand All @@ -39,24 +39,31 @@ export async function fetchRedirects(path = '/smart-redirects.json') {
return [];
}

export async function applyRedirects(
redirects = fetchRedirects(),
path = window.location.pathname,
) {
export async function getRedirect(redirects, path, currentURL) {
const redirect = (await redirects)
.filter((r) => typeof r.start === 'undefined' || r.start.getTime() <= Date.now())
.find((r) => r.from.test(path));
if (redirect) {
const target = redirect.to(path, ...redirect.from.exec(path).slice(1));
const currentUrl = new URL(window.location.href);
const targetURL = new URL(target, currentUrl.origin);
// Copy all URL parameters from currentUrl to targetURL
currentUrl.searchParams.forEach((value, key) => {
const targetURL = new URL(target, currentURL.origin);
// Copy all URL parameters from currentURL to targetURL
currentURL.searchParams.forEach((value, key) => {
targetURL.searchParams.set(key, value);
});

targetURL.searchParams.set('redirect_from', path);
window.location.replace(targetURL.toString());
return targetURL.toString();
}
return null;
}

export async function applyRedirects(
redirects = fetchRedirects(),
path = window.location.pathname,
) {
const redirect = await getRedirect(redirects, path, window.location.href);
if (redirect) {
window.location.replace(redirect);
}
return path;
}
71 changes: 71 additions & 0 deletions tests/scripts/redirects.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { expect } from '@esm-bundle/chai';
import { readFile } from '@web/test-runner-commands';
import { activateRedirects, getRedirect } from '../../scripts/redirects.js';
/* eslint-env mocha */

document.body.innerHTML = await readFile({ path: './dummy.html' });
document.head.innerHTML = await readFile({ path: './head.html' });

describe.only('Redirects', () => {
it('loads redirects', async () => {
const emptyRedirects = [];
const redirects = await activateRedirects(emptyRedirects);
expect(redirects).to.deep.equal(emptyRedirects);
});

it('applies applies a simple redirect', async () => {
const exampleRedirects = [
{
from: '/foo',
to: '/bar',
start: 1,
},
];
const redirects = await activateRedirects(exampleRedirects);
const currentURL = new URL('https://example.com/foo');
const redirect = await getRedirect(redirects, '/foo', currentURL);
expect(redirect).to.equal('https://example.com/bar?redirect_from=%2Ffoo');
});

it('applies applies a redirect with a parameter', async () => {
const exampleRedirects = [
{
from: '/foo/*',
to: '/bar/*',
start: 1,
},
];
const redirects = await activateRedirects(exampleRedirects);
const currentURL = new URL('https://example.com/foo/baz');
const redirect = await getRedirect(redirects, '/foo/baz', currentURL);
expect(redirect).to.equal('https://example.com/bar/baz?redirect_from=%2Ffoo%2Fbaz');
});

it('applies applies a redirect with multiple parameters', async () => {
const exampleRedirects = [
{
from: '/foo/*/*',
to: '/bar/*/baz/*',
start: 1,
},
];
const redirects = await activateRedirects(exampleRedirects);
const currentURL = new URL('https://example.com/foo/fifi/qux');
const redirect = await getRedirect(redirects, '/foo/fifi/qux', currentURL);
expect(redirect).to.equal('https://example.com/bar/fifi/baz/qux?redirect_from=%2Ffoo%2Ffifi%2Fqux');
});

it('applies applies a redirect with multiple parameters and changed order', async () => {
const exampleRedirects = [
{
from: '/foo/*/*',
to: '/bar/$2/baz/$1',
start: 1,
},
];
const redirects = await activateRedirects(exampleRedirects);
const currentURL = new URL('https://example.com/foo/fifi/qux');
const redirect = await getRedirect(redirects, '/foo/fifi/qux', currentURL);
expect(redirect).to.equal('https://example.com/bar/qux/baz/fifi?redirect_from=%2Ffoo%2Ffifi%2Fqux');
});
});

0 comments on commit 449387b

Please sign in to comment.