From f3f75e8ece123cad2919225b5735cf019305cf39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20J=C3=A4derberg?= Date: Fri, 10 Oct 2025 07:51:47 +0000 Subject: [PATCH] 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 --- .../createRedirectEntry.test.ts | 44 ++++++++++++++++ .../createRedirectEntry.ts | 50 ++++++++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/apps/scandic-redirect/scripts/generateRedirectFile/createRedirectEntry.test.ts b/apps/scandic-redirect/scripts/generateRedirectFile/createRedirectEntry.test.ts index 62eda925a..553967d2c 100644 --- a/apps/scandic-redirect/scripts/generateRedirectFile/createRedirectEntry.test.ts +++ b/apps/scandic-redirect/scripts/generateRedirectFile/createRedirectEntry.test.ts @@ -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") + }) }) diff --git a/apps/scandic-redirect/scripts/generateRedirectFile/createRedirectEntry.ts b/apps/scandic-redirect/scripts/generateRedirectFile/createRedirectEntry.ts index 208d44e01..ce614dc82 100644 --- a/apps/scandic-redirect/scripts/generateRedirectFile/createRedirectEntry.ts +++ b/apps/scandic-redirect/scripts/generateRedirectFile/createRedirectEntry.ts @@ -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}/`)) + ) +}