Merged in feature/BOOK-401-handle-new-redirects-part-2 (pull request #2944)

feat(BOOK-401): Add support for new-url -> new-url in the redirect-service

* Switch to typescript

* add new dependencies for tests and typescript

* Switch to typescript

* add new dependencies for tests and typescript

* rewrite to typescript and include tests

* rewrite to typescript and include tests

* refactor: update README and scripts for CSV handling; rename update script to generate

* include csv-data folder

* feat(BOOK-401): Add support for new-url -> new-url in the redirect-service

* Add errors when given unsupported URLs

* merge


Approved-by: Linus Flood
This commit is contained in:
Joakim Jäderberg
2025-10-10 07:51:47 +00:00
parent c84d686d9d
commit f3f75e8ece
2 changed files with 93 additions and 1 deletions

View File

@@ -1,6 +1,23 @@
import { describe, it, expect } from "vitest"
import { createRedirectEntry } from "./createRedirectEntry"
import { langs } from "./lang"
describe("createRedirectEntry", () => {
it("throws when given invalid URL", () => {
expect(() =>
createRedirectEntry({
oldUrl: "not-a-url",
newUrl: "https://www.scandichotels.com/en/new-path",
})
).toThrow("Invalid URL: not-a-url")
expect(() =>
createRedirectEntry({
oldUrl: "https://scandichotels.com/old-path",
newUrl: "also-not-a-url",
})
).toThrow("Invalid URL: also-not-a-url")
})
describe("top level domain from old site to new", () => {
it(".com", () => {
expect(
@@ -56,4 +73,31 @@ describe("createRedirectEntry", () => {
).toEqual({ from: "/no/old-path", to: "/no/new-path" })
})
})
describe("handles .com/[locale]", () => {
it.each(langs)(".com/%s", (locale) => {
expect(
createRedirectEntry({
oldUrl: `https://scandichotels.com/${locale}/old-path`,
newUrl: `https://www.scandichotels.com/${locale}/new-path`,
})
).toEqual({ from: `/${locale}/old-path`, to: `/${locale}/new-path` })
})
})
it("throws when non-dotcom has locale in path", () => {
expect(() =>
createRedirectEntry({
oldUrl: "https://scandichotels.se/sv/old-path",
newUrl: "https://www.scandichotels.com/sv/new-path",
})
).toThrow("Unsupported URL found, non-.com hostname with locale in path")
expect(() =>
createRedirectEntry({
oldUrl: "https://scandichotels.com/sv/old-path",
newUrl: "https://www.scandichotels.se/sv/new-path",
})
).toThrow("Unsupported URL found, non-.com hostname with locale in path")
})
})

View File

@@ -1,3 +1,4 @@
import { langs } from "./lang"
import { akamaiRedirect, removeDomain } from "./utils"
export function createRedirectEntry({
@@ -7,7 +8,12 @@ export function createRedirectEntry({
oldUrl: string
newUrl: string
}) {
const from = removeDomain(akamaiRedirect(oldUrl))
oldUrl = validateUrl(oldUrl).href
newUrl = validateUrl(newUrl).href
const from = alreadyHasLocale(oldUrl)
? removeDomain(oldUrl)
: removeDomain(akamaiRedirect(oldUrl))
const to = removeDomain(newUrl)
return {
@@ -15,3 +21,45 @@ export function createRedirectEntry({
to,
}
}
function alreadyHasLocale(path: string) {
const url = new URL(path)
return (
url.hostname.endsWith("scandichotels.com") &&
langs.some((locale) => url.pathname.startsWith(`/${locale}/`))
)
}
function validateUrl(url: string) {
let output: URL
try {
output = new URL(url)
} catch (e) {
throw new Error(`Invalid URL: ${url}`)
}
if (hasOldHostnameAndLocale(output)) {
throw new Error(
"Unsupported URL found, non-.com hostname with locale in path",
{ cause: output.href }
)
}
return output
}
const oldHostnames = [
"scandichotels.de",
"scandichotels.dk",
"scandichotels.fi",
"scandichotels.no",
"scandichotels.se",
] as const
function hasOldHostnameAndLocale(url: URL) {
return oldHostnames.some(
(hostname) =>
url.hostname.endsWith(hostname) &&
langs.some((locale) => url.pathname.startsWith(`/${locale}/`))
)
}