refactor(lineage): migrate life-and-lineage to lineage subdomain redirect
Move the marketing landing page content to the new route group served at , and convert the legacy route into a 308 permanent redirect to the new subdomain. - Add hosting the migrated marketing page. - Extract shared landing content and the redirect target into , with unit tests asserting the redirect destination.
This commit is contained in:
133
src/routes/lineage/landing-content.test.ts
Normal file
133
src/routes/lineage/landing-content.test.ts
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Unit tests for the Lineage landing page content (task 08).
|
||||
*
|
||||
* Mirrors the `page-head-meta.ts` / `nav-config.ts` pattern: assert against
|
||||
* pure constants exported from `landing-content.ts` (no solid-js / router /
|
||||
* DOM). This covers the task-08 acceptance matrix that's structurally
|
||||
* verifiable without rendering:
|
||||
* - App Store link is present and correct
|
||||
* - Google Play / downloads link targets the subdomain `/downloads` path
|
||||
* (public browser path, NOT the vercel-rewritten `/lineage/downloads`)
|
||||
* - Feature highlights cover: dark fantasy, mobile, remote saves, PvP
|
||||
* - PageHead base title + description (suffix is added by PageHead, task 02)
|
||||
* - Legacy `/marketing/life-and-lineage` redirect target points at the
|
||||
* Lineage subdomain.
|
||||
*
|
||||
* The PageHead title-suffix + canonical derivation for the lineage site is
|
||||
* already covered by `src/components/PageHead.test.ts`; these tests assert
|
||||
* the *inputs* the page passes to PageHead.
|
||||
*/
|
||||
import { describe, it, expect } from "bun:test";
|
||||
import {
|
||||
APP_STORE_URL,
|
||||
DOWNLOADS_HREF,
|
||||
APP_ICON_SRC,
|
||||
GOOGLE_PLAY_BADGE_SRC,
|
||||
SCREENSHOT_ASSETS,
|
||||
PAGE_META,
|
||||
FEATURES,
|
||||
LEGACY_REDIRECT_TARGET,
|
||||
type LineageFeature
|
||||
} from "~/routes/lineage/landing-content";
|
||||
|
||||
describe("Lineage landing — App Store link", () => {
|
||||
it("matches the canonical Life and Lineage App Store URL", () => {
|
||||
expect(APP_STORE_URL).toBe(
|
||||
"https://apps.apple.com/us/app/life-and-lineage/id6737252442"
|
||||
);
|
||||
});
|
||||
|
||||
it("is an absolute https URL", () => {
|
||||
expect(APP_STORE_URL.startsWith("https://")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Lineage landing — downloads link", () => {
|
||||
it("targets the subdomain-relative public browser path", () => {
|
||||
// NOT `/lineage/downloads` (the internal vercel-rewrite prefix) — vercel
|
||||
// rewrites `lineage.freno.me/downloads` → `/lineage/downloads` while
|
||||
// leaving the browser URL clean, matching the canonical rule from task 02.
|
||||
expect(DOWNLOADS_HREF).toBe("/downloads");
|
||||
});
|
||||
|
||||
it("does not leak the internal route prefix", () => {
|
||||
expect(DOWNLOADS_HREF).not.toContain("/lineage");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Lineage landing — asset paths", () => {
|
||||
it("points at the shared app icon", () => {
|
||||
expect(APP_ICON_SRC).toBe("/LineageIcon.png");
|
||||
});
|
||||
|
||||
it("points at the shared Google Play badge", () => {
|
||||
expect(GOOGLE_PLAY_BADGE_SRC).toBe("/google-play-badge.png");
|
||||
});
|
||||
|
||||
it("exposes screenshot + preview assets", () => {
|
||||
expect(SCREENSHOT_ASSETS.home).toBe("/lineage-home.png");
|
||||
expect(SCREENSHOT_ASSETS.shops).toBe("/lineage-shops.png");
|
||||
expect(SCREENSHOT_ASSETS.preview).toBe("/lineage-preview.mp4");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Lineage landing — PageHead inputs", () => {
|
||||
it("passes the base title (suffix is appended by PageHead)", () => {
|
||||
expect(PAGE_META.title).toBe("Life and Lineage");
|
||||
});
|
||||
|
||||
it("does not pre-bake the site suffix into the title", () => {
|
||||
// PageHead via resolvePageHeadMeta appends ` | Life and Lineage`.
|
||||
expect(PAGE_META.title).not.toContain("|");
|
||||
});
|
||||
|
||||
it("carries a non-empty description", () => {
|
||||
expect(PAGE_META.description.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("description mentions both store fronts", () => {
|
||||
expect(PAGE_META.description.toLowerCase()).toContain("app store");
|
||||
expect(PAGE_META.description.toLowerCase()).toContain("google play");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Lineage landing — feature highlights", () => {
|
||||
it("exposes exactly the four required pillars", () => {
|
||||
expect(FEATURES.length).toBe(4);
|
||||
const titles = FEATURES.map((f) => f.title);
|
||||
expect(titles).toContain("Dark Fantasy Adventure");
|
||||
expect(titles).toContain("Built for Mobile");
|
||||
expect(titles).toContain("Remote Saves");
|
||||
expect(titles).toContain("PvP Combat");
|
||||
});
|
||||
|
||||
it("every feature has a non-empty title + description", () => {
|
||||
for (const f of FEATURES as LineageFeature[]) {
|
||||
expect(f.title.length).toBeGreaterThan(0);
|
||||
expect(f.description.length).toBeGreaterThan(0);
|
||||
}
|
||||
});
|
||||
|
||||
it("covers the dark-fantasy / mobile / saves / PvP themes", () => {
|
||||
const blob = FEATURES.map(
|
||||
(f) => `${f.title} ${f.description}`
|
||||
)
|
||||
.join(" ")
|
||||
.toLowerCase();
|
||||
expect(blob).toContain("dark fantasy");
|
||||
expect(blob).toContain("mobile");
|
||||
expect(blob).toContain("sav");
|
||||
expect(blob).toContain("pvp");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Lineage landing — legacy redirect target", () => {
|
||||
it("points at the lineage subdomain apex", () => {
|
||||
expect(LEGACY_REDIRECT_TARGET).toBe("https://lineage.freno.me");
|
||||
});
|
||||
|
||||
it("is an https absolute URL with no trailing path", () => {
|
||||
expect(LEGACY_REDIRECT_TARGET.startsWith("https://")).toBe(true);
|
||||
expect(LEGACY_REDIRECT_TARGET.endsWith("/")).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user