Add full application: receipt scanning, auth, billing, and account deletion
Brings the working codebase (Next.js app, auth system, Stripe billing, Docker/deploy config, tests, docs) into version control on top of the placeholder initial commit, and adds account self-deletion (Danger Zone in Settings, password + typed-email confirmation, cascading DB cleanup, Stripe cancellation) per GDPR right-to-erasure. Excludes local build caches, node_modules, and internal agent scratch files; .gitignore hardened to keep those out going forward. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
89
tests/e2e/seo_slugs.test.ts
Normal file
89
tests/e2e/seo_slugs.test.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Locale-specific SEO slugs — public German keyword URLs rewrite onto the
|
||||
* shared App Router folders; English slugs under /de/ 301 to the DE slug.
|
||||
*/
|
||||
|
||||
import { describe, test, expect } from "./runner";
|
||||
import {
|
||||
decideSeoLocalePath,
|
||||
localizePathname,
|
||||
publicPath,
|
||||
} from "../../src/lib/seo/slugs";
|
||||
|
||||
describe("SEO slugs — public paths", () => {
|
||||
test("German blog slugs use keyword URLs", () => {
|
||||
expect(publicPath("de", "blog/simple-expense-tracking")).toBe(
|
||||
"/de/blog/einfache-ausgabenverfolgung",
|
||||
);
|
||||
expect(publicPath("en", "blog/simple-expense-tracking")).toBe(
|
||||
"/en/blog/simple-expense-tracking",
|
||||
);
|
||||
});
|
||||
|
||||
test("German keyword pages use German slugs", () => {
|
||||
expect(publicPath("de", "ocr-receipt-scanner")).toBe("/de/beleg-ocr");
|
||||
expect(publicPath("de", "expense-tracker-freelancers")).toBe(
|
||||
"/de/ausgaben-tracker-freelancer",
|
||||
);
|
||||
expect(publicPath("de", "expensify-alternative")).toBe("/de/alternative-zu-expensify");
|
||||
expect(publicPath("de", "lexoffice-alternative")).toBe("/de/alternative-zu-lexoffice");
|
||||
});
|
||||
});
|
||||
|
||||
describe("SEO slugs — middleware decisions", () => {
|
||||
test("DE public slug rewrites onto the internal folder", () => {
|
||||
expect(decideSeoLocalePath("/de/blog/einfache-ausgabenverfolgung")).toEqual({
|
||||
kind: "rewrite",
|
||||
pathname: "/de/blog/simple-expense-tracking",
|
||||
});
|
||||
expect(decideSeoLocalePath("/de/beleg-ocr")).toEqual({
|
||||
kind: "rewrite",
|
||||
pathname: "/de/ocr-receipt-scanner",
|
||||
});
|
||||
});
|
||||
|
||||
test("English slug under /de/ redirects to the German keyword URL", () => {
|
||||
expect(decideSeoLocalePath("/de/blog/simple-expense-tracking")).toEqual({
|
||||
kind: "redirect",
|
||||
pathname: "/de/blog/einfache-ausgabenverfolgung",
|
||||
});
|
||||
expect(decideSeoLocalePath("/de/ocr-receipt-scanner")).toEqual({
|
||||
kind: "redirect",
|
||||
pathname: "/de/beleg-ocr",
|
||||
});
|
||||
});
|
||||
|
||||
test("German slug under /en/ redirects to the English URL", () => {
|
||||
expect(decideSeoLocalePath("/en/blog/einfache-ausgabenverfolgung")).toEqual({
|
||||
kind: "redirect",
|
||||
pathname: "/en/blog/simple-expense-tracking",
|
||||
});
|
||||
});
|
||||
|
||||
test("correct English public slugs pass through", () => {
|
||||
expect(decideSeoLocalePath("/en/blog/simple-expense-tracking")).toEqual({
|
||||
kind: "none",
|
||||
});
|
||||
expect(decideSeoLocalePath("/en/ocr-receipt-scanner")).toEqual({ kind: "none" });
|
||||
});
|
||||
|
||||
test("homepage and blog index are untouched", () => {
|
||||
expect(decideSeoLocalePath("/de")).toEqual({ kind: "none" });
|
||||
expect(decideSeoLocalePath("/en")).toEqual({ kind: "none" });
|
||||
expect(decideSeoLocalePath("/de/blog")).toEqual({ kind: "none" });
|
||||
expect(decideSeoLocalePath("/en/blog")).toEqual({ kind: "none" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("SEO slugs — language switch", () => {
|
||||
test("maps the sibling locale slug instead of only swapping /en and /de", () => {
|
||||
expect(localizePathname("/en/blog/simple-expense-tracking", "de")).toBe(
|
||||
"/de/blog/einfache-ausgabenverfolgung",
|
||||
);
|
||||
expect(localizePathname("/de/blog/einfache-ausgabenverfolgung", "en")).toBe(
|
||||
"/en/blog/simple-expense-tracking",
|
||||
);
|
||||
expect(localizePathname("/de", "en")).toBe("/en");
|
||||
expect(localizePathname("/en/blog", "de")).toBe("/de/blog");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user