SPB Git

spb/worthdoing Public

Autonomous investigation agent that discovers, challenges, and ranks things genuinely worth doing — Claude + Firecrawl, Next.js 16, PostgreSQL

TypeScript 91.5% SQL 5.8% CSS 2.2%
1.7 KB · 49 lines typescript
Raw Blame History
1/**2 * WorthDoing.ai3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File: tests/canonical-url.test.ts6 * Description: URL canonicalization + content hashing tests (deduplication layer).7 */8import { describe, it, expect } from "vitest";9import { canonicalizeUrl, sha256 } from "@/lib/firecrawl/url";1011describe("canonicalizeUrl", () => {12  it("strips www, fragments, and trailing slashes", () => {13    expect(canonicalizeUrl("https://www.Example.com/path/#section")).toBe("https://example.com/path");14  });1516  it("removes tracking parameters but keeps meaningful ones", () => {17    expect(canonicalizeUrl("https://example.com/a?utm_source=x&page=2&fbclid=abc")).toBe(18      "https://example.com/a?page=2",19    );20  });2122  it("sorts query parameters for stable comparison", () => {23    expect(canonicalizeUrl("https://example.com/a?b=2&a=1")).toBe(canonicalizeUrl("https://example.com/a?a=1&b=2"));24  });2526  it("normalizes equivalent URLs to the same canonical form", () => {27    const variants = [28      "https://www.example.com/post/",29      "https://example.com/post",30      "https://example.com/post#comments",31      "https://example.com/post?utm_campaign=news",32    ];33    const canon = new Set(variants.map(canonicalizeUrl));34    expect(canon.size).toBe(1);35  });3637  it("keeps the root path as /", () => {38    expect(canonicalizeUrl("https://example.com")).toBe("https://example.com/");39  });40});4142describe("sha256", () => {43  it("is deterministic and collision-distinct for different content", () => {44    expect(sha256("hello")).toBe(sha256("hello"));45    expect(sha256("hello")).not.toBe(sha256("hello!"));46    expect(sha256("hello")).toHaveLength(64);47  });48});49