diff --git a/source/redirect/base.ts b/source/redirect/base.ts new file mode 100644 index 0000000..376199b --- /dev/null +++ b/source/redirect/base.ts @@ -0,0 +1,9 @@ +import {HostnameParameters} from './hostname.js'; + +export type RedirectParameters = HostnameParameters; + +export abstract class Redirect

{ + constructor(public parameters: P) {} + + public abstract redirect(url: URL | string): URL; +} diff --git a/source/redirect/exports.ts b/source/redirect/exports.ts new file mode 100644 index 0000000..0b5e5f2 --- /dev/null +++ b/source/redirect/exports.ts @@ -0,0 +1,15 @@ +import {RedirectParameters} from './base.js'; +import {HostnameRedirect} from './hostname.js'; + +export * from './base.js'; +export * from './hostname.js'; + +export type Redirects = HostnameRedirect; + +export function parseRedirect

( + parameters: P, +): Redirects | undefined { + if (parameters.type === 'hostname') { + return new HostnameRedirect(parameters); + } +} diff --git a/source/redirect/hostname.ts b/source/redirect/hostname.ts new file mode 100644 index 0000000..2c7245a --- /dev/null +++ b/source/redirect/hostname.ts @@ -0,0 +1,14 @@ +import {Redirect} from './base.js'; + +export type HostnameParameters = { + hostname: string; + type: 'hostname'; +}; + +export class HostnameRedirect extends Redirect { + public redirect(url: URL | string): URL { + const redirected = new URL(url); + redirected.hostname = this.parameters.hostname; + return redirected; + } +} diff --git a/tests/redirect.test.ts b/tests/redirect.test.ts new file mode 100644 index 0000000..ae7b89b --- /dev/null +++ b/tests/redirect.test.ts @@ -0,0 +1,54 @@ +/// + +import test from 'ava'; + +import { + parseRedirect, + HostnameRedirect, + Redirect, + RedirectParameters, +} from '../source/redirect/exports.js'; + +test('parseRedirect', (t) => { + const samples: RedirectParameters[] = [ + { + test: 'Invalid parameters', + } as unknown as RedirectParameters, + { + hostname: 'example.org', + type: 'hostname', + }, + ]; + + for (const sample of samples) { + const redirect = parseRedirect(sample); + + if (redirect === undefined) { + t.pass('parseRedirect returned undefined'); + } else { + t.snapshot(redirect, `Class ${redirect.constructor.name}`); + } + } +}); + +test('Redirect.redirect', (t) => { + const hostnameRedirect = new HostnameRedirect({ + hostname: 'example.org', + type: 'hostname', + }); + + const samples: Array<[string, Redirect]> = [ + ['https://example.com', hostnameRedirect], + ['https://example.com/path#hash?query=test', hostnameRedirect], + ]; + + for (const [index, [url, redirect]] of samples.entries()) { + t.snapshot( + { + original: url, + redirected: redirect.redirect(url).href, + }, + `${index} ${redirect.constructor.name}`, + ); + } +}); diff --git a/tests/snapshots/tests/redirect.test.ts.md b/tests/snapshots/tests/redirect.test.ts.md new file mode 100644 index 0000000..0cb63b1 --- /dev/null +++ b/tests/snapshots/tests/redirect.test.ts.md @@ -0,0 +1,32 @@ +# Snapshot report for `tests/redirect.test.ts` + +The actual snapshot is saved in `redirect.test.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## parseRedirect + +> Class HostnameRedirect + + HostnameRedirect { + parameters: { + hostname: 'example.org', + type: 'hostname', + }, + } + +## Redirect.redirect + +> 0 HostnameRedirect + + { + original: 'https://example.com', + redirected: 'https://example.org/', + } + +> 1 HostnameRedirect + + { + original: 'https://example.com/path#hash?query=test', + redirected: 'https://example.org/path#hash?query=test', + } diff --git a/tests/snapshots/tests/redirect.test.ts.snap b/tests/snapshots/tests/redirect.test.ts.snap new file mode 100644 index 0000000..57ab73d Binary files /dev/null and b/tests/snapshots/tests/redirect.test.ts.snap differ