import { expect } from "vitest";
import TestUtils from "@supersoniks/concorde/test-utils/TestUtils";
import "./router";
import { html } from "lit";
import { Routes } from "@supersoniks/concorde/core/utils/route";
function create(template = "", addToDocument = true) {
return TestUtils.bootstrap(
`
${template}
`,
addToDocument
)[0];
}
describe("SonicRouter", () => {
it("devrait afficher le contenu du template avec une route regexp", async () => {
const elt: any = create(`
Page Utilisateur
`);
elt.location = "/utilisateur/123";
await elt.updated();
expect(elt.textContent.trim()).toBe("Page Utilisateur");
});
it("devrait afficher le contenu avec dataProvider quand spécifié", async () => {
const elt: any = create(`
Page Utilisateur
`);
elt.location = "/utilisateur/123";
await elt.updated();
const divWrapper = elt.querySelector("div[dataProvider]");
expect(divWrapper.getAttribute("dataProvider")).toBe("/api/user/123");
});
it("devrait afficher le contenu du template avec url-pattern", async () => {
const elt: any = create(`
Page Utilisateur Pattern
`);
elt.location = "/utilisateur/123";
await elt.updated();
expect(elt.textContent.trim()).toBe("Page Utilisateur Pattern");
});
it("devrait afficher le fallback quand aucune route ne correspond", async () => {
const elt: any = create(`
Page Utilisateur
Page 404
`);
elt.location = "/page-inexistante";
await elt.updated();
expect(elt.textContent.trim()).toBe("Page 404");
});
it("devrait mettre à jour le titre de la page quand spécifié", async () => {
const elt: any = create(`
Accueil
`);
elt.location = "/accueil";
await elt.updated();
expect(document.title).toBe("Page d'accueil");
});
it("devrait gérer plusieurs templates correspondants", async () => {
const elt: any = create(`
Base Utilisateur
Détail Utilisateur
`);
elt.location = "/utilisateur/123";
await elt.updated();
expect(elt.textContent.trim().replace(/\s+/gm, " ")).toBe(
"Base Utilisateur Détail Utilisateur"
);
});
it("devrait rediriger vers fallBackRoute si défini et aucune route ne correspond", async () => {
const elt: any = create(`
Page Utilisateur
`);
elt.fallBackRoute = "#/404";
document.location.href = "#/page-inexistante";
await elt.updated();
// On ne peut pas tester document.location.href directement à cause de jsdom
// Mais on peut vérifier que la propriété est bien définie
expect(document.location.href.replace(document.location.origin, "")).toBe(
"/#/404"
);
});
it("devrait gérer les templates fournis via l'attribut templates", async () => {
const elt: any = create("", false);
const template = document.createElement("template");
template.setAttribute("data-route", "/test");
template.innerHTML = "
Test Template
";
elt.templates = [template];
document.body.appendChild(elt);
elt.location = "/test";
await elt.updated();
expect(elt.textContent.trim()).toBe("Test Template");
});
it("devrait gérer le dataProvider avec url-pattern", async () => {
const elt: any = create(`
Profil Utilisateur
`);
elt.location = "/utilisateur/123/profil/preferences";
await elt.updated();
const divWrapper = elt.querySelector("div[dataProvider]");
expect(divWrapper.getAttribute("dataProvider")).toBe(
"/api/user/123/preferences"
);
});
});
describe("SonicRouter Programmatic", () => {
it("devrait supporter les routes programmées simples", async () => {
const elt: any = create();
const routes = {
home: () => html`Accueil
`,
about: () => html`À propos
`,
fallback: () => html`404
`,
} satisfies Routes;
elt.routes = routes;
elt.location = "/home";
await elt.updated();
expect(elt.textContent.trim()).toBe("Accueil");
});
it("devrait supporter les paramètres avec url-pattern", async () => {
const elt: any = create("", false);
const routes = {
"user/:id/profile/:section": ({
id,
section,
}: {
id: number;
section: string;
}) => html` Utilisateur ${id} - Section ${section}
`,
} satisfies Routes;
elt.routes = routes;
document.body.appendChild(elt);
elt.location = "/user/123/profile/settings";
await elt.updated();
expect(elt.textContent.trim()).toBe("Utilisateur 123 - Section settings");
});
it("devrait supporter les expressions régulières", async () => {
const elt: any = create();
const routes = {
"user/(\\d+)/post/(\\d+)": ([userId, postId]: number[]) =>
html` User ${userId} Post ${postId}
`,
} satisfies Routes;
elt.routes = routes;
elt.location = "/user/123/post/456";
await elt.updated();
expect(elt.textContent.trim()).toBe("User 123 Post 456");
});
it("devrait utiliser le fallback quand aucune route ne correspond", async () => {
const elt: any = create();
const routes = {
home: () => html`Accueil
`,
fallback: () => html`Page Non Trouvée
`,
} satisfies Routes;
elt.routes = routes;
elt.location = "/invalid";
await elt.updated();
expect(elt.textContent.trim()).toBe("Page Non Trouvée");
});
it("devrait prioriser les routes programmées sur les templates HTML", async () => {
const elt: any = create(`
Accueil HTML
`);
const routes = {
home: () => html`Accueil Programmé
`,
} satisfies Routes;
elt.routes = routes;
elt.location = "/home";
await elt.updated();
expect(elt.textContent.trim()).toBe("Accueil Programmé");
});
});